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

1

Я пытаюсь обезвредить функцию во внешнем модуле, который я использую, но 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 я вижу, что пространство имен модулей .PDBList кажется, перезаписывается классом .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')
Теги:
mocking
biopython
monkeypatching
pytest

1 ответ

2
Лучший ответ

Вы правы - поскольку класс 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())
        ...
  • 0
    Блестящий! Это именно то, что я искал! Я думаю, я должен больше копаться в sys .
  • 0
    Рад, что смог помочь!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню