[Cython] Difference between Cython / Python isinstance() vs. NumPy scalars, Python bug?

Yury V. Zaytsev yury at shurup.com
Mon Jul 15 17:54:04 CEST 2013


On Mon, 2013-07-15 at 17:03 +0200, Yury V. Zaytsev wrote:
> However, when I run the same code from within Python, both checks work
> just fine. So is this a genuine bug in Cython, or, rather, NumPy is
> doing some black magic behind the scenes, that prevents
> Cython-compiled modules from working correctly?

I think I've found the problem, but still, it's not clear to me how do
go about solving it, so your guidance would be very much appreciated. As
it appears, this could be then a bug in Python, and C-API specifically?

Cython optimizer in _handle_simple_function_isinstance() replaces
`isinstance(x, (int, long, float))` with corresponding C-API function
calls (which are actually macros) like this (this is perfectly legal!):

#define PyInt_Check(op) \
    PyType_FastSubclass((op)->ob_type, Py_TPFLAGS_INT_SUBCLASS)

#define PyLong_Check(op) \
    PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LONG_SUBCLASS)

#define PyFloat_Check(op) PyObject_TypeCheck(op, &PyFloat_Type)

However, it seems that PyType_FastSubclass doesn't really work
correctly, because when I replace the following in the generated code
everything works perfectly:

(a)    __pyx_t_4 = PyInt_Check(__pyx_v_x, &PyInt_Type);

<->

(b)    __pyx_t_4 = PyObject_TypeCheck(__pyx_v_x, &PyInt_Type);

So, I guess, my question can be now really split into two questions, a
practical one and a philosophical one:

1) What's the best way to get Cython to generate (b) instead of (a)?

2) Shall I open a bug against Python and suggest to investigate why
PyType_FastSubclass is not really equivalent to PyObject_TypeCheck as it
should be for the built-in types?

Many thanks,

-- 
Sincerely yours,
Yury V. Zaytsev




More information about the cython-devel mailing list