summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorda-woods <dw-git@d-woods.co.uk>2020-03-07 20:13:52 +0000
committerStefan Behnel <stefan_ml@behnel.de>2020-03-07 21:16:22 +0100
commited79741ce61313c3b90eec613c5ee0f926ddd999 (patch)
tree1fcb05e49c19e32c11f11d7fd4cd829cb2469b70
parent477c1d1338efb6c160dee865d694def6f298d6a3 (diff)
downloadcython-ed79741ce61313c3b90eec613c5ee0f926ddd999.tar.gz
Fixed issue where fused functions didn't register as cyfunctions (GH-3386)
* Fixed issue where fused functions didn't register as cyfunctions Issue https://github.com/cython/cython/issues/3384 This happened where Cython was using a shared API because the CyFunction type imported from the shared api wasn't the same as used to initialize the fused function tp_base.
-rw-r--r--Cython/Utility/CythonFunction.c3
-rw-r--r--tests/run/fused_def.pyx13
2 files changed, 16 insertions, 0 deletions
diff --git a/Cython/Utility/CythonFunction.c b/Cython/Utility/CythonFunction.c
index 25a32d5ed..9e9da163d 100644
--- a/Cython/Utility/CythonFunction.c
+++ b/Cython/Utility/CythonFunction.c
@@ -1212,6 +1212,7 @@ static PyTypeObject __pyx_FusedFunctionType_type = {
// __doc__ is None for the fused function type, but we need it to be
// a descriptor for the instance's __doc__, so rebuild descriptors in our subclass
__pyx_CyFunction_getsets, /*tp_getset*/
+ // NOTE: tp_base may be changed later during module initialisation when importing CyFunction across modules.
&__pyx_CyFunctionType_type, /*tp_base*/
0, /*tp_dict*/
__pyx_FusedFunction_descr_get, /*tp_descr_get*/
@@ -1241,6 +1242,8 @@ static PyTypeObject __pyx_FusedFunctionType_type = {
};
static int __pyx_FusedFunction_init(void) {
+ // Set base from __Pyx_FetchCommonTypeFromSpec, in case it's different from the local static value.
+ __pyx_FusedFunctionType_type.tp_base = __pyx_CyFunctionType;
__pyx_FusedFunctionType = __Pyx_FetchCommonType(&__pyx_FusedFunctionType_type);
if (__pyx_FusedFunctionType == NULL) {
return -1;
diff --git a/tests/run/fused_def.pyx b/tests/run/fused_def.pyx
index be99a1aa3..f0e1be4c8 100644
--- a/tests/run/fused_def.pyx
+++ b/tests/run/fused_def.pyx
@@ -7,6 +7,9 @@ Test Python def functions without extern types
cy = __import__("cython")
cimport cython
+cdef extern from *:
+ int __Pyx_CyFunction_Check(object)
+
cdef class Base(object):
def __repr__(self):
return type(self).__name__
@@ -128,6 +131,16 @@ def opt_func(fused_t obj, cython.floating myf = 1.2, cython.integral myi = 7):
print cython.typeof(obj), cython.typeof(myf), cython.typeof(myi)
print obj, "%.2f" % myf, myi, "%.2f" % f, i
+def run_cyfunction_check():
+ """
+ tp_base of the fused function was being set incorrectly meaning
+ it wasn't being identified as a CyFunction
+ >>> run_cyfunction_check()
+ fused_cython_function
+ 1
+ """
+ print(type(opt_func).__name__)
+ print(__Pyx_CyFunction_Check(opt_func)) # should be True
def test_opt_func():
"""