Вопрос

I have a utility method that behaves like this

def my_patch_method(self):
    pass

def patch_my_lib():
    from mylib import MyClass
    MyClass.target_method = my_patch_method
    return MyClass()

This test fails:

self.assertEqual(my_patch_method, patch_my_lib().target_method)

Whereas this one works:

self.assertEqual(my_patch_method.__name__, patch_my_lib().target_method.__name__)

As the patch method does not have the same name, this is still acceptable proof that patch_my_lib() is doing what it's payed for but why doesn't the first work as I would expect ? And, is there a way to "fix" it ?

Это было полезно?

Решение

The reason your first test fails is that once you monkey-patch the function into your class, it isn't really the same object any more.

>>> def foo(self): pass
... 
>>> class Foo: pass
... 
>>> Foo.bar = foo
>>> type(Foo.bar)
<type 'instancemethod'>
>>> type(foo)
<type 'function'>
>>> 
>>> Foo.bar is foo
False
>>> Foo.bar == foo
False

In fact, the original function and the new method have different types. Instead, have your first test check this condition:

>>> Foo.bar.im_func is foo
True

So maybe this: self.assertIs(my_patch_method, patch_my_lib().target_method.im_func)

Другие советы

Try:

self.assertEqual(my_patch_method, patch_my_lib().target_method.im_func)

You are returning an instance from patch_my_lib, so comparing the function to the bound method

Something like this should pass

self.assertEqual(my_patch_method, patch_my_lib().target_method.im_func)

But it's probably better to check that the behaviour you are patching is working

MyClass.target_method = my_patch_method sets your function as a class function for MyClass, but you return a instance of that class with return MyClass().

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top