Я испытываю странное и непоследовательное поведение функции importlib.import_module
в Python3.Мне интересно 1) если кто-то еще испытал это и 2) лучшие способы исправить.Если уместно, я использую Python 3.5.3 в контейнере Docker, основанном на Debian (stretch).
Основой является то, что у меня есть среда, в которой я позволяю разработчикам писать небольшие кусочки настраиваемого кода.В качестве очень простой проверки мой скрипт использует importlib.import_module
для «проглатывания» кода;возникли бы синтаксические ошибки и т. д., если бы были очень очевидные проблемы с их кодом.
Я создаю промежуточную директорию и копирую их файл python в эту папку.Затем я запускаю (из того же каталога, что и BASE_DIR
ниже):
# if base is /foo, and module_path is at /foo/bar/xyz.py
# this gives bar/xyz.py
module_path_relative_to_base = os.path.relpath(
module_path,
start=BASE_DIR
)
# makes "bar/xyz.py" into "bar.xyz"
module_dot_path = module_path_relative_to_base.replace('/', '.')[:-3]
# import that module:
mod = import_module(module_dot_path)
Большинство времени (скажем, 80% времени) это работает.Однако иногда я получаю сообщение об ошибке:
Traceback (most recent call last):
File "workflow_ingestion/ingest_workflow.py", line 700, in <module>
handler_name_list = check_handlers(staging_dir)
File "workflow_ingestion/ingest_workflow.py", line 495, in check_handlers
inspect_handler_module(module_path, 'add_to_context', 2)
File "workflow_ingestion/ingest_workflow.py", line 432, in inspect_handler_module
mod = import_module(module_dot_path)
File "/usr/lib/python3.5/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 986, in _gcd_import
File "<frozen importlib._bootstrap>", line 969, in _find_and_load
File "<frozen importlib._bootstrap>", line 956, in _find_and_load_unlocked
ImportError: No module named 'workflow_ingestion.staging.20190130.file_chooser_handler'
, которое, по-видимому, указывает на то, что файла workflow_ingestion/staging/20190130/file_chooser_handler.py
там не было.Это не тот случай - когда я перечисляю каталог после этой ошибки, файл определенно там.
ОДНАКО, странно то, что если я поставлю print
оператор перед этим вызовом importlib.import_module
, он ВСЕГДА работает!Как только я удаляю вызов print
, ошибка снова появляется (!!).
Меня интересует, является ли это какой-то странной ошибкой (?), Когда предыдущая копия файла (с использованием shutil.copy2
Python) не полностью "зарегистрирована" в файловой системе / ОС или с взаимодействием Python с ними?Файловые системы / ОС находятся далеко от моей рулевой рубки, поэтому я понятия не имею, может ли это быть источником.
Мое временное решение - оставить это оператор печати или добавить вызов time.sleep
, который также доказал«эффективный», так как это не чувствительный ко времени процесс.Есть еще идеи?Я в порядке с этим взломом, но это просто очень странно для меня!