Author: mattip <[email protected]>
Branch: cpyext-ext
Changeset: r83056:731fbe0846a6
Date: 2016-03-14 22:12 +0200
http://bitbucket.org/pypy/pypy/changeset/731fbe0846a6/
Log: refactor PyStringObject to use PyObject_VARHEAD not PyObject_HEAD,
improve failing test
diff --git a/pypy/module/cpyext/bytesobject.py
b/pypy/module/cpyext/bytesobject.py
--- a/pypy/module/cpyext/bytesobject.py
+++ b/pypy/module/cpyext/bytesobject.py
@@ -27,7 +27,7 @@
## Solution
## --------
##
-## PyStringObject contains two additional members: the size and a pointer to a
+## PyStringObject contains two additional members: the ob_size and a pointer
to a
## char buffer; it may be NULL.
##
## - A string allocated by pypy will be converted into a PyStringObject with a
@@ -36,7 +36,7 @@
##
## - A string allocated with PyString_FromStringAndSize(NULL, size) will
## allocate a PyStringObject structure, and a buffer with the specified
-## size, but the reference won't be stored in the global map; there is no
+## size+1, but the reference won't be stored in the global map; there is no
## corresponding object in pypy. When from_ref() or Py_INCREF() is called,
## the pypy string is created, and added to the global map of tracked
## objects. The buffer is then supposed to be immutable.
@@ -54,7 +54,7 @@
PyStringObject = lltype.Ptr(PyStringObjectStruct)
PyStringObjectFields = PyObjectFields + \
(("ob_shash", rffi.LONG), ("ob_sstate", rffi.INT),
- ("buffer", rffi.CCHARP), ("size", Py_ssize_t))
+ ("buffer", rffi.CCHARP), ("ob_size", Py_ssize_t))
cpython_struct("PyStringObject", PyStringObjectFields, PyStringObjectStruct)
@bootstrap_function
@@ -62,7 +62,7 @@
"Type description of PyStringObject"
make_typedescr(space.w_str.layout.typedef,
basestruct=PyStringObject.TO,
- alloc = string_alloc,
+ #alloc = string_alloc,
attach=string_attach,
dealloc=string_dealloc,
realize=string_realize)
@@ -77,6 +77,7 @@
from string_attach. This is used as the tp_alloc function
for PyStringObject
'''
+ xxxx # TODO remove
from pypy.module.cpyext.typeobjectdefs import PyTypeObjectPtr
pytype = as_pyobj(space, w_type)
pytype = rffi.cast(PyTypeObjectPtr, pytype)
@@ -90,7 +91,7 @@
if length > 0:
py_str.c_buffer = lltype.malloc(rffi.CCHARP.TO, length+1,
flavor='raw', zero=True)
- py_str.c_size = length
+ py_str.c_ob_size = length
py_str.c_ob_sstate = rffi.cast(rffi.INT, 0) # SSTATE_NOT_INTERNED
s = rffi.charpsize2str(py_str.c_buffer, length+1)
w_obj = space.wrap(s)
@@ -110,7 +111,7 @@
py_str = rffi.cast(PyStringObject, py_obj)
buflen = length + 1
- py_str.c_size = length
+ py_str.c_ob_size = length
py_str.c_buffer = lltype.malloc(rffi.CCHARP.TO, buflen,
flavor='raw', zero=True)
py_str.c_ob_sstate = rffi.cast(rffi.INT, 0) # SSTATE_NOT_INTERNED
@@ -122,7 +123,7 @@
buffer must not be modified.
"""
py_str = rffi.cast(PyStringObject, py_obj)
- py_str.c_size = len(space.str_w(w_obj))
+ py_str.c_ob_size = len(space.str_w(w_obj))
py_str.c_buffer = lltype.nullptr(rffi.CCHARP.TO)
py_str.c_ob_shash = space.hash_w(w_obj)
py_str.c_ob_sstate = rffi.cast(rffi.INT, 1) # SSTATE_INTERNED_MORTAL
@@ -133,7 +134,7 @@
be modified after this call.
"""
py_str = rffi.cast(PyStringObject, py_obj)
- s = rffi.charpsize2str(py_str.c_buffer, py_str.c_size)
+ s = rffi.charpsize2str(py_str.c_buffer, py_str.c_ob_size)
w_obj = space.wrap(s)
py_str.c_ob_shash = space.hash_w(w_obj)
py_str.c_ob_sstate = rffi.cast(rffi.INT, 1) # SSTATE_INTERNED_MORTAL
@@ -193,12 +194,12 @@
ref_str.c_buffer = rffi.str2charp(s)
buffer[0] = ref_str.c_buffer
if length:
- length[0] = ref_str.c_size
+ length[0] = ref_str.c_ob_size
else:
i = 0
while ref_str.c_buffer[i] != '\0':
i += 1
- if i != ref_str.c_size:
+ if i != ref_str.c_ob_size:
raise OperationError(space.w_TypeError, space.wrap(
"expected string without null bytes"))
return 0
@@ -207,7 +208,7 @@
def PyString_Size(space, ref):
if from_ref(space, rffi.cast(PyObject, ref.c_ob_type)) is space.w_str:
ref = rffi.cast(PyStringObject, ref)
- return ref.c_size
+ return ref.c_ob_size
else:
w_obj = from_ref(space, ref)
return space.len_w(w_obj)
@@ -236,7 +237,7 @@
ref[0] = lltype.nullptr(PyObject.TO)
raise
to_cp = newsize
- oldsize = py_str.c_size
+ oldsize = py_str.c_ob_size
if oldsize < newsize:
to_cp = oldsize
for i in range(to_cp):
diff --git a/pypy/module/cpyext/include/stringobject.h
b/pypy/module/cpyext/include/stringobject.h
--- a/pypy/module/cpyext/include/stringobject.h
+++ b/pypy/module/cpyext/include/stringobject.h
@@ -38,15 +38,15 @@
typedef struct {
- PyObject_HEAD
+ PyObject_VAR_HEAD
long ob_shash;
int ob_sstate;
- char * buffer;
- Py_ssize_t size;
+ char * buffer; /* change the name from cpython so all non-api c access is
thwarted */
- /* Invariants:
- * ob_sval contains space for 'ob_size+1' elements.
- * ob_sval[ob_size] == 0.
+ /* Invariants
+ * (not relevant in PyPy, all stringobjects are backed by a pypy object)
+ * buffer contains space for 'ob_size+1' elements.
+ * buffer[ob_size] == 0.
* ob_shash is the hash of the string or -1 if not computed yet.
* ob_sstate != 0 iff the string object is in stringobject.c's
* 'interned' dictionary; in this case the two references
diff --git a/pypy/module/cpyext/test/test_bytesobject.py
b/pypy/module/cpyext/test/test_bytesobject.py
--- a/pypy/module/cpyext/test/test_bytesobject.py
+++ b/pypy/module/cpyext/test/test_bytesobject.py
@@ -91,13 +91,15 @@
def test_string_tp_alloc(self):
module = self.import_extension('foo', [
- ("getstring", "METH_NOARGS",
+ ("tpalloc", "METH_NOARGS",
"""
PyObject *base;
PyTypeObject * type;
PyStringObject *obj;
char * p_str;
base = PyString_FromString("test");
+ if (((PyStringObject*)base)->buffer == NULL)
+ return PyLong_FromLong(-2);
type = base->ob_type;
if (type->tp_itemsize != 1)
return PyLong_FromLong(type->tp_itemsize);
@@ -109,7 +111,7 @@
return (PyObject*)obj;
"""),
])
- s = module.getstring()
+ s = module.tpalloc()
assert s == 'works\x00\x00\x00\x00\x00'
def test_AsString(self):
@@ -262,14 +264,14 @@
ar[0] = rffi.cast(PyObject, py_str)
api._PyString_Resize(ar, 3)
py_str = rffi.cast(PyStringObject, ar[0])
- assert py_str.c_size == 3
+ assert py_str.c_ob_size == 3
assert py_str.c_buffer[1] == 'b'
assert py_str.c_buffer[3] == '\x00'
# the same for growing
ar[0] = rffi.cast(PyObject, py_str)
api._PyString_Resize(ar, 10)
py_str = rffi.cast(PyStringObject, ar[0])
- assert py_str.c_size == 10
+ assert py_str.c_ob_size == 10
assert py_str.c_buffer[1] == 'b'
assert py_str.c_buffer[10] == '\x00'
Py_DecRef(space, ar[0])
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit