pycのマジックナンバーについて調べました。

Pythonバイトコードのpycの最初の4バイトにはマジックナンバーがあって、どのバージョンで作成されたのか分かるようになっている。 各バージョンのマジックナンバー
Lib/importlib/_bootstrap_external.pyを見れば分かる。 マジックナンバーは、各バージョンごとに用意されている2バイトの数値+168627479になっている。

pycからバージョンを調べる

まず、中身をみる。

$ od -tx1 a.pyc                                                  
0000000 17 0d 0d 0a b2 cb 3e 59 1f 00 00 00 e3 00 00 00
0000020 00 00 00 00 00 00 00 00 00 02 00 00 00 40 00 00
0000040 00 73 10 00 00 00 64 00 00 64 01 00 84 00 00 5a
0000060 00 00 64 02 00 53 29 03 63 02 00 00 00 00 00 00
0000100 00 02 00 00 00 02 00 00 00 43 00 00 00 73 08 00
0000120 00 00 7c 00 00 7c 01 00 17 53 29 01 4e a9 00 29
0000140 02 da 01 61 da 01 62 72 01 00 00 00 72 01 00 00
0000160 00 fa 04 61 2e 70 79 da 03 66 6f 6f 01 00 00 00
0000200 73 02 00 00 00 00 01 72 05 00 00 00 4e 29 01 72
0000220 05 00 00 00 72 01 00 00 00 72 01 00 00 00 72 01
0000240 00 00 00 72 04 00 00 00 da 08 3c 6d 6f 64 75 6c
0000260 65 3e 01 00 00 00 73 00 00 00 00
0000273

最初の4バイトは,17 0d 0d 0aなので、

>>> 23 + 13 * (1<<8) + 13 * (1<<16) + 10 * (1<<24)
168627479

マジックナンバーは168627479で、下2バイトをとりだす。

>>>168627479 & int("FFFF",16)
3351

あとは、一覧を眺めて同じやつを見つける。

#     Python 3.5b1  3330 (PEP 448: Additional Unpacking Generalizations)
#     Python 3.5b2  3340 (fix dictionary display evaluation order #11205)
#     Python 3.5b2  3350 (add GET_YIELD_FROM_ITER opcode #24400)
#     Python 3.5.2  3351 (fix BUILD_MAP_UNPACK_WITH_CALL opcode #27286)
#     Python 3.6a0  3360 (add FORMAT_VALUE opcode #25483
#     Python 3.6a0  3361 (lineno delta of code.co_lnotab becomes signed)
#     Python 3.6a1  3370 (16 bit wordcode)
#     Python 3.6a1  3371 (add BUILD_CONST_KEY_MAP opcode #27140)
#     Python 3.6a1  3372 (MAKE_FUNCTION simplification, remove MAKE_CLOSURE
#                         #27095)
#     Python 3.6b1  3373 (add BUILD_STRING opcode #27078)
#     Python 3.6b1  3375 (add SETUP_ANNOTATIONS and STORE_ANNOTATION opcodes
#                         #27985)
#     Python 3.6b1  3376 (simplify CALL_FUNCTIONs & BUILD_MAP_UNPACK_WITH_CALL)
#     Python 3.6b1  3377 (set __class__ cell from type.__new__ #23722)
#     Python 3.6b2  3378 (add BUILD_TUPLE_UNPACK_WITH_CALL #28257)
#     Python 3.6rc1 3379 (more thorough __class__ validation #23722)
#     Python 3.7a0  3390 (add LOAD_METHOD and CALL_METHOD opcodes)

バージョン3.5.2だね。

処理系からマジックナンバーを調べる

>>> import importlib.util
>>> importlib.util.MAGIC_NUMBER
b'\x17\r\r\n'
>>> int.from_bytes(importlib.util.MAGIC_NUMBER,"little")
168627479