web-dev-qa-db-ja.com

Python 3で.pycヘッダーのマジックナンバーを見つける方法

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バイトコード、Webアセンブリ、そして今Pythonバイトコード)をチュートリアルシリーズの一部としてコンパイラの構築。

byteasmライブラリー を使用してPythonバイトコードを生成できます。内容を.pycファイルに書き込むには、有効なヘッダーが必要です。ヘッダーをハードコーディングすることで、チュートリアルに従う人がPython 3私は(3.7)か、バージョンのマジックナンバーを手動で見つける必要があります。

12
sepp2k

Python 3.4の時点で、モジュールimportlibには importlib.util.MAGIC_NUMBER があります。

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

Python <3.4またはPython2の別の解決策は、impモジュールの get_magicメソッド です。

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

これはまだPython 3.7で動作しますが、Python 3.4

9
kalehmann

動いた!1

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

バージョン3.4の新機能

これをtry/exceptでラップしてpy_compileにフォールバックするのがおそらく最も簡単です。

8
Josh Lee