-
Committer:
Robert Collins
-
Author(s):
Andrew Laski
-
Date:
2016-05-18 23:51:19 UTC
-
Revision ID:
git-v1:78527ff5ab5452b5d91c361d040f3f31469b37ec
Update the semantics on _fixtures.MonkeyPatch
A previous change added some logic so that when monkeypatching a
staticmethod the old_value was restored as a staticmethod. There was an
issue where the determination of whether or not a method should be
static was incorrectly checking the new function not the one to be
replaced. That caused an unintended side-effect that in order to patch
an instance method of a class the new function needed to be an instance
method of a class.
This change now reworks the semantics of MonkeyPatch to address that
issue and at the same time be explicit about how it should work in a
large number of different cases. The rule is simple and provides great
flexibility. Given a callable bar to be patched on to foo bar will be
called with any bound arguments first and then arguments of foo
appended. This is easier to visualize. Given:
class C(object):
@classmethod
def foo(cls, arg):
pass
class D(object):
@classmethod
def bar(cls, tgtcls, arg):
pass
def baz(cls, arg):
pass
MonkeyPatch('...C.foo', D.bar) will result in C.foo(1) calling bar like
bar(D, C, 1) because cls on bar was already bound to D when patching.
And MonkeyPatch('...C.foo', baz) will result in baz being called with
baz(C, 1).