[pypy-commit] pypy default: a passing test for issue #2482, but perhaps we should support PyBaseObject_Type too?
mattip
pypy.commits at gmail.com
Mon Apr 17 16:37:08 EDT 2017
Author: Matti Picus <matti.picus at gmail.com>
Branch:
Changeset: r91077:8175c5e20480
Date: 2017-04-17 23:34 +0300
http://bitbucket.org/pypy/pypy/changeset/8175c5e20480/
Log: a passing test for issue #2482, but perhaps we should support
PyBaseObject_Type too?
diff --git a/pypy/module/cpyext/test/issue2482.c b/pypy/module/cpyext/test/issue2482.c
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/test/issue2482.c
@@ -0,0 +1,107 @@
+
+#include "Python.h"
+//#define ISSUE_2482
+
+typedef struct {
+ PyObject_HEAD
+ // Some extra storage:
+ char blank[500];
+} instance;
+
+static PyObject * get_basicsize(PyObject *self, PyObject * arg)
+{
+ return PyLong_FromLong(((PyTypeObject*)arg)->tp_basicsize);
+}
+
+const char *name = "issue2482_object";
+static
+PyObject *make_object_base_type(void) {
+
+ PyHeapTypeObject *heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc(&PyType_Type, 0);
+ if (!heap_type) return NULL;
+
+ PyTypeObject *type = &heap_type->ht_type;
+ type->tp_name = name;
+#ifdef ISSUE_2482
+ type->tp_base = &PyBaseObject_Type; /*fails */
+#else
+ type->tp_base = &PyType_Type;
+#endif
+ type->tp_basicsize = sizeof(instance);
+ type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;
+
+ if (PyType_Ready(type) < 0)
+ return NULL;
+
+ return (PyObject *) heap_type;
+};
+
+static PyMethodDef issue2482_functions[] = {
+ {"get_basicsize", (PyCFunction)get_basicsize, METH_O, NULL},
+ {NULL, NULL} /* Sentinel */
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef moduledef = {
+ PyModuleDef_HEAD_INIT,
+ "issue2482",
+ "Module Doc",
+ -1,
+ issue2482_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_issue2482(void)
+
+#else
+
+#define INITERROR return
+
+/* Initialize this module. */
+#ifdef __GNUC__
+extern __attribute__((visibility("default")))
+#else
+extern __declspec(dllexport)
+#endif
+
+PyMODINIT_FUNC
+initissue2482(void)
+#endif
+{
+#if PY_MAJOR_VERSION >= 3
+ PyObject *module = PyModule_Create(&moduledef);
+#else
+ PyObject *module = Py_InitModule("issue2482", issue2482_functions);
+#endif
+ if (module == NULL)
+ INITERROR;
+
+ PyHeapTypeObject *heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc(&PyType_Type, 0);
+ if (!heap_type) INITERROR;
+
+ PyTypeObject *type = &heap_type->ht_type;
+ type->tp_name = name;
+
+ PyObject *base = make_object_base_type();
+ if (! base) INITERROR;
+ Py_INCREF(base);
+ type->tp_base = (PyTypeObject *) base;
+ type->tp_basicsize = ((PyTypeObject *) base)->tp_basicsize;
+ type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE | Py_TPFLAGS_CHECKTYPES;
+
+ if (PyType_Ready(type) < 0) INITERROR;
+
+ PyModule_AddObject(module, name, (PyObject *) type);
+};
diff --git a/pypy/module/cpyext/test/test_typeobject.py b/pypy/module/cpyext/test/test_typeobject.py
--- a/pypy/module/cpyext/test/test_typeobject.py
+++ b/pypy/module/cpyext/test/test_typeobject.py
@@ -1256,3 +1256,27 @@
# doesn't call tp_getattr at all, also on CPython
raises(AttributeError, type(module.gettype1).__getattribute__,
module.gettype1, 'dcBA')
+
+ def test_multiple_inheritance_tp_basicsize(self):
+ module = self.import_module(name='issue2482')
+
+ class PyBase(object):
+ pass
+
+ basesize = module.get_basicsize(PyBase)
+
+ CBase = module.issue2482_object
+ class A(CBase, PyBase):
+ def __init__(self, i):
+ CBase.__init__(self)
+ PyBase.__init__(self)
+
+ class B(PyBase, CBase):
+ def __init__(self, i):
+ PyBase.__init__(self)
+ CBase.__init__(self)
+
+ Asize = module.get_basicsize(A)
+ Bsize = module.get_basicsize(B)
+ assert Asize == Bsize
+ assert Asize > basesize
More information about the pypy-commit
mailing list