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
- test.py 638
Comment #1
Posted on Mar 5, 2009 by Grumpy OxThe 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 OxAttached 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.
- stubout.py.diff 376
Comment #3
Posted on Mar 6, 2009 by Grumpy OxSadly, 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 OxThought that was going to take longer.
Foo.b = classmethod(Foo.b.im_func)
Revised diff attached.
- stubout.py.diff 384
Comment #5
Posted on Mar 18, 2009 by Massive PandaDavid, 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 PandaI just submitted your patch.
Status: Fixed
Labels:
Type-Defect
Priority-Medium