我正在尝试在我使用的外部模块中对函数进行monkeypatch,但是monkeypatch似乎无法访问该函数,因为模块的名称空间在导入时会被覆盖。
具体来说,我在代码中使用了Bio.PDB.PDBList.PDBList
对象(biopython
模块),并且试图在Bio.PDB.PDBList
中修补_urlretrieve
,以防止拨打互联网和而是从本地目录获取文件,而不必模拟PDBList
的实例方法,这将需要更多工作。但是当我尝试天真时:
m.setattr("Bio.PDB.PDBList._urlretrieve", mock_retrieve)
pytest抱怨:
AttributeError: 'type' object at Bio.PDB.PDBList has no attribute '_urlretrieve'
进一步检查Bio.PDB
时,我发现模块名称空间.PDBList
似乎被类.PDBList.PDBList
覆盖:
# Download from the PDB
from .PDBList import PDBList
所以这可以解释为什么pytest将Bio.PDB.PDBList
视为没有属性type
的{{1}}对象。我的问题是,有没有办法让Monkeypatch修补此“隐藏”功能?
_urlretrieve
类用法的具体示例:
PDBList
答案 0 :(得分:2)
您是对的-由于PDBList
类与模块Bio.PDB.PDBList
的名称相同,因此在import Bio.PDB.PDBList
之后,您将无法通过其名称访问该模块(影子问题)。但是,您仍然可以从已加载的模块缓存中获取导入的模块对象,然后进行以下操作的猴子补丁:
import sys
from unittest.mock import Mock
import Bio.PDB.PDBList
def test_spam(monkeypatch):
assert isinstance(Bio.PDB.PDBList, type)
with monkeypatch.context() as m:
m.setattr(sys.modules['Bio.PDB.PDBList'], '_urlretrieve', Mock())
...