I apologize in advance for the long-winded background info.
I've been playing around with the Python/C-API recently (Python 3.4) and have gotten stumped. My goal is to have a C extension which I can use as a function/method decorator. I have a reasonably well working prototype for an LRU cache in the gist, https://gist.github.com/pbrady/916495198910e7d7c713. Although the cache works and is very fast, there are two issues problems :
The
type
returned by the my decorater is not function: i.e.>>> from lrucache import lrucache >>> @lrucache() ... def f(a, b): ... return a+b ... >>> type(f) >>> <class 'lrucache.cache'>
Because of this, the decorator does not work properly on methods - it seems that
self
gets lost because Python doesn't make an instance method when it sees my class (which makes sense).Copying
__doc__
from the decorated function to my cache class doesn't impact the message displayed byhelp
.
My idea to get around these issues was to simply return the user function with a few modifications rather than a new custom class object. These modifications are
Add a
__wrapped__
attribute to the function and point it to the function.Overwrite the
__call__
attribute so that function calls are directed to a custom C routine.
I was able to accomplish (1) but overriding a functions __call__
method doesn't do anything since it's not generally used by the interpreter.
My Question (finally): How do I create a Python function (i.e., a PyFunctionObject) which will call a C function?
Or, if there is a better way to do this, I would be interested in that as well. This is largely a learning/fun exercise so I'm not too interested in Cython based solutions.