Python mock.patch.object 和 functool.partial 绑定参数可能吗?
Python mock.patch.object with functool.partial bound arguments possible?
如何解决这个问题?用另一个签名修补对象方法(例如,一个额外的参数。我试图绑定可选参数,但这似乎不起作用。我不能在这里使用普通的猴子修补,因为修补 class在我无法以其他方式修补它的位置下调用。
感谢任何帮助。
import mock
import functools
# this class lives in another (unchangeable) module, __len__ method has to be patched
class ToOverride(object):
def __len__(self):
raise NotImplementedError()
# this code is changeable
def my_len(self, arg):
return arg+1
my_len_bound = functools.partial(my_len, arg=1)
with mock.patch.object(ToOverride, '__len__', my_len_bound):
inst = ToOverride()
print len(inst) # expected output: 2
调用上下文 mock.patch.object 时,出现以下错误:
TypeError Traceback (most recent call last)
<ipython-input-7-bfdb41d8628f> in <module>()
1 with mock.patch.object(ToOverride, '__len__', my_len_bound):
2 inst = ToOverride()
----> 3 print len(inst)
TypeError: my_len() takes exactly 2 arguments (1 given)
但是使用 None 作为第一个参数调用 my_len 会按预期工作(打印出 2)。
假设可以简单地进行猴子补丁,如果 len 以实例作为第一个参数手动调用,它就可以工作。但这当然是不受欢迎的:
ToOverride.__len__ = my_len_bound
inst = ToOverride()
print( inst.__len__(inst)) # 2
通过使用闭包模式,可以避免使用 functools partial,它不适用于 class 方法。
def bind_arg(arg):
def my_len(self, arg):
return arg+1
return my_len
如何解决这个问题?用另一个签名修补对象方法(例如,一个额外的参数。我试图绑定可选参数,但这似乎不起作用。我不能在这里使用普通的猴子修补,因为修补 class在我无法以其他方式修补它的位置下调用。
感谢任何帮助。
import mock
import functools
# this class lives in another (unchangeable) module, __len__ method has to be patched
class ToOverride(object):
def __len__(self):
raise NotImplementedError()
# this code is changeable
def my_len(self, arg):
return arg+1
my_len_bound = functools.partial(my_len, arg=1)
with mock.patch.object(ToOverride, '__len__', my_len_bound):
inst = ToOverride()
print len(inst) # expected output: 2
调用上下文 mock.patch.object 时,出现以下错误:
TypeError Traceback (most recent call last)
<ipython-input-7-bfdb41d8628f> in <module>()
1 with mock.patch.object(ToOverride, '__len__', my_len_bound):
2 inst = ToOverride()
----> 3 print len(inst)
TypeError: my_len() takes exactly 2 arguments (1 given)
但是使用 None 作为第一个参数调用 my_len 会按预期工作(打印出 2)。
假设可以简单地进行猴子补丁,如果 len 以实例作为第一个参数手动调用,它就可以工作。但这当然是不受欢迎的:
ToOverride.__len__ = my_len_bound
inst = ToOverride()
print( inst.__len__(inst)) # 2
通过使用闭包模式,可以避免使用 functools partial,它不适用于 class 方法。
def bind_arg(arg):
def my_len(self, arg):
return arg+1
return my_len