diff options
author | da-woods <dw-git@d-woods.co.uk> | 2020-03-07 20:13:52 +0000 |
---|---|---|
committer | Stefan Behnel <stefan_ml@behnel.de> | 2020-03-07 21:16:22 +0100 |
commit | ed79741ce61313c3b90eec613c5ee0f926ddd999 (patch) | |
tree | 1fcb05e49c19e32c11f11d7fd4cd829cb2469b70 | |
parent | 477c1d1338efb6c160dee865d694def6f298d6a3 (diff) | |
download | cython-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.c | 3 | ||||
-rw-r--r-- | tests/run/fused_def.pyx | 13 |
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(): """ |