Export to GitHub

pymox - issue #5

Stubs are not unset properly for classmethods


Posted on Mar 5, 2009 by Grumpy Ox

What steps will reproduce the problem? 1. Stub out a classmethod (method) of a base class (Foo) with one child (Bar) Note that Bar.method.im_self == Bar at this point 2. Execute stub 3. Unset stubs 4. Check Bar.method.im_self. Note that it is now equivalent to Foo

See attached test case for complete example

What is the expected output? What do you see instead? Bar.method.im_self should revert to it's original value (e.g. Bar, not Foo)

What version of the product are you using? On what operating system? mox 0.5, OS X

Attachments

Comment #1

Posted on Mar 5, 2009 by Grumpy Ox

The basic problem is demonstrated by the snippet below. Obviously the bug is a result of Python behavior and not mox itself. Anyone have ideas for a workaround?

class Foo(object): @classmethod def b(self): pass

class Bar(Foo): pass

print Foo.b.im_self print Bar.b.im_self

Foo.b = Foo.b

print Foo.b.im_self print Bar.b.im_self

Comment #2

Posted on Mar 6, 2009 by Grumpy Ox

Attached is a patch that solves the problem. For those interested in an explanation...

In the simple example above Foo.b needs to be reassigned to itself as a classmethod. Otherwise it gets rebound to Foo normally. That was very confusing to me but the demonstration below cleared it up for me.

print Foo.dict {... 'b': ...} Foo.b = Foo.b print Foo.dict {... 'b': > ...}

The proper behavior is actually already implemented for staticmethods in mox/stubout.py but not for classmethods. In our simple example the following solves the problem.

Foo.b = classmethod(Foo.b)

The attached diff does just that for stubbing out classmethods.

Attachments

Comment #3

Posted on Mar 6, 2009 by Grumpy Ox

Sadly, this isn't the whole solution...

Foo.b = classmethod(Foo.b) Foo.b() Traceback (most recent call last): File "", line 1, in TypeError: b() takes exactly 1 argument (2 given)

Python passes Foo to b twice... Will update if I can find a proper solution. My guess is this is why only the staticmethod fix is in the core code.

Comment #4

Posted on Mar 6, 2009 by Grumpy Ox

Thought that was going to take longer.

Foo.b = classmethod(Foo.b.im_func)

Revised diff attached.

Attachments

Comment #5

Posted on Mar 18, 2009 by Massive Panda

David, can you handle this patch?

Sorry for the huge delay! I'm swamped with work and I am talking a month long vacation soon, so I'm extra swamped getting everything in order.

Comment #6

Posted on Mar 20, 2009 by Massive Panda

I just submitted your patch.

Status: Fixed

Labels:
Type-Defect Priority-Medium