AKA hooking the args & return value of every function in a Python module
23 Jun 2017
Suppose you want to create a Python wrapper for some module, but hook into EVERY function call to do something with the args and results.
In my case, the module was a C Extension (using cffi), and I needed to convert most arguments to <cdata> things for cffi, and then turn most of the results back into Python objects.
Indeed, you could do a billion lines of this.
But nah, time to stir some metaprogramming into the soup.
I’ll assume you have functions like this in the wrapper module.
You’ll need a decorator to actually apply the functions (though we won’t use it like a decorator). Pretty simple, just passes args and kwargs through one function, and the return value through the other. We use functools.wraps to preserve the original function’s name, docstring, etc.
Now, we set the the module that the decorated members should be imported into. I wanted to dump all the resulting objects into the wrapper module (as if we did from SOMETHING.lib import *), so I just used __name__, but if that’s not the case for you, you’ll have to change this to another module.
We iterate through all the objects in the source module, and apply the decorator if it’s a C function (change BuiltinFunctionType to FunctionType to process Python functions). Then, using setattr, we assign the hooked object to the target module with the original name.
I bundled up the tracks I’ve made over the past year and a half into an EP! It’s called Vetrarlyktin and it’s on iTunes, Spotify, Google Play, Soundcloud, Amazon, etc.
As much as I hate boxing music into genres, it’s probably electronic post rock (although I couldn’t even select post rock as a genre when uploading it to distrokid).
Here’s the track listing, and what I had in mind while composing them:
Vetrarlyktin (“wintersmell”) - trilingual lyrics woah. it’s about nighttime during the winter
Yfir (“above”) - it’s kinda about taking flight in a steampunk machine
Dust in Servomotors - a robot making his way through the desert
Lanterns - something about trains going through mountains at night
Fjöll (“mountains”) - huge misty mountains; that’s about it