функция monkeypatch в модуле, пространство имен которого было перезаписано - PullRequest
0 голосов
/ 19 сентября 2018

Я пытаюсь установить функцию monkeypatch во внешнем модуле, который я использую, но monkeypatch не может получить доступ к функции, потому что пространство имен модуля перезаписывается при импорте.

Конкретно, я использую Bio.PDB.PDBList.PDBList объект (biopython модуль) в моем коде, и я пытаюсь исправить _urlretrieve в Bio.PDB.PDBList, чтобы предотвратить вызовы в Интернет и вместо этого получать файлы из локального каталога, без необходимостивысмеивать методы экземпляра PDBList, которые были бы значительно более трудоемкими.Но когда я пытаюсь наивно:

m.setattr("Bio.PDB.PDBList._urlretrieve", mock_retrieve)

pytest жалуется:

AttributeError: 'type' object at Bio.PDB.PDBList has no attribute '_urlretrieve'

При дальнейшей проверке Bio.PDB я вижу, что пространство имен модуля *Кажется, 1019 * перезаписывается классом .PDBList.PDBList:

# Download from the PDB
from .PDBList import PDBList

Так что это объясняет, почему Pytest видит Bio.PDB.PDBList как type объект без атрибута _urlretrieve.У меня вопрос, есть ли способ получить monkeypatch для исправления этой «скрытой» функции?


Конкретный пример использования PDBList класса:

from Bio.PDB.PDBList import PDBList

_pdblist = PDBList()

downloaded_file = _pdblist.retrieve_pdb_file('2O8B', pdir='./temp', file_format='pdb')

1 Ответ

0 голосов
/ 21 сентября 2018

Вы правы - поскольку класс PDBList имеет то же имя, что и модуль 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())
        ...
...