Author: Armin Rigo <[email protected]>
Branch:
Changeset: r75131:3899fdaff537
Date: 2014-12-27 19:03 +0100
http://bitbucket.org/pypy/pypy/changeset/3899fdaff537/
Log: Export in app-level buffer objects the method "_pypy_raw_address()"
mapping to the internal buffer's get_raw_address().
diff --git a/pypy/module/_rawffi/buffer.py b/pypy/module/_rawffi/buffer.py
--- a/pypy/module/_rawffi/buffer.py
+++ b/pypy/module/_rawffi/buffer.py
@@ -1,4 +1,5 @@
from rpython.rlib.buffer import Buffer
+from rpython.rtyper.lltypesystem import rffi
# XXX not the most efficient implementation
@@ -20,3 +21,7 @@
def setitem(self, index, char):
ll_buffer = self.datainstance.ll_buffer
ll_buffer[index] = char
+
+ def get_raw_address(self):
+ ll_buffer = self.datainstance.ll_buffer
+ return rffi.cast(rffi.CCHARP, ll_buffer)
diff --git a/pypy/module/_rawffi/test/test__rawffi.py
b/pypy/module/_rawffi/test/test__rawffi.py
--- a/pypy/module/_rawffi/test/test__rawffi.py
+++ b/pypy/module/_rawffi/test/test__rawffi.py
@@ -1144,6 +1144,15 @@
b[3] = b'x'
assert b[3] == b'x'
+ def test_pypy_raw_address(self):
+ import _rawffi
+ S = _rawffi.Structure((40, 1))
+ s = S(autofree=True)
+ addr = buffer(s)._pypy_raw_address()
+ assert type(addr) is int
+ assert buffer(s)._pypy_raw_address() == addr
+ assert buffer(s, 10)._pypy_raw_address() == addr + 10
+
def test_union(self):
import _rawffi
longsize = _rawffi.sizeof('l')
diff --git a/pypy/module/cpyext/slotdefs.py b/pypy/module/cpyext/slotdefs.py
--- a/pypy/module/cpyext/slotdefs.py
+++ b/pypy/module/cpyext/slotdefs.py
@@ -244,6 +244,9 @@
def getitem(self, index):
return self.ptr[index]
+ def get_raw_address(self):
+ return rffi.cast(rffi.CCHARP, self.ptr)
+
def wrap_getreadbuffer(space, w_self, w_args, func):
func_target = rffi.cast(readbufferproc, func)
with lltype.scoped_alloc(rffi.VOIDPP.TO, 1) as ptr:
diff --git a/pypy/objspace/std/bufferobject.py
b/pypy/objspace/std/bufferobject.py
--- a/pypy/objspace/std/bufferobject.py
+++ b/pypy/objspace/std/bufferobject.py
@@ -5,7 +5,7 @@
from rpython.rlib.objectmodel import compute_hash
from pypy.interpreter.baseobjspace import W_Root
-from pypy.interpreter.error import oefmt
+from pypy.interpreter.error import OperationError, oefmt
from pypy.interpreter.gateway import interp2app, unwrap_spec
from pypy.interpreter.typedef import TypeDef
@@ -123,6 +123,17 @@
return space.wrap("<%s for 0x%s, size %d>" %
(info, addrstring, self.buf.getlength()))
+ def descr_pypy_raw_address(self, space):
+ from rpython.rtyper.lltypesystem import lltype, rffi
+ try:
+ ptr = self.buf.get_raw_address()
+ except ValueError:
+ # report the error using the RPython-level internal repr of
self.buf
+ msg = ("cannot find the underlying address of buffer that "
+ "is internally %r" % (self.buf,))
+ raise OperationError(space.w_ValueError, space.wrap(msg))
+ return space.wrap(rffi.cast(lltype.Signed, ptr))
+
W_Buffer.typedef = TypeDef(
"buffer",
__doc__ = """\
@@ -149,5 +160,6 @@
__mul__ = interp2app(W_Buffer.descr_mul),
__rmul__ = interp2app(W_Buffer.descr_mul),
__repr__ = interp2app(W_Buffer.descr_repr),
+ _pypy_raw_address = interp2app(W_Buffer.descr_pypy_raw_address),
)
W_Buffer.typedef.acceptable_as_base_class = False
diff --git a/pypy/objspace/std/test/test_bufferobject.py
b/pypy/objspace/std/test/test_bufferobject.py
--- a/pypy/objspace/std/test/test_bufferobject.py
+++ b/pypy/objspace/std/test/test_bufferobject.py
@@ -197,3 +197,9 @@
buf = buffer('hello world')
raises(TypeError, "buf[MyInt(0)]")
raises(TypeError, "buf[MyInt(0):MyInt(5)]")
+
+ def test_pypy_raw_address_base(self):
+ raises(ValueError, buffer("foobar")._pypy_raw_address)
+ raises(ValueError, buffer(u"foobar")._pypy_raw_address)
+ e = raises(ValueError, buffer(bytearray("foobar"))._pypy_raw_address)
+ assert 'BytearrayBuffer' in str(e.value)
diff --git a/rpython/rlib/buffer.py b/rpython/rlib/buffer.py
--- a/rpython/rlib/buffer.py
+++ b/rpython/rlib/buffer.py
@@ -115,3 +115,8 @@
return # otherwise, adding self.offset might make 'start'
# out of bounds
self.buffer.setslice(self.offset + start, string)
+
+ def get_raw_address(self):
+ from rpython.rtyper.lltypesystem import rffi
+ ptr = self.buffer.get_raw_address()
+ return rffi.ptradd(ptr, self.offset)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit