[pypy-commit] pypy default: Change check_valid() to make its usage explicit at the level of RPython:
arigo
noreply at buildbot.pypy.org
Thu Jun 20 09:36:35 CEST 2013
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r64947:c924be84e77b
Date: 2013-06-20 09:36 +0200
http://bitbucket.org/pypy/pypy/changeset/c924be84e77b/
Log: Change check_valid() to make its usage explicit at the level of
RPython: users of rmmap.py have to call the check_*() methods
explicitly if they want that behavior. The result is a bit more
consistent.
diff --git a/pypy/module/mmap/interp_mmap.py b/pypy/module/mmap/interp_mmap.py
--- a/pypy/module/mmap/interp_mmap.py
+++ b/pypy/module/mmap/interp_mmap.py
@@ -4,7 +4,7 @@
from pypy.interpreter.gateway import interp2app, unwrap_spec
from pypy.interpreter.buffer import RWBuffer
from rpython.rlib import rmmap, rarithmetic
-from rpython.rlib.rmmap import RValueError, RTypeError
+from rpython.rlib.rmmap import RValueError, RTypeError, RMMapError
if rmmap.HAVE_LARGEFILE_SUPPORT:
OFF_T = rarithmetic.r_longlong
@@ -21,13 +21,14 @@
self.mmap.close()
def read_byte(self):
+ self.check_valid()
try:
return self.space.wrap(self.mmap.read_byte())
except RValueError, v:
- raise OperationError(self.space.w_ValueError,
- self.space.wrap(v.message))
+ raise mmap_error(self.space, v)
def readline(self):
+ self.check_valid()
return self.space.wrap(self.mmap.readline())
@unwrap_spec(num=int)
@@ -37,6 +38,7 @@
@unwrap_spec(tofind='bufferstr')
def find(self, tofind, w_start=None, w_end=None):
+ self.check_valid()
space = self.space
if w_start is None:
start = self.mmap.pos
@@ -50,6 +52,7 @@
@unwrap_spec(tofind='bufferstr')
def rfind(self, tofind, w_start=None, w_end=None):
+ self.check_valid()
space = self.space
if w_start is None:
start = self.mmap.pos
@@ -63,16 +66,18 @@
@unwrap_spec(pos=OFF_T, whence=int)
def seek(self, pos, whence=0):
+ self.check_valid()
try:
self.mmap.seek(pos, whence)
except RValueError, v:
- raise OperationError(self.space.w_ValueError,
- self.space.wrap(v.message))
+ raise mmap_error(self.space, v)
def tell(self):
+ self.check_valid()
return self.space.wrap(self.mmap.tell())
def descr_size(self):
+ self.check_valid()
try:
return self.space.wrap(self.mmap.file_size())
except OSError, e:
@@ -80,41 +85,40 @@
@unwrap_spec(data='bufferstr')
def write(self, data):
+ self.check_valid()
self.check_writeable()
try:
self.mmap.write(data)
except RValueError, v:
- raise OperationError(self.space.w_ValueError,
- self.space.wrap(v.message))
+ raise mmap_error(self.space, v)
@unwrap_spec(byte=str)
def write_byte(self, byte):
+ self.check_valid()
+ self.check_writeable()
try:
self.mmap.write_byte(byte)
- except RValueError, v:
- raise OperationError(self.space.w_ValueError,
- self.space.wrap(v.message))
- except RTypeError, v:
- raise OperationError(self.space.w_TypeError,
- self.space.wrap(v.message))
+ except RMMapError, v:
+ raise mmap_error(self.space, v)
@unwrap_spec(offset=int, size=int)
def flush(self, offset=0, size=0):
+ self.check_valid()
try:
return self.space.wrap(self.mmap.flush(offset, size))
except RValueError, v:
- raise OperationError(self.space.w_ValueError,
- self.space.wrap(v.message))
+ raise mmap_error(self.space, v)
except OSError, e:
raise mmap_error(self.space, e)
@unwrap_spec(dest=int, src=int, count=int)
def move(self, dest, src, count):
+ self.check_valid()
+ self.check_writeable()
try:
self.mmap.move(dest, src, count)
except RValueError, v:
- raise OperationError(self.space.w_ValueError,
- self.space.wrap(v.message))
+ raise mmap_error(self.space, v)
@unwrap_spec(newsize=int)
def resize(self, newsize):
@@ -134,33 +138,22 @@
return self.space.wrap(self.mmap.size)
def check_valid(self):
- # XXX the check_xxx() are inconsistent in this file. Please review!
- # For example readline() might raise an interp-level RValueError.
try:
self.mmap.check_valid()
except RValueError, v:
- raise OperationError(self.space.w_ValueError,
- self.space.wrap(v.message))
+ raise mmap_error(self.space, v)
def check_writeable(self):
try:
self.mmap.check_writeable()
- except RValueError, v:
- raise OperationError(self.space.w_ValueError,
- self.space.wrap(v.message))
- except RTypeError, v:
- raise OperationError(self.space.w_TypeError,
- self.space.wrap(v.message))
+ except RMMapError, v:
+ raise mmap_error(self.space, v)
def check_resizeable(self):
try:
self.mmap.check_resizeable()
- except RValueError, v:
- raise OperationError(self.space.w_ValueError,
- self.space.wrap(v.message))
- except RTypeError, v:
- raise OperationError(self.space.w_TypeError,
- self.space.wrap(v.message))
+ except RMMapError, v:
+ raise mmap_error(self.space, v)
def descr_getitem(self, w_index):
self.check_valid()
@@ -219,10 +212,8 @@
offset))
except OSError, e:
raise mmap_error(space, e)
- except RValueError, e:
- raise OperationError(space.w_ValueError, space.wrap(e.message))
- except RTypeError, e:
- raise OperationError(space.w_TypeError, space.wrap(e.message))
+ except RMMapError, e:
+ raise mmap_error(space, e)
return space.wrap(self)
elif rmmap._MS_WINDOWS:
@@ -238,10 +229,8 @@
offset))
except OSError, e:
raise mmap_error(space, e)
- except RValueError, e:
- raise OperationError(space.w_ValueError, space.wrap(e.message))
- except RTypeError, e:
- raise OperationError(space.w_TypeError, space.wrap(e.message))
+ except RMMapError, e:
+ raise mmap_error(space, e)
return space.wrap(self)
W_MMap.typedef = TypeDef("mmap",
@@ -281,8 +270,19 @@
space.w_EnvironmentError)
def mmap_error(space, e):
- w_error = space.fromcache(Cache).w_error
- return wrap_oserror(space, e, w_exception_class=w_error)
+ if isinstance(e, RValueError):
+ return OperationError(space.w_ValueError,
+ space.wrap(e.message))
+ elif isinstance(e, RTypeError):
+ return OperationError(space.w_TypeError,
+ space.wrap(e.message))
+ elif isinstance(e, OSError):
+ w_error = space.fromcache(Cache).w_error
+ return wrap_oserror(space, e, w_exception_class=w_error)
+ else:
+ # bogus 'e'?
+ return OperationError(space.w_SystemError, space.wrap(repr(e)))
+mmap_error._dont_inline_ = True
class MMapBuffer(RWBuffer):
@@ -297,31 +297,37 @@
return self.mmap.size
def getitem(self, index):
+ self.check_valid()
return self.mmap.data[index]
def getslice(self, start, stop, step, size):
+ self.check_valid()
if step == 1:
- return self.mmap._getslice(start, size)
+ return self.mmap.getslice(start, size)
else:
return RWBuffer.getslice(self, start, stop, step, size)
- def check_writeable(self):
+ def setitem(self, index, char):
+ self.check_valid_writeable()
+ self.mmap.data[index] = char
+
+ def setslice(self, start, string):
+ self.check_valid_writeable()
+ self.mmap.setslice(start, string)
+
+ def get_raw_address(self):
+ self.check_valid()
+ return self.mmap.data
+
+ def check_valid(self):
+ try:
+ self.mmap.check_valid()
+ except RValueError, v:
+ raise mmap_error(self.space, v)
+
+ def check_valid_writeable(self):
try:
self.mmap.check_valid()
self.mmap.check_writeable()
- except RValueError, v:
- raise OperationError(self.space.w_ValueError,
- self.space.wrap(v.message))
- except RTypeError, v:
- raise OperationError(self.space.w_TypeError,
- self.space.wrap(v.message))
-
- def setitem(self, index, char):
- self.mmap.check_writeable()
- self.mmap.data[index] = char
-
- def setslice(self, start, string):
- self.mmap.setslice(start, string)
-
- def get_raw_address(self):
- return self.mmap.data
+ except RMMapError, v:
+ raise mmap_error(self.space, v)
diff --git a/rpython/rlib/rmmap.py b/rpython/rlib/rmmap.py
--- a/rpython/rlib/rmmap.py
+++ b/rpython/rlib/rmmap.py
@@ -1,3 +1,11 @@
+"""Interp-level mmap-like object.
+
+Note that all the methods assume that the mmap is valid (or writable, for
+writing methods). You have to call check_valid() from the higher-level API,
+as well as maybe check_writeable(). In the case of PyPy, this is done from
+pypy/module/mmap/.
+"""
+
from rpython.rtyper.tool import rffi_platform
from rpython.rtyper.lltypesystem import rffi, lltype
from rpython.rlib import rposix
@@ -15,13 +23,15 @@
_64BIT = "64bit" in platform.architecture()[0]
_CYGWIN = "cygwin" == sys.platform
-class RValueError(Exception):
+class RMMapError(Exception):
def __init__(self, message):
self.message = message
-class RTypeError(Exception):
- def __init__(self, message):
- self.message = message
+class RValueError(RMMapError):
+ pass
+
+class RTypeError(RMMapError):
+ pass
includes = ["sys/types.h"]
if _POSIX:
@@ -330,8 +340,6 @@
self.close()
def read_byte(self):
- self.check_valid()
-
if self.pos < self.size:
value = self.data[self.pos]
self.pos += 1
@@ -340,8 +348,6 @@
raise RValueError("read byte out of range")
def readline(self):
- self.check_valid()
-
data = self.data
for pos in xrange(self.pos, self.size):
if data[pos] == '\n':
@@ -350,12 +356,11 @@
else: # no '\n' found
eol = self.size
- res = self._getslice(self.pos, eol - self.pos)
+ res = self.getslice(self.pos, eol - self.pos)
self.pos += len(res)
return res
def read(self, num=-1):
- self.check_valid()
if num < 0:
# read all
eol = self.size
@@ -365,13 +370,11 @@
if eol > self.size:
eol = self.size
- res = self._getslice(self.pos, eol - self.pos)
+ res = self.getslice(self.pos, eol - self.pos)
self.pos += len(res)
return res
def find(self, tofind, start, end, reverse=False):
- self.check_valid()
-
# XXX naive! how can we reuse the rstr algorithm?
if start < 0:
start += self.size
@@ -412,8 +415,6 @@
p += step
def seek(self, pos, whence=0):
- self.check_valid()
-
dist = pos
how = whence
@@ -432,12 +433,9 @@
self.pos = intmask(where)
def tell(self):
- self.check_valid()
return self.pos
def file_size(self):
- self.check_valid()
-
size = self.size
if _MS_WINDOWS:
if self.file_handle != INVALID_HANDLE:
@@ -455,23 +453,18 @@
return size
def write(self, data):
- self.check_valid()
- self.check_writeable()
data_len = len(data)
start = self.pos
if start + data_len > self.size:
raise RValueError("data out of range")
- self._setslice(start, data)
+ self.setslice(start, data)
self.pos = start + data_len
def write_byte(self, byte):
- self.check_valid()
-
if len(byte) != 1:
raise RTypeError("write_byte() argument must be char")
- self.check_writeable()
if self.pos >= self.size:
raise RValueError("write byte out of range")
@@ -482,25 +475,14 @@
return rffi.ptradd(self.data, offset)
def getslice(self, start, length):
- self.check_valid()
- return self._getslice(start, length)
-
- def setslice(self, start, data):
- self.check_valid()
- self.check_writeable()
- self._setslice(start, data)
-
- def _getslice(self, start, length):
return rffi.charpsize2str(self.getptr(start), length)
- def _setslice(self, start, newdata):
+ def setslice(self, start, newdata):
internaldata = self.data
for i in range(len(newdata)):
internaldata[start+i] = newdata[i]
def flush(self, offset=0, size=0):
- self.check_valid()
-
if size == 0:
size = self.size
if offset < 0 or size < 0 or offset + size > self.size:
@@ -521,10 +503,6 @@
return 0
def move(self, dest, src, count):
- self.check_valid()
-
- self.check_writeable()
-
# check boundings
if (src < 0 or dest < 0 or count < 0 or
src + count > self.size or dest + count > self.size):
@@ -535,10 +513,6 @@
c_memmove(datadest, datasrc, count)
def resize(self, newsize):
- self.check_valid()
-
- self.check_resizeable()
-
if _POSIX:
if not has_mremap:
raise RValueError("mmap: resizing not available--no mremap()")
@@ -597,21 +571,15 @@
raise winerror
def len(self):
- self.check_valid()
-
return self.size
def getitem(self, index):
- self.check_valid()
# simplified version, for rpython
if index < 0:
index += self.size
return self.data[index]
def setitem(self, index, value):
- self.check_valid()
- self.check_writeable()
-
if len(value) != 1:
raise RValueError("mmap assignment must be "
"single-character string")
diff --git a/rpython/rlib/test/test_rmmap.py b/rpython/rlib/test/test_rmmap.py
--- a/rpython/rlib/test/test_rmmap.py
+++ b/rpython/rlib/test/test_rmmap.py
@@ -99,7 +99,7 @@
m = mmap.mmap(no, 1)
m.close()
try:
- m.read(1)
+ m.check_valid()
except RValueError:
pass
else:
@@ -214,13 +214,13 @@
def func(no):
m = mmap.mmap(no, 6, access=mmap.ACCESS_READ)
try:
- m.write('x')
+ m.check_writeable()
except RTypeError:
pass
else:
assert False
try:
- m.resize(7)
+ m.check_resizeable()
except RTypeError:
pass
else:
@@ -286,7 +286,7 @@
f.write("foobar")
f.flush()
m = mmap.mmap(f.fileno(), 6, prot=mmap.PROT_READ)
- py.test.raises(RTypeError, m.write, "foo")
+ py.test.raises(RTypeError, m.check_writeable)
m.close()
f.close()
@@ -297,8 +297,8 @@
f.write("foobar")
f.flush()
m = mmap.mmap(f.fileno(), 6, prot=~mmap.PROT_WRITE)
- py.test.raises(RTypeError, m.write_byte, 'a')
- py.test.raises(RTypeError, m.write, "foo")
+ py.test.raises(RTypeError, m.check_writeable)
+ py.test.raises(RTypeError, m.check_writeable)
m.close()
f.close()
More information about the pypy-commit
mailing list