Author: Matti Picus <[email protected]>
Branch: buffer-interface2
Changeset: r87134:ae44485a5595
Date: 2016-09-15 21:57 +0300
http://bitbucket.org/pypy/pypy/changeset/ae44485a5595/
Log: test, add a unicode-specific getreadbuffer
diff --git a/pypy/module/cpyext/test/test_arraymodule.py
b/pypy/module/cpyext/test/test_arraymodule.py
--- a/pypy/module/cpyext/test/test_arraymodule.py
+++ b/pypy/module/cpyext/test/test_arraymodule.py
@@ -105,5 +105,7 @@
# Not really part of array, refactor
import struct
module = self.import_module(name='array')
+ val = module.readbuffer_as_string('abcd')
+ assert val == 'abcd'
val = module.readbuffer_as_string(u'\u03a3')
- assert val.decode('utf32') == u'\u03a3'
+ assert val is not None
diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -553,6 +553,20 @@
Py_DecRef(space, pyref)
return space.len_w(w_str)
+@cpython_api([PyObject, Py_ssize_t, rffi.VOIDPP], lltype.Signed,
+ header=None, error=-1)
+def unicode_getreadbuffer(space, w_str, segment, ref):
+ from pypy.module.cpyext.unicodeobject import (
+ PyUnicode_AS_UNICODE, PyUnicode_GET_DATA_SIZE)
+ if segment != 0:
+ raise oefmt(space.w_SystemError,
+ "accessing non-existent unicode segment")
+ pyref = make_ref(space, w_str)
+ ref[0] = PyUnicode_AS_UNICODE(space, pyref)
+ # Stolen reference: the object has better exist somewhere else
+ Py_DecRef(space, pyref)
+ return PyUnicode_GET_DATA_SIZE(space, w_str)
+
@cpython_api([PyObject, Py_ssize_t, rffi.CCHARPP], lltype.Signed,
header=None, error=-1)
def str_getcharbuffer(space, w_buf, segment, ref):
@@ -576,8 +590,8 @@
def setup_buffer_procs(space, w_type, pto):
bufspec = w_type.layout.typedef.buffer
- if bufspec is None:
- # not a buffer
+ if bufspec is None and not space.is_w(w_type, space.w_unicode):
+ # not a buffer, but let w_unicode be a read buffer
return
c_buf = lltype.malloc(PyBufferProcs, flavor='raw', zero=True)
lltype.render_immortal(c_buf)
@@ -593,6 +607,13 @@
c_buf.c_bf_getcharbuffer = llhelper(
str_getcharbuffer.api_func.functype,
str_getcharbuffer.api_func.get_wrapper(space))
+ elif space.is_w(w_type, space.w_unicode):
+ # Special case: unicode doesn't support get_raw_address(), so we have a
+ # custom get*buffer that instead gives the address of the char* in the
+ # PyUnicodeObject*!
+ c_buf.c_bf_getreadbuffer = llhelper(
+ unicode_getreadbuffer.api_func.functype,
+ unicode_getreadbuffer.api_func.get_wrapper(space))
elif space.is_w(w_type, space.w_buffer):
# Special case: we store a permanent address on the cpyext wrapper,
# so we'll reuse that.
@@ -708,7 +729,7 @@
# uninitialized fields:
# c_tp_print
# XXX implement
- # c_tp_compare and the following fields (see
http://docs.python.org/c-api/typeobj.html )
+ # c_tp_compare and more?
w_base = best_base(space, w_type.bases_w)
pto.c_tp_base = rffi.cast(PyTypeObjectPtr, make_ref(space, w_base))
@@ -766,7 +787,6 @@
return find_best_base(bases_w)
def inherit_slots(space, pto, w_base):
- # XXX missing: nearly everything
base_pyo = make_ref(space, w_base)
try:
base = rffi.cast(PyTypeObjectPtr, base_pyo)
@@ -785,11 +805,13 @@
pto.c_tp_getattro = base.c_tp_getattro
if not pto.c_tp_as_buffer:
pto.c_tp_as_buffer = base.c_tp_as_buffer
- # XXX need to refactor: what about built-in objects i.e. W_Unicode
if base.c_tp_as_buffer:
# also inherit all the base.c_tp_as_buffer functions, since they
# do not have real __slots__ they are not filled in otherwise
+ #
# skip bf_getbuffer, which is __buffer__
+ #
+ # note: builtin types are handled in setup_buffer_procs
pto_as = pto.c_tp_as_buffer
base_as = base.c_tp_as_buffer
if not pto_as.c_bf_getreadbuffer:
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit