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

Vitja Makarov vitja.makarov at gmail.com
Sat Aug 31 15:45:05 CEST 2013


2013/8/31 Stefan Behnel <stefan_ml at behnel.de>:
> 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?
>

I think we should do something like gevent does:
https://github.com/surfly/gevent/blob/master/gevent/monkey.py

It allows user to manually apply patch. It would be something like this:

import cython
cython.patch_all()


-- 
vitja.


More information about the cython-devel mailing list