From e9aa3db7ba616316319bd31d591be1b715fd8c5a Mon Sep 17 00:00:00 2001 From: Robert Bradshaw Date: Sat, 10 Apr 2021 00:54:35 -0700 Subject: Unconditionally use modified PyType_Ready. This fixes github issue #4106. --- Cython/Compiler/Nodes.py | 26 +++++-------- .../run/cdef_multiple_inheritance_cimport.srctree | 44 ++++++++++++++++++++++ 2 files changed, 54 insertions(+), 16 deletions(-) create mode 100644 tests/run/cdef_multiple_inheritance_cimport.srctree diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index 719ca7144..0d56a541c 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -5246,13 +5246,13 @@ class CClassDefNode(ClassDefNode): self.type_init_args.generate_disposal_code(code) self.type_init_args.free_temps(code) - self.generate_type_ready_code(self.entry, code, True) + self.generate_type_ready_code(self.entry, code) if self.body: self.body.generate_execution_code(code) # Also called from ModuleNode for early init types. @staticmethod - def generate_type_ready_code(entry, code, heap_type_bases=False): + def generate_type_ready_code(entry, code): # Generate a call to PyType_Ready for an extension # type defined in this module. type = entry.type @@ -5288,15 +5288,10 @@ class CClassDefNode(ClassDefNode): code.putln("#else") for slot in TypeSlots.slot_table: slot.generate_dynamic_init_code(scope, code) - if heap_type_bases: - code.globalstate.use_utility_code( - UtilityCode.load_cached('PyType_Ready', 'ExtensionTypes.c')) - readyfunc = "__Pyx_PyType_Ready" - else: - readyfunc = "PyType_Ready" + code.globalstate.use_utility_code( + UtilityCode.load_cached('PyType_Ready', 'ExtensionTypes.c')) code.putln( - "if (%s(&%s) < 0) %s" % ( - readyfunc, + "if (__Pyx_PyType_Ready(&%s) < 0) %s" % ( typeobj_cname, code.error_goto(entry.pos))) # Don't inherit tp_print from builtin types in Python 2, restoring the @@ -5375,12 +5370,11 @@ class CClassDefNode(ClassDefNode): type.vtabptr_cname, code.error_goto(entry.pos))) code.putln("#endif") - if heap_type_bases: - code.globalstate.use_utility_code( - UtilityCode.load_cached('MergeVTables', 'ImportExport.c')) - code.putln("if (__Pyx_MergeVtables(&%s) < 0) %s" % ( - typeobj_cname, - code.error_goto(entry.pos))) + code.globalstate.use_utility_code( + UtilityCode.load_cached('MergeVTables', 'ImportExport.c')) + code.putln("if (__Pyx_MergeVtables(&%s) < 0) %s" % ( + typeobj_cname, + code.error_goto(entry.pos))) if not type.scope.is_internal and not type.scope.directives.get('internal'): # scope.is_internal is set for types defined by # Cython (such as closures), the 'internal' diff --git a/tests/run/cdef_multiple_inheritance_cimport.srctree b/tests/run/cdef_multiple_inheritance_cimport.srctree new file mode 100644 index 000000000..dd56b3e30 --- /dev/null +++ b/tests/run/cdef_multiple_inheritance_cimport.srctree @@ -0,0 +1,44 @@ +# Test for https://github.com/cython/cython/issues/4106 + +PYTHON setup.py build_ext --inplace +PYTHON -c "import sub" + +######## setup.py ######## + +from Cython.Build import cythonize +from distutils.core import setup + +setup( + ext_modules = cythonize("*.pyx"), +) + +######## base.pxd ######## + +cdef class A: + cdef dict __dict__ + cdef int a(self) + +cdef class B(A): + cdef int b(self) + +######## base.pyx ######## + +cdef class A: + cdef int a(self): + return 1 + +class PyA: + pass + +cdef class B(A, PyA): + cdef int b(self): + return 2 + +######## sub.pyx ######## + +from base cimport B +print(B) + +cdef class C(B): + cdef int c(self): + return 3 -- cgit v1.2.1 From b68f2585ceec37e0be245122a0fb6328f5145e8d Mon Sep 17 00:00:00 2001 From: Robert Bradshaw Date: Sat, 10 Apr 2021 00:55:50 -0700 Subject: Efficiency improvements for enabling/disabling gc in __Pyx_PyType_Ready(). These are more important in light of it being used ubiquitously. --- Cython/Utility/ExtensionTypes.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/Cython/Utility/ExtensionTypes.c b/Cython/Utility/ExtensionTypes.c index d8b8353cb..26bc2d9d9 100644 --- a/Cython/Utility/ExtensionTypes.c +++ b/Cython/Utility/ExtensionTypes.c @@ -3,6 +3,7 @@ static int __Pyx_PyType_Ready(PyTypeObject *t); /////////////// PyType_Ready /////////////// +//@requires: ObjectHandling.c::PyObjectCallNoArg // Wrapper around PyType_Ready() with some runtime checks and fixes // to deal with multiple inheritance. @@ -67,24 +68,35 @@ static int __Pyx_PyType_Ready(PyTypeObject *t) { // For details, see https://github.com/cython/cython/issues/3603 PyObject *ret, *py_status; int gc_was_enabled; - PyObject *gc = PyImport_Import(PYUNICODE("gc")); - if (unlikely(!gc)) return -1; - py_status = PyObject_CallMethodObjArgs(gc, PYUNICODE("isenabled"), NULL); + static PyObject *gc = NULL; + static PyObject *gc_isenabled = NULL, *gc_enable = NULL, *gc_disable = NULL; + if (unlikely(!gc)) { + gc = PyImport_Import(PYUNICODE("gc")); + if (unlikely(!gc)) return -1; + gc_isenabled = PyObject_GetAttr(gc, PYUNICODE("isenabled")); + gc_enable = PyObject_GetAttr(gc, PYUNICODE("enable")); + gc_disable = PyObject_GetAttr(gc, PYUNICODE("disable")); + if (unlikely(!gc_isenabled || !gc_enable || !gc_disable)) { + Py_XDECREF(gc_isenabled); gc_isenabled = NULL; + Py_XDECREF(gc_enable); gc_enable = NULL; + Py_XDECREF(gc_disable); gc_disable = NULL; + Py_XDECREF(gc); gc = NULL; + return -1; + } + } + py_status = __Pyx_PyObject_CallNoArg(gc_isenabled); if (unlikely(!py_status)) { - Py_DECREF(gc); return -1; } gc_was_enabled = __Pyx_PyObject_IsTrue(py_status); Py_DECREF(py_status); if (gc_was_enabled > 0) { - ret = PyObject_CallMethodObjArgs(gc, PYUNICODE("disable"), NULL); + ret = __Pyx_PyObject_CallNoArg(gc_disable); if (unlikely(!ret)) { - Py_DECREF(gc); return -1; } Py_DECREF(ret); } else if (unlikely(gc_was_enabled == -1)) { - Py_DECREF(gc); return -1; } @@ -106,7 +118,7 @@ static int __Pyx_PyType_Ready(PyTypeObject *t) { if (gc_was_enabled) { PyObject *t, *v, *tb; PyErr_Fetch(&t, &v, &tb); - ret = PyObject_CallMethodObjArgs(gc, PYUNICODE("enable"), NULL); + ret = __Pyx_PyObject_CallNoArg(gc_enable); if (likely(ret || r == -1)) { Py_XDECREF(ret); // do not overwrite exceptions raised by PyType_Ready() above @@ -119,7 +131,6 @@ static int __Pyx_PyType_Ready(PyTypeObject *t) { r = -1; } } - Py_DECREF(gc); } #endif -- cgit v1.2.1 From 6d3480590ba5a10efa3288c2101090ff35e4ecbb Mon Sep 17 00:00:00 2001 From: Lobstros Date: Wed, 14 Apr 2021 20:26:25 +0100 Subject: Set black text for .cython code lines in HTML report. (GH-4117) --- Cython/Compiler/Annotate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cython/Compiler/Annotate.py b/Cython/Compiler/Annotate.py index 67e4662a8..48e73f853 100644 --- a/Cython/Compiler/Annotate.py +++ b/Cython/Compiler/Annotate.py @@ -87,7 +87,7 @@ class AnnotationCCodeWriter(CCodeWriter): body.cython { font-family: courier; font-size: 12; } .cython.tag { } - .cython.line { margin: 0em } + .cython.line { color: #000000; margin: 0em } .cython.code { font-size: 9; color: #444444; display: none; margin: 0px 0px 0px 8px; border-left: 8px none; } .cython.line .run { background-color: #B0FFB0; } -- cgit v1.2.1 From 0f4a15d907bb095bc93f93afe6bd30f224c98989 Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Thu, 15 Apr 2021 23:34:13 +0200 Subject: Add a missing "#undef" for the limited API target. --- Cython/Utility/ModuleSetupCode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Cython/Utility/ModuleSetupCode.c b/Cython/Utility/ModuleSetupCode.c index 2354c00a8..3929bc64b 100644 --- a/Cython/Utility/ModuleSetupCode.c +++ b/Cython/Utility/ModuleSetupCode.c @@ -163,8 +163,9 @@ #define CYTHON_USE_TYPE_SLOTS 0 #undef CYTHON_USE_PYTYPE_LOOKUP #define CYTHON_USE_PYTYPE_LOOKUP 0 - #undef CYTHON_USE_PYLIST_INTERNALS + #undef CYTHON_USE_ASYNC_SLOTS #define CYTHON_USE_ASYNC_SLOTS 0 + #undef CYTHON_USE_PYLIST_INTERNALS #define CYTHON_USE_PYLIST_INTERNALS 0 #undef CYTHON_USE_UNICODE_INTERNALS #define CYTHON_USE_UNICODE_INTERNALS 0 -- cgit v1.2.1