[Cython] Should we monkey patch inspect.isfunction() ?

Stefan Behnel stefan_ml at behnel.de
Sat Aug 31 15:28:33 CEST 2013


Hi,

currently, this fails in Cython compiled code:

    def cyfunc(): pass

    import inspect
    assert inspect.isfunction(cyfunc)

There isn't really much of a reason why this *should* fail, except for the
implementation of inspect.isfunction(), which tests for

    isinstance(obj, types.FunctionType)

where types.FunctionType is type(some_python_function).

In the benchmarks that we run on Jenkins, I'm patching into this as follows:

"""
def patch_inspect_isfunction():
    import inspect
    orig_isfunction = inspect.isfunction
    def isfunction(obj):
        return (orig_isfunction(obj)
                or type(obj).__name__ == 'cython_function_or_method')
    isfunction._orig_isfunction = orig_isfunction
    inspect.isfunction = isfunction

patch_inspect_isfunction()
"""

For example, Django uses inspect.isfunction() in some dynamic code and
requires this fix to run properly when compiled.

Now that we have a function type that is shared between different Cython
modules, I think it's worth considering the addition of a proper type test
in the inspect module as a general 'fix'. Meaning that we could patch the
inspect module automatically whenever we insert the Cython function type
into the shared Cython types module.

I'm aware that this is a bit evil and hackish, but it usually works quite
nicely.

I'm also aware that the proper way to do this would eventually be the ABC
mechanism as defined by PEP 3119, but Python's function type doesn't
currently support the ABC protocol. We could additionally lobby for getting
that changed.

http://www.python.org/dev/peps/pep-3119/#overloading-isinstance-and-issubclass

Opinions?

Stefan


More information about the cython-devel mailing list