[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