名称空间被覆盖的模块中的 monkeypatch 函数
monkeypatch function in module whose namespace was overwritten
我正在尝试对我使用的外部模块中的函数进行 monkeypatch,但 monkeypatch 似乎无法访问该函数,因为模块的名称空间在导入时被覆盖。
具体来说,我在我的代码中使用了一个 Bio.PDB.PDBList.PDBList
对象(biopython
模块),我试图在 Bio.PDB.PDBList
中修补 _urlretrieve
以防止调用internet 而不是从本地目录获取文件,而不必模拟 PDBList
的实例方法,这将大大增加工作量。但是当我尝试天真时:
m.setattr("Bio.PDB.PDBList._urlretrieve", mock_retrieve)
pytest 抱怨:
AttributeError: 'type' object at Bio.PDB.PDBList has no attribute '_urlretrieve'
进一步检查 Bio.PDB
,我发现模块命名空间 .PDBList
似乎被 class .PDBList.PDBList
:
覆盖
# Download from the PDB
from .PDBList import PDBList
这样就可以解释为什么 pytest 将 Bio.PDB.PDBList
视为没有属性 _urlretrieve
的 type
对象。我的问题是,有没有办法让 monkeypatch 修补这个 'hidden' 函数?
PDBList
用法的具体例子 class:
from Bio.PDB.PDBList import PDBList
_pdblist = PDBList()
downloaded_file = _pdblist.retrieve_pdb_file('2O8B', pdir='./temp', file_format='pdb')
你是对的 - 由于 PDBList
class 与模块 Bio.PDB.PDBList
同名,在 import Bio.PDB.PDBList
之后你将无法访问该模块顾名思义(阴影问题)。但是,您仍然可以从加载的模块缓存和 monkeypatch 中获取导入的模块对象:
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())
...
我正在尝试对我使用的外部模块中的函数进行 monkeypatch,但 monkeypatch 似乎无法访问该函数,因为模块的名称空间在导入时被覆盖。
具体来说,我在我的代码中使用了一个 Bio.PDB.PDBList.PDBList
对象(biopython
模块),我试图在 Bio.PDB.PDBList
中修补 _urlretrieve
以防止调用internet 而不是从本地目录获取文件,而不必模拟 PDBList
的实例方法,这将大大增加工作量。但是当我尝试天真时:
m.setattr("Bio.PDB.PDBList._urlretrieve", mock_retrieve)
pytest 抱怨:
AttributeError: 'type' object at Bio.PDB.PDBList has no attribute '_urlretrieve'
进一步检查 Bio.PDB
,我发现模块命名空间 .PDBList
似乎被 class .PDBList.PDBList
:
# Download from the PDB
from .PDBList import PDBList
这样就可以解释为什么 pytest 将 Bio.PDB.PDBList
视为没有属性 _urlretrieve
的 type
对象。我的问题是,有没有办法让 monkeypatch 修补这个 'hidden' 函数?
PDBList
用法的具体例子 class:
from Bio.PDB.PDBList import PDBList
_pdblist = PDBList()
downloaded_file = _pdblist.retrieve_pdb_file('2O8B', pdir='./temp', file_format='pdb')
你是对的 - 由于 PDBList
class 与模块 Bio.PDB.PDBList
同名,在 import Bio.PDB.PDBList
之后你将无法访问该模块顾名思义(阴影问题)。但是,您仍然可以从加载的模块缓存和 monkeypatch 中获取导入的模块对象:
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())
...