Я реорганизую библиотеку для использования importlib.resources для python 3.7+. Я использую бэкпорт importlib_resources для совместимости python 3.6. Код работает для питонов 3.6-3.8. Тем не менее, тесты pytest, использующие pyfakefs, проваливаются на 3.6. В условиях тестирования путь, возвращаемый при использовании importlib_resources, искажается (но в «реальных» условиях они возвращаются правильно).
Минимальный пример: у меня есть следующая структура библиотеки:
mypackage
├── mypackage
│ ├── __init__.py
│ ├── bin
│ │ └── __init__.py
│ └── find_bin.py
└── tests
└── test_find_bin.py
В самой библиотеке в папке bin содержатся двоичные файлы (плюс пустой __init__
). Код в другом месте библиотеки нуждается в пути к нему. find_bin.py
демонстрирует функцию, которая возвращает путь:
import sys
if sys.version_info >= (3, 7):
from importlib import resources
else:
import importlib_resources as resources
import mypackage.bin
def find_bin():
init_path_context = resources.path(mypackage.bin, '__init__.py')
with init_path_context as p:
init_path = p
bin_path = init_path.parent
return bin_path
Тест pytest test_find_bin.py
:
import pathlib
from mypackage.find_bin import find_bin
def test_findbin(fs):
test_bin = (pathlib.Path(__file__)
.resolve()
.parent.parent
.joinpath('mypackage', 'bin'))
print('test bin is ', test_bin)
expected_bin = find_bin()
print('expected bin is ', expected_bin)
assert not expected_bin.exists()
print('test creating fakefs ', test_bin)
fs.create_dir(test_bin)
assert expected_bin.exists()
Python 3.7+ работает с тестами, как и ожидалось. В python 3.6 путь ожидаемого_бина искажен:
test bin is /Users/geoffreysametz/Documents/mypackage/mypackage/bin # correct
expected bin is /var/folders/bv/m5cg5cp15t38sh8rxx244hp00000gn/T # ?!?!?!
Я попытался отследить выполнение функции find_bin, и он длинный и запутанный. Однако я видел, что importlib_resources
использует класс python FakeFilesystem. Моя гипотеза состоит в том, что проблема возникает из-за того, что importlib_resources
и pytest одновременно используют поддельные файловые системы.
Верна ли моя гипотеза? Есть ли обходной путь для получения pytest для тестирования кода, который использует importlib_resources?