importlib._bootstrap и инициализация интерпретатора Python

Система импорта модулей интерпретатора CPython написана на самом Python и инициализируется в importlib._bootstrap, Его источник можно увидеть в importlib/_bootstrap.py, но он не загружается оттуда. Вместо этого он загружается из так называемого замороженного модуля, байт-код которого запекается в библиотеке интерпретатора (python37.dll).

Интерпретатор инициализирует себя путем импорта _frozen_importlib (это название дляimportlib._bootstrap запеченный в переводчике) и зовет_installопределенная там функция, передаваяsys а также _impмодули в качестве аргументов._installзвонки_setup, который инициализирует время выполнения, необходимое для этого модуля, а затем добавляет 2 импортера, реализующих PEP 451.

При разработке собственного импортера я столкнулся с несколькими ошибками в _bootstrap.py или в моем импортере, поэтому мне нужно добавить отладочный вывод в _bootstrap.py,

Поэтому я пытаюсь сделать так, чтобы переводчик загружался _bootstrap.py с диска, а не со встроенного байт-кода.

Анализ исходного кода cpython показал, что для импорта встроенных модулей мне не нужна большая часть спецификационного класса. Таким образом, встроенные модули могут быть импортированы с помощью _create_builtin

class UltraSimpleSpec:
    __slots__=("name",)
    def __init__(self, name):
       self.name = name

def _install(sys, _imp):
    io = _imp.create_builtin(UltraSimpleSpec("_io"))
    _bi = _imp.create_builtin(UltraSimpleSpec("builtins"))
    fd = io.open("path/to/_bootstrap.py", "rt") # exits the _install function without any exception, how can it do it?
    raise _bi.Exception("Never called") # _bi.print doesn't work, because sys.stdout is not initialized, so I have to use exceptions for debug output
    ...

К сожалению, происходит что-то странное, и вызов io.open вызывает _install чтобы выйти, поток управления никогда не достигает следующего оператора. И никакое исключение не возникает, когда интерпретатор печатает его, вместо этого возникает исключение в другом месте из-за отсутствия побочного эффекта _install,

Еще одна неприятность заключается в том, что sys.stdout не инициализируется, поэтому мы не можем print и должны полагаться на исключения для вывода отладки.

Так

  1. Как я должен сделать open Работа?

  2. Как я должен инициализировать sys.stdout?

1 ответ

Не совсем ответ, но я решил одну проблему только для моего случая (загрузка исходного кода Python).

Как я должен сделать open Работа?

Оказалось, что строковое кодирование недоступно в то время, поэтому я использовал rb вместо r, Тогда я передаю bytes в compileС ними можно иметь дело.

Другие вопросы по тегам