Author: Matti Picus <[email protected]>
Branch:
Changeset: r85403:9bf5c0afe0d0
Date: 2016-06-27 18:41 +0300
http://bitbucket.org/pypy/pypy/changeset/9bf5c0afe0d0/
Log: merge PyTuple_Type-subclass which changes the model of PyTupleObject
and allows subclassing it
diff --git a/pypy/module/cpyext/bufferobject.py
b/pypy/module/cpyext/bufferobject.py
--- a/pypy/module/cpyext/bufferobject.py
+++ b/pypy/module/cpyext/bufferobject.py
@@ -79,5 +79,5 @@
Py_DecRef(space, py_buf.c_b_base)
else:
rffi.free_charp(rffi.cast(rffi.CCHARP, py_buf.c_b_ptr))
- from pypy.module.cpyext.object import PyObject_dealloc
- PyObject_dealloc(space, py_obj)
+ from pypy.module.cpyext.object import _dealloc
+ _dealloc(space, py_obj)
diff --git a/pypy/module/cpyext/bytearrayobject.py
b/pypy/module/cpyext/bytearrayobject.py
--- a/pypy/module/cpyext/bytearrayobject.py
+++ b/pypy/module/cpyext/bytearrayobject.py
@@ -26,54 +26,10 @@
PyByteArrayObjectStruct = lltype.ForwardReference()
PyByteArrayObject = lltype.Ptr(PyByteArrayObjectStruct)
PyByteArrayObjectFields = PyVarObjectFields
-# (("ob_exports", rffi.INT), ("ob_alloc", rffi.LONG), ("ob_bytes",
rffi.CCHARP))
cpython_struct("PyByteArrayObject", PyByteArrayObjectFields,
PyByteArrayObjectStruct)
-@bootstrap_function
-def init_bytearrayobject(space):
- "Type description of PyByteArrayObject"
- #make_typedescr(space.w_bytearray.layout.typedef,
- # basestruct=PyByteArrayObject.TO,
- # attach=bytearray_attach,
- # dealloc=bytearray_dealloc,
- # realize=bytearray_realize)
-
PyByteArray_Check, PyByteArray_CheckExact = build_type_checkers("ByteArray",
"w_bytearray")
-# XXX dead code to be removed
-#def bytearray_attach(space, py_obj, w_obj):
-# """
-# Fills a newly allocated PyByteArrayObject with the given bytearray object
-# """
-# py_ba = rffi.cast(PyByteArrayObject, py_obj)
-# py_ba.c_ob_size = len(space.str_w(w_obj))
-# py_ba.c_ob_bytes = lltype.nullptr(rffi.CCHARP.TO)
-# py_ba.c_ob_exports = rffi.cast(rffi.INT, 0)
-
-#def bytearray_realize(space, py_obj):
-# """
-# Creates the bytearray in the interpreter.
-# """
-# py_ba = rffi.cast(PyByteArrayObject, py_obj)
-# if not py_ba.c_ob_bytes:
-# py_ba.c_buffer = lltype.malloc(rffi.CCHARP.TO, py_ba.c_ob_size + 1,
-# flavor='raw', zero=True)
-# s = rffi.charpsize2str(py_ba.c_ob_bytes, py_ba.c_ob_size)
-# w_obj = space.wrap(s)
-# py_ba.c_ob_exports = rffi.cast(rffi.INT, 0)
-# track_reference(space, py_obj, w_obj)
-# return w_obj
-
-#@cpython_api([PyObject], lltype.Void, header=None)
-#def bytearray_dealloc(space, py_obj):
-# """Frees allocated PyByteArrayObject resources.
-# """
-# py_ba = rffi.cast(PyByteArrayObject, py_obj)
-# if py_ba.c_ob_bytes:
-# lltype.free(py_ba.c_ob_bytes, flavor="raw")
-# from pypy.module.cpyext.object import PyObject_dealloc
-# PyObject_dealloc(space, py_obj)
-
#_______________________________________________________________________
@cpython_api([PyObject], PyObject, result_is_ll=True)
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
@@ -120,8 +120,8 @@
def string_dealloc(space, py_obj):
"""Frees allocated PyStringObject resources.
"""
- from pypy.module.cpyext.object import PyObject_dealloc
- PyObject_dealloc(space, py_obj)
+ from pypy.module.cpyext.object import _dealloc
+ _dealloc(space, py_obj)
#_______________________________________________________________________
diff --git a/pypy/module/cpyext/frameobject.py
b/pypy/module/cpyext/frameobject.py
--- a/pypy/module/cpyext/frameobject.py
+++ b/pypy/module/cpyext/frameobject.py
@@ -46,8 +46,8 @@
Py_DecRef(space, py_code)
Py_DecRef(space, py_frame.c_f_globals)
Py_DecRef(space, py_frame.c_f_locals)
- from pypy.module.cpyext.object import PyObject_dealloc
- PyObject_dealloc(space, py_obj)
+ from pypy.module.cpyext.object import _dealloc
+ _dealloc(space, py_obj)
def frame_realize(space, py_obj):
"""
diff --git a/pypy/module/cpyext/funcobject.py b/pypy/module/cpyext/funcobject.py
--- a/pypy/module/cpyext/funcobject.py
+++ b/pypy/module/cpyext/funcobject.py
@@ -60,8 +60,8 @@
def function_dealloc(space, py_obj):
py_func = rffi.cast(PyFunctionObject, py_obj)
Py_DecRef(space, py_func.c_func_name)
- from pypy.module.cpyext.object import PyObject_dealloc
- PyObject_dealloc(space, py_obj)
+ from pypy.module.cpyext.object import _dealloc
+ _dealloc(space, py_obj)
def code_attach(space, py_obj, w_obj):
py_code = rffi.cast(PyCodeObject, py_obj)
@@ -80,8 +80,8 @@
py_code = rffi.cast(PyCodeObject, py_obj)
Py_DecRef(space, py_code.c_co_name)
Py_DecRef(space, py_code.c_co_filename)
- from pypy.module.cpyext.object import PyObject_dealloc
- PyObject_dealloc(space, py_obj)
+ from pypy.module.cpyext.object import _dealloc
+ _dealloc(space, py_obj)
@cpython_api([PyObject], PyObject, result_borrowed=True)
def PyFunction_GetCode(space, w_func):
diff --git a/pypy/module/cpyext/include/tupleobject.h
b/pypy/module/cpyext/include/tupleobject.h
--- a/pypy/module/cpyext/include/tupleobject.h
+++ b/pypy/module/cpyext/include/tupleobject.h
@@ -8,9 +8,12 @@
#endif
typedef struct {
- PyObject_HEAD
- Py_ssize_t ob_size;
- PyObject **ob_item; /* XXX optimize to ob_item[] */
+ PyObject_VAR_HEAD
+ PyObject *ob_item[1];
+ /* ob_item contains space for 'ob_size' elements.
+ * Items must normally not be NULL, except during construction when
+ * the tuple is not yet visible outside the function that builds it.
+ */
} PyTupleObject;
/* defined in varargswrapper.c */
diff --git a/pypy/module/cpyext/methodobject.py
b/pypy/module/cpyext/methodobject.py
--- a/pypy/module/cpyext/methodobject.py
+++ b/pypy/module/cpyext/methodobject.py
@@ -55,8 +55,8 @@
py_func = rffi.cast(PyCFunctionObject, py_obj)
Py_DecRef(space, py_func.c_m_self)
Py_DecRef(space, py_func.c_m_module)
- from pypy.module.cpyext.object import PyObject_dealloc
- PyObject_dealloc(space, py_obj)
+ from pypy.module.cpyext.object import _dealloc
+ _dealloc(space, py_obj)
class W_PyCFunctionObject(W_Root):
diff --git a/pypy/module/cpyext/object.py b/pypy/module/cpyext/object.py
--- a/pypy/module/cpyext/object.py
+++ b/pypy/module/cpyext/object.py
@@ -54,6 +54,9 @@
@cpython_api([PyObject], lltype.Void)
def PyObject_dealloc(space, obj):
+ return _dealloc(space, obj)
+
+def _dealloc(space, obj):
# This frees an object after its refcount dropped to zero, so we
# assert that it is really zero here.
assert obj.c_ob_refcnt == 0
diff --git a/pypy/module/cpyext/pytraceback.py
b/pypy/module/cpyext/pytraceback.py
--- a/pypy/module/cpyext/pytraceback.py
+++ b/pypy/module/cpyext/pytraceback.py
@@ -46,5 +46,5 @@
py_traceback = rffi.cast(PyTracebackObject, py_obj)
Py_DecRef(space, rffi.cast(PyObject, py_traceback.c_tb_next))
Py_DecRef(space, rffi.cast(PyObject, py_traceback.c_tb_frame))
- from pypy.module.cpyext.object import PyObject_dealloc
- PyObject_dealloc(space, py_obj)
+ from pypy.module.cpyext.object import _dealloc
+ _dealloc(space, py_obj)
diff --git a/pypy/module/cpyext/sliceobject.py
b/pypy/module/cpyext/sliceobject.py
--- a/pypy/module/cpyext/sliceobject.py
+++ b/pypy/module/cpyext/sliceobject.py
@@ -44,8 +44,8 @@
Py_DecRef(space, py_slice.c_start)
Py_DecRef(space, py_slice.c_stop)
Py_DecRef(space, py_slice.c_step)
- from pypy.module.cpyext.object import PyObject_dealloc
- PyObject_dealloc(space, py_obj)
+ from pypy.module.cpyext.object import _dealloc
+ _dealloc(space, py_obj)
PySlice_Check, PySlice_CheckExact = build_type_checkers("Slice")
diff --git a/pypy/module/cpyext/test/foo.c b/pypy/module/cpyext/test/foo.c
--- a/pypy/module/cpyext/test/foo.c
+++ b/pypy/module/cpyext/test/foo.c
@@ -1,6 +1,20 @@
#include "Python.h"
#include "structmember.h"
+#if PY_MAJOR_VERSION >= 3
+ #define PyInt_FromLong PyLong_FromLong
+ #define PyInt_AsLong PyLong_AsLong
+ #define PyThing_FromStringAndSize PyUnicode_FromStringAndSize
+ #define PyThing_FromString PyUnicode_FromString
+ # defin PyThing_Check PyUnicode_Check
+ #define _PyThing_AsString _PyUnicode_AsString
+#else
+ #define PyThing_FromStringAndSize PyString_FromStringAndSize
+ #define PyThing_FromString PyString_FromString
+ #define PyThing_Check PyString_Check
+ #define _PyThing_AsString PyString_AsString
+#endif
+
typedef struct {
PyObject_HEAD
int foo; /* the context holder */
@@ -88,7 +102,7 @@
static PyObject *
foo_get_name(PyObject *self, void *closure)
{
- return PyString_FromStringAndSize("Foo Example", 11);
+ return PyThing_FromStringAndSize("Foo Example", 11);
}
static PyObject *
@@ -114,7 +128,7 @@
{
PyObject *format;
- format = PyString_FromString("<Foo>");
+ format = PyThing_FromString("<Foo>");
if (format == NULL) return NULL;
return format;
}
@@ -130,11 +144,11 @@
foo_setattro(fooobject *self, PyObject *name, PyObject *value)
{
char *name_str;
- if (!PyString_Check(name)) {
+ if (!PyThing_Check(name)) {
PyErr_SetObject(PyExc_AttributeError, name);
return -1;
}
- name_str = PyString_AsString(name);
+ name_str = _PyThing_AsString(name);
if (strcmp(name_str, "set_foo") == 0)
{
long v = PyInt_AsLong(value);
@@ -620,20 +634,65 @@
(destructor)custom_dealloc, /*tp_dealloc*/
};
+static PyTypeObject TupleLike = {
+ PyObject_HEAD_INIT(NULL)
+ 0,
+ "foo.TupleLike", /*tp_name*/
+ sizeof(PyObject), /*tp_size*/
+};
+
+
static PyObject *size_of_instances(PyObject *self, PyObject *t)
{
return PyInt_FromLong(((PyTypeObject *)t)->tp_basicsize);
}
+
+static PyObject * is_TupleLike(PyObject *self, PyObject * t)
+{
+ int tf = t->ob_type == &TupleLike;
+ if (t->ob_type->tp_itemsize == 0)
+ return PyInt_FromLong(-1);
+ return PyInt_FromLong(tf);
+}
+
/* List of functions exported by this module */
static PyMethodDef foo_functions[] = {
{"new", (PyCFunction)foo_new, METH_NOARGS, NULL},
{"newCustom", (PyCFunction)newCustom, METH_NOARGS, NULL},
{"size_of_instances", (PyCFunction)size_of_instances, METH_O, NULL},
+ {"is_TupleLike", (PyCFunction)is_TupleLike, METH_O, NULL},
{NULL, NULL} /* Sentinel */
};
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef moduledef = {
+ PyModuleDef_HEAD_INIT,
+ "foo",
+ "Module Doc",
+ -1,
+ foo_functions,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+};
+#define INITERROR return NULL
+
+/* Initialize this module. */
+#ifdef __GNUC__
+extern __attribute__((visibility("default")))
+#else
+extern __declspec(dllexport)
+#endif
+
+PyMODINIT_FUNC
+PyInit_foo(void)
+
+#else
+
+#define INITERROR return
/* Initialize this module. */
#ifdef __GNUC__
@@ -644,8 +703,16 @@
PyMODINIT_FUNC
initfoo(void)
+#endif
{
- PyObject *m, *d;
+ PyObject *d;
+#if PY_MAJOR_VERSION >= 3
+ PyObject *module = PyModule_Create(&moduledef);
+#else
+ PyObject *module = Py_InitModule("foo", foo_functions);
+#endif
+ if (module == NULL)
+ INITERROR;
footype.tp_new = PyType_GenericNew;
@@ -654,52 +721,59 @@
MetaType.tp_base = &PyType_Type;
if (PyType_Ready(&footype) < 0)
- return;
+ INITERROR;
if (PyType_Ready(&UnicodeSubtype) < 0)
- return;
+ INITERROR;
if (PyType_Ready(&UnicodeSubtype2) < 0)
- return;
+ INITERROR;
if (PyType_Ready(&MetaType) < 0)
- return;
+ INITERROR;
if (PyType_Ready(&InitErrType) < 0)
- return;
+ INITERROR;
if (PyType_Ready(&SimplePropertyType) < 0)
- return;
+ INITERROR;
SimplePropertyType.tp_new = PyType_GenericNew;
InitErrType.tp_new = PyType_GenericNew;
CustomType.ob_type = &MetaType;
if (PyType_Ready(&CustomType) < 0)
- return;
+ INITERROR;
UnicodeSubtype3.tp_flags = Py_TPFLAGS_DEFAULT;
UnicodeSubtype3.tp_base = &UnicodeSubtype;
UnicodeSubtype3.tp_bases = Py_BuildValue("(OO)", &UnicodeSubtype,
&CustomType);
if (PyType_Ready(&UnicodeSubtype3) < 0)
+ INITERROR;
+
+ TupleLike.tp_base = &PyTuple_Type;
+ if (PyType_Ready(&TupleLike) < 0)
return;
- m = Py_InitModule("foo", foo_functions);
- if (m == NULL)
- return;
- d = PyModule_GetDict(m);
+
+ d = PyModule_GetDict(module);
if (d == NULL)
- return;
+ INITERROR;
if (PyDict_SetItemString(d, "fooType", (PyObject *)&footype) < 0)
- return;
+ INITERROR;
if (PyDict_SetItemString(d, "UnicodeSubtype", (PyObject *)
&UnicodeSubtype) < 0)
- return;
+ INITERROR;
if (PyDict_SetItemString(d, "UnicodeSubtype2", (PyObject *)
&UnicodeSubtype2) < 0)
- return;
+ INITERROR;
if (PyDict_SetItemString(d, "UnicodeSubtype3", (PyObject *)
&UnicodeSubtype3) < 0)
- return;
+ INITERROR;
if (PyDict_SetItemString(d, "MetaType", (PyObject *) &MetaType) < 0)
- return;
+ INITERROR;
if (PyDict_SetItemString(d, "InitErrType", (PyObject *) &InitErrType) < 0)
- return;
+ INITERROR;
if (PyDict_SetItemString(d, "Property", (PyObject *) &SimplePropertyType)
< 0)
- return;
+ INITERROR;
if (PyDict_SetItemString(d, "Custom", (PyObject *) &CustomType) < 0)
- return;
+ INITERROR;
+ if (PyDict_SetItemString(d, "TupleLike", (PyObject *) &TupleLike) < 0)
+ INITERROR;
+#if PY_MAJOR_VERSION >=3
+ return module;
+#endif
}
diff --git a/pypy/module/cpyext/test/test_tupleobject.py
b/pypy/module/cpyext/test/test_tupleobject.py
--- a/pypy/module/cpyext/test/test_tupleobject.py
+++ b/pypy/module/cpyext/test/test_tupleobject.py
@@ -51,7 +51,7 @@
api._PyTuple_Resize(ar, 10)
assert api.PyTuple_Size(ar[0]) == 10
for i in range(3, 10):
- rffi.cast(PyTupleObject, py_tuple).c_ob_item[i] = make_ref(
+ rffi.cast(PyTupleObject, ar[0]).c_ob_item[i] = make_ref(
space, space.wrap(42 + i))
w_tuple = from_ref(space, ar[0])
assert space.int_w(space.len(w_tuple)) == 10
@@ -151,3 +151,8 @@
"""),
])
module.run()
+
+ def test_tuple_subclass(self):
+ module = self.import_module(name='foo')
+ a = module.TupleLike([1, 2, 3])
+ assert module.is_TupleLike(a) == 1
diff --git a/pypy/module/cpyext/tupleobject.py
b/pypy/module/cpyext/tupleobject.py
--- a/pypy/module/cpyext/tupleobject.py
+++ b/pypy/module/cpyext/tupleobject.py
@@ -2,10 +2,10 @@
from rpython.rtyper.lltypesystem import rffi, lltype
from rpython.rlib.debug import fatalerror_notb
from pypy.module.cpyext.api import (cpython_api, Py_ssize_t, CANNOT_FAIL,
- build_type_checkers, PyObjectFields,
+ build_type_checkers, PyVarObjectFields,
cpython_struct, bootstrap_function)
from pypy.module.cpyext.pyobject import (PyObject, PyObjectP, Py_DecRef,
- make_ref, from_ref, decref,
+ make_ref, from_ref, decref, incref, pyobj_has_w_obj,
track_reference, make_typedescr, get_typedescr)
from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall
from pypy.objspace.std.tupleobject import W_TupleObject
@@ -29,8 +29,8 @@
PyTupleObjectStruct = lltype.ForwardReference()
PyTupleObject = lltype.Ptr(PyTupleObjectStruct)
ObjectItems = rffi.CArray(PyObject)
-PyTupleObjectFields = PyObjectFields + \
- (("ob_size", Py_ssize_t), ("ob_item", lltype.Ptr(ObjectItems)))
+PyTupleObjectFields = PyVarObjectFields + \
+ (("ob_item", ObjectItems),)
cpython_struct("PyTupleObject", PyTupleObjectFields, PyTupleObjectStruct)
@bootstrap_function
@@ -56,14 +56,12 @@
tuple_realize() is called. Refcount of the result is 1.
"""
typedescr = get_typedescr(space.w_tuple.layout.typedef)
- py_obj = typedescr.allocate(space, space.w_tuple)
+ py_obj = typedescr.allocate(space, space.w_tuple, length)
py_tup = rffi.cast(PyTupleObject, py_obj)
-
- py_tup.c_ob_item = lltype.malloc(ObjectItems, length,
- flavor='raw', zero=True,
- add_memory_pressure=True)
- py_tup.c_ob_size = length
- return py_tup
+ p = py_tup.c_ob_item
+ for i in range(py_tup.c_ob_size):
+ p[i] = lltype.nullptr(PyObject.TO)
+ return py_obj
def tuple_attach(space, py_obj, w_obj):
"""
@@ -71,23 +69,24 @@
buffer must not be modified.
"""
items_w = space.fixedview(w_obj)
- l = len(items_w)
- p = lltype.malloc(ObjectItems, l, flavor='raw',
- add_memory_pressure=True)
+ py_tup = rffi.cast(PyTupleObject, py_obj)
+ length = len(items_w)
+ if py_tup.c_ob_size < length:
+ raise oefmt(space.w_ValueError,
+ "tuple_attach called on object with ob_size %d but trying to store
%d",
+ py_tup.c_ob_size, length)
i = 0
try:
- while i < l:
- p[i] = make_ref(space, items_w[i])
+ while i < length:
+ py_tup.c_ob_item[i] = make_ref(space, items_w[i])
i += 1
except:
while i > 0:
i -= 1
- decref(space, p[i])
- lltype.free(p, flavor='raw')
+ ob = py_tup.c_ob_item[i]
+ py_tup.c_ob_item[i] = lltype.nullptr(PyObject.TO)
+ decref(space, ob)
raise
- py_tup = rffi.cast(PyTupleObject, py_obj)
- py_tup.c_ob_size = l
- py_tup.c_ob_item = p
def tuple_realize(space, py_obj):
"""
@@ -108,7 +107,9 @@
"converting a PyTupleObject into a W_TupleObject, "
"but found NULLs as items")
items_w[i] = w_item
- w_obj = space.newtuple(items_w)
+ w_type = from_ref(space, rffi.cast(PyObject, py_obj.c_ob_type))
+ w_obj = space.allocate_instance(W_TupleObject, w_type)
+ w_obj.__init__(items_w)
track_reference(space, py_obj, w_obj)
return w_obj
@@ -118,18 +119,16 @@
"""
py_tup = rffi.cast(PyTupleObject, py_obj)
p = py_tup.c_ob_item
- if p:
- for i in range(py_tup.c_ob_size):
- decref(space, p[i])
- lltype.free(p, flavor="raw")
- from pypy.module.cpyext.object import PyObject_dealloc
- PyObject_dealloc(space, py_obj)
+ for i in range(py_tup.c_ob_size):
+ decref(space, p[i])
+ from pypy.module.cpyext.object import _dealloc
+ _dealloc(space, py_obj)
#_______________________________________________________________________
@cpython_api([Py_ssize_t], PyObject, result_is_ll=True)
def PyTuple_New(space, size):
- return rffi.cast(PyObject, new_empty_tuple(space, size))
+ return new_empty_tuple(space, size)
@cpython_api([PyObject, Py_ssize_t, PyObject], rffi.INT_real, error=-1)
def PyTuple_SetItem(space, ref, index, py_obj):
@@ -185,25 +184,25 @@
ref = p_ref[0]
if not tuple_check_ref(space, ref):
PyErr_BadInternalCall(space)
- ref = rffi.cast(PyTupleObject, ref)
- oldsize = ref.c_ob_size
- oldp = ref.c_ob_item
- newp = lltype.malloc(ObjectItems, newsize, zero=True, flavor='raw',
- add_memory_pressure=True)
+ oldref = rffi.cast(PyTupleObject, ref)
+ oldsize = oldref.c_ob_size
+ p_ref[0] = new_empty_tuple(space, newsize)
+ newref = rffi.cast(PyTupleObject, p_ref[0])
try:
if oldsize < newsize:
to_cp = oldsize
else:
to_cp = newsize
for i in range(to_cp):
- newp[i] = oldp[i]
+ ob = oldref.c_ob_item[i]
+ incref(space, ob)
+ newref.c_ob_item[i] = ob
except:
- lltype.free(newp, flavor='raw')
+ decref(space, p_ref[0])
+ p_ref[0] = lltype.nullptr(PyObject.TO)
raise
- ref.c_ob_item = newp
- ref.c_ob_size = newsize
- lltype.free(oldp, flavor='raw')
- # in this version, p_ref[0] never needs to be updated
+ finally:
+ decref(space, ref)
return 0
@cpython_api([PyObject, Py_ssize_t, Py_ssize_t], PyObject)
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
@@ -371,6 +371,8 @@
# (minimally, if tp_basicsize is zero we copy it from the base)
if not pto.c_tp_basicsize:
pto.c_tp_basicsize = base_pto.c_tp_basicsize
+ if pto.c_tp_itemsize < base_pto.c_tp_itemsize:
+ pto.c_tp_itemsize = base_pto.c_tp_itemsize
flags = rffi.cast(lltype.Signed, pto.c_tp_flags)
base_object_pyo = make_ref(space, space.w_object)
base_object_pto = rffi.cast(PyTypeObjectPtr, base_object_pyo)
@@ -597,7 +599,7 @@
@cpython_api([PyObject], lltype.Void, header=None)
def type_dealloc(space, obj):
- from pypy.module.cpyext.object import PyObject_dealloc
+ from pypy.module.cpyext.object import _dealloc
obj_pto = rffi.cast(PyTypeObjectPtr, obj)
base_pyo = rffi.cast(PyObject, obj_pto.c_tp_base)
Py_DecRef(space, obj_pto.c_tp_bases)
@@ -608,7 +610,7 @@
heaptype = rffi.cast(PyHeapTypeObject, obj)
Py_DecRef(space, heaptype.c_ht_name)
Py_DecRef(space, base_pyo)
- PyObject_dealloc(space, obj)
+ _dealloc(space, obj)
def type_alloc(space, w_metatype, itemsize=0):
@@ -659,6 +661,8 @@
subtype_dealloc.api_func.get_wrapper(space))
if space.is_w(w_type, space.w_str):
pto.c_tp_itemsize = 1
+ elif space.is_w(w_type, space.w_tuple):
+ pto.c_tp_itemsize = rffi.sizeof(PyObject)
# buffer protocol
setup_buffer_procs(space, w_type, pto)
diff --git a/pypy/module/cpyext/unicodeobject.py
b/pypy/module/cpyext/unicodeobject.py
--- a/pypy/module/cpyext/unicodeobject.py
+++ b/pypy/module/cpyext/unicodeobject.py
@@ -90,8 +90,9 @@
Py_DecRef(space, py_unicode.c_defenc)
if py_unicode.c_str:
lltype.free(py_unicode.c_str, flavor="raw")
- from pypy.module.cpyext.object import PyObject_dealloc
- PyObject_dealloc(space, py_obj)
+
+ from pypy.module.cpyext.object import _dealloc
+ _dealloc(space, py_obj)
@cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL)
def Py_UNICODE_ISSPACE(space, ch):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit