Как узнать магическое число для заголовка .pyc в Python 3 - PullRequest
0 голосов
/ 18 декабря 2018

Файлы байт-кода Python (.pyc) имеют заголовок, который начинается с магического числа, которое изменяется между версиями Python.Как я могу (программно) узнать это число для текущей версии Python, чтобы сгенерировать действительный заголовок?В настоящее время я жестко программирую один для Python 3.7.1, но это означает, что теперь я зависел от конкретной версии Python.

Этот ответ делает именно то, что я хочу, используя py_compile.MAGIC, но этого, похоже, больше не существует в Python 3. Как я могу сделать эквивалент в Python 3?

Вот пример того, что я пытаюсь сделать:

import dis
import marshal

PYC_HEADER = b'\x42\x0d\x0d\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

def f():
    print('Hello World')

with open('test.pyc', 'wb') as pyc:
    pyc.write(PYC_HEADER)
    marshal.dump(dis.Bytecode(f).codeobj, pyc)

Это должно создать файл test.pyc, который затем можно запустить, используя тот же интерпретатор Python, что и скрипт, и вывести «Hello World!».И это так, но только при использовании Python 3.7.Я ищу способ создания заголовка для любой версии Python 3, используемой для запуска сценария, а не для жесткого кодирования 3.7.

Для контекста:

Я компилируюпростой язык программирования для различных форматов байт-кода (LLVM, байт-код Java, веб-сборка и теперь байт-код Python) как часть запланированной серии руководств по созданию компилятора.

Я могу сгенерировать байт-код Python, используя byteasmбиблиотека , которая в результате дает мне функцию.Но чтобы записать содержимое в файл .pyc, мне нужен правильный заголовок.При жестком кодировании заголовка код будет работать только в том случае, если люди, следующие руководству, используют ту же версию Python 3, что и я (3.7), или им придется вручную узнать магическое число для своей версии.

Ответы [ 2 ]

0 голосов
/ 18 декабря 2018

Он перемещен! 1

>>> import importlib.util
>>> importlib.util.MAGIC_NUMBER
b'3\r\r\n'

Новое в версии 3.4.

Возможно, проще всего это обернутьв попытке / за исключением отступить к py_compile.

0 голосов
/ 18 декабря 2018

Начиная с Python 3.4 в модуле есть importlib.util.MAGIC_NUMBER importlib:

>>> import importlib
>>> importlib.util.MAGIC_NUMBER.hex()
'420d0d0a'

Другое решение для Python <3.4 или Python2 - это <a href="https://docs.python.org/3/library/imp.html#imp.get_magic" rel="noreferrer">get_magic метод модуля imp .

>>> import imp
>>> imp.get_magic().hex()
'420d0d0a'

Обратите внимание, что, хотя это все еще работает в Python 3.7, с Python 3.4

оно устарело
...