хуки импорта (пользовательские загрузчики модулей) для pypy не работают

Я успешно могу создавать перехватчики импорта для загрузки файлов непосредственно из памяти в python2.7. Пример, который я использовал, был принятым ответом на этот вопрос:

python: Импорт модуля из памяти

Однако; при применении этого кода на pypy; я получаю ошибку импорта. Я также пробовал другие примеры хуков импорта, которые работают с обычным python, но не с pypy, например:

zip для загрузки python с модулями из памяти

Кто-нибудь знает, почему хуки импорта не работают в pypy? Есть ли что-то, что мне не хватает?


person efel    schedule 28.08.2016    source источник


Ответы (1)


Проблема в том, что в обоих примерах, на которые вы указываете, load_module() не добавляет загруженный модуль в sys.modules. Обычно так и должно быть (и тогда PyPy работает как CPython).

Если load_module() не добавит модуль в sys.modules, то каждый import a снова вызовет load_module() и вернет новую копию модуля. Например, в примере из python:Import module from memory:

import a as a1
import a as a2
print a1 is a2   # False!
a1.foo = "foo"
print a2.foo     # AttributeError

Это задокументировано в https://www.python.org/dev/peps/pep-0302/#id27. Метод load_module() отвечает за выполнение большего количества проверок, чем показано в этих простых примерах. В частности, обратите внимание на эту строку (выделение в оригинале):

Обратите внимание, что объект модуля должен находиться в sys.modules до того, как загрузчик выполнит код модуля.

Таким образом, тот факт, что PyPy ведет себя иначе, чем CPython в этом случае, можно понимать как разницу в поведении, которая следует из кода, который не соблюдает документы.

Но в любом случае, мое мнение, что это должно быть исправлено. Я создал задачу по адресу https://bitbucket.org/pypy/pypy/issues/2382/sysmeta_path-not-working-like-cpythons.

person Armin Rigo    schedule 28.08.2016
comment
Также обратите внимание, что два примера, которые вы цитируете, не работают в CPython 3.x: они дают вам непонятную ошибку KeyError откуда-то из внутренностей File "<frozen importlib._bootstrap>" - person Armin Rigo; 28.08.2016