With my recent work in Python win32 programming I’ve had a real need for AAA style mocking framework. Unable to find anything that I’ve been completely happy with I started my own simple mocking framework and got to learn some Python style meta programming in the process. I’ve found out a lot about the depth of the Python 2.x object model over the last 2 weeks and here are some of the nicer things I’ve found (updated as per Chris Taveres below):
This is useful if you pass in an instance method somewhere and you want to be able to access its attached class. Decorators on instance methods normally use this, but I needed it to get a nicer syntax on my asserts, I wanted this:
So now when I want to track what class is passed in I just have to start with the following:
this creates a module import by string. This becomes super powerful say if you wanted to replace functionality on a module, but didn’t know its name before hand. In my case I wanted to be able to patch in a replacement method for mocking and then put it back when I was done, and I didn’t want to have to keep passing in the module name on resets. The only downside to it so far is it behaves a little quirky with packages and you have walk your module hierarchy to get it to do what you want
example of patching originals back into the module:
###
__getattribute__ is called when any attribute is accessed on a class including __getattribute__ itself which is a bit silly. This was the primary engine of my mocking framework as it allowed me to record all calls to the methods on a mocked class. Just remember when you use this to have it not call itself or you’ll be in endless recursion!
example:
def stuff(self):
pass
def interceptor(self, name):
if name == “__getattribute__”: #guard condition against calling itself
return object.__getattribute__(self, name)
#whatever interception logic you need here
MyClass.__getattribute__ = interceptor
m = MyClass()
m.stuff() #interception logic will be called here </div> </div>
I’m just starting to dip into the Python object model now and I’ll try and share what I find over the next few weeks.