Является ли перевод в байт-код в python построчным?

Является ли перевод в байт-код в python построчным?


Имеется код:

try:
    def f():
        print('hi')
        print('bye) # здесь намеренно пропущен закрывающий апостроф
except:
    pass
          
f()

Целью эксперимента было: выяснить, что произойдёт при вызове функции f, построчное определение (def) которой в run-time провалилось. Предполагалось, что определение (def) как оператор провалилось, поэтому объект функции и ссылка f на него не создадутся в глобальной области видимости модуля. Поэтому предполагалось, что вызов f() приведёт к возбуждению исключения NameError.

В действительности оказалось, что при запуске выходит SyntaxError, и строка 'hi' не печатается. Думаю, что то ли блок try не ловит исключение, то ли bite-code всего модуля не смог создаться, а потому не выполнился его запуск в принципе, и оператор def даже не начинал работу (собственно как и последующий оператор вызова f()).

Вопрос: Помогите, пожалуйста, разобраться, почему до вызова f() дело не дошло. Возможно одно из моих предположений выше верно, тогда хотелось бы увидеть ссылки на документацию, подробно объясняющие происходящее.

Ответ:

Сначала исходник проходит фазу токенизации. Потом из токенов строится AST. Потом компилятор транслирует AST в байткод. Полученный байткод выполняет PVM. Перехват исключений, очевидно, может работать только в процессе выполнения байткода виртуальной машиной, на предыдущих этапах самого механизма исключений ещё не существует, поэтому SyntaxError перехватить нельзя. Конечно, если исключить варианты с парсингом в рантайме, типа выполнения инструкции eval.

Report Page