Using binding=True fills in all the attributes to make cython function work with the inspect module, mostly. Some monkey patching is also required for it to recognize cython functions/methods as functions/methods (see at the end).
However, it turns out that python's co_firstlineno starts from the first decorator that decorates the function, while cython's co_firstlineno is set to the actual function start and does not include the decorator, which I think is a bug on cython's part.
You can replicate it by inspecting co_firstlineno for e.g. the following function in cython and python using binding=True.
def do_nothing(f):
return f
@do_nothing
@do_nothing
def do_something():
pass
For reference, here's my inspect monkey patching:
import inspect
from inspect import ismethod, isfunction
def ismethod_cython(object):
if ismethod(object):
return True
if object.__class__.__name__ == 'cython_function_or_method' and hasattr(object, '__func__'):
return True
return False
inspect.ismethod = ismethod_cython
def isfunction_cython(object):
if isfunction(object):
return True
if object.__class__.__name__ == 'cython_function_or_method' and not hasattr(object, '__func__'):
return True
return False
inspect.isfunction = isfunction_cython
Using
binding=Truefills in all the attributes to make cython function work with the inspect module, mostly. Some monkey patching is also required for it to recognize cython functions/methods as functions/methods (see at the end).However, it turns out that python's
co_firstlinenostarts from the first decorator that decorates the function, while cython'sco_firstlinenois set to the actual function start and does not include the decorator, which I think is a bug on cython's part.You can replicate it by inspecting
co_firstlinenofor e.g. the following function in cython and python usingbinding=True.For reference, here's my inspect monkey patching: