magics.py 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873
  1. # (C) Copyright 2018-2025 by Rocky Bernstein
  2. #
  3. # This program is free software; you can redistribute it and/or
  4. # modify it under the terms of the GNU General Public License
  5. # as published by the Free Software Foundation; either version 2
  6. # of the License, or (at your option) any later version.
  7. #
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with this program; if not, write to the Free Software
  15. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  16. """
  17. Everything you ever wanted to know about Python versions and their
  18. magic numbers. And a little bit more...
  19. by_magic: in this dictionary, the key is a magic byte string like
  20. # b'\x03\xf3\r\n' and its value is a set of canonic version strings, like
  21. # '2.7'
  22. by_version: in this dictionary, the key is a canonic version string like '2.7,
  23. and its value is a magic byte string like b'\x03\xf3\r\n' canonic
  24. name, like '2.7'
  25. magicint2version: in this dictionary, the key is a magic integer, e.g. 62211,
  26. and the value is its canonic versions string, e.g. '2.7'
  27. PYTHON_MAGIC_INT: The magic integer for the current running Python interpreter
  28. """
  29. import re
  30. import struct
  31. import sys
  32. from importlib.util import MAGIC_NUMBER as MAGIC
  33. from typing import Dict, Set
  34. from xdis.version_info import IS_GRAAL, IS_PYPY, IS_RUST, version_tuple_to_str
  35. GRAAL3_MAGICS = (21150, 21280, 21290)
  36. JYTHON_MAGICS = (1011, 65526)
  37. # See below for mappting to version numbers
  38. PYPY3_MAGICS = (48, 64, 112, 160, 192, 240, 244, 256, 320, 336, 384, 416)
  39. RUSTPYTHON_MAGICS = (
  40. 12641, # RustPython 3.12
  41. 12897, # RustPython 3.12
  42. 13413, # RustPython 3.13
  43. 24881, # RustPython 3.13
  44. )
  45. def add_magic_from_int(magic_int: int, version: str) -> None:
  46. magicint2version[magic_int] = version
  47. versions[int2magic(magic_int)] = version
  48. def int2magic(magic_int: int) -> bytes:
  49. """Given a magic int like 62211, compute the corresponding magic byte string
  50. b'\x03\xf3\r\n' using the conversion method that does this.
  51. See also dictionary magic2nt2version which has precomputed these values
  52. for known magic_int's.
  53. """
  54. if magic_int in (39170, 39171):
  55. return struct.pack("<H", magic_int) + b"\x99\x00"
  56. return struct.pack("<Hcc", magic_int, bytes("\r", "utf-8"), bytes("\n", "utf-8"))
  57. def magic2int(magic: bytes) -> int:
  58. """Given a magic byte string, e.g. b'\x03\xf3\r\n', compute the
  59. corresponding magic integer, e.g. 62211, using the conversion
  60. method that does this.
  61. See also dictionary magic2nt2version which has precomputed these values
  62. for knonwn magic_int's.
  63. """
  64. return struct.unpack("<Hcc", magic)[0]
  65. def __by_version(magic_versions: Dict[bytes, str]) -> dict:
  66. for m, version in list(magic_versions.items()):
  67. if m not in by_magic:
  68. by_magic[m] = {version}
  69. else:
  70. by_magic[m].add(version)
  71. by_version[version] = m
  72. return by_version
  73. # Documentation for the below variables is above.
  74. by_magic: Dict[bytes, Set] = {}
  75. by_version: Dict[str, bytes] = {}
  76. magicint2version: Dict[int, str] = {}
  77. versions: Dict[bytes, str] = {}
  78. PYTHON_MAGIC_INT = magic2int(MAGIC)
  79. # The magic word is used to reject .pyc files generated by other
  80. # Python versions. It should change for each incompatible change to
  81. # the bytecode.
  82. #
  83. # The value of CR and LF is incorporated so if you ever read or write
  84. # a .pyc file in text mode the magic number will be wrong; also, the
  85. # Apple MPW compiler swaps their values, botching string constants.
  86. #
  87. # The magic numbers must be spaced apart at least 2 values, as the
  88. # -U interpreter flag will cause MAGIC+1 being used. They have been
  89. # odd numbers for some time now.
  90. #
  91. # There were a variety of old schemes for setting the magic number.
  92. # The current working scheme is to increment the previous value by
  93. # 10.
  94. #
  95. # Starting with the adoption of PEP 3147 in Python 3.2, every bump in magic
  96. # number also includes a new "magic tag", i.e. a human-readable string used
  97. # to represent the magic number in __pycache__ directories. When you change
  98. # the magic number, you must also set a new unique magic tag. Generally this
  99. # can be named after the Python major version of the magic number bump, but
  100. # it can really be anything, as long as it's different from anything else
  101. # that's come before. The tags are included in the following table, starting
  102. # with Python 3.2a0.
  103. # The below is taken from Python/import.c, and more recently
  104. # Lib/importlib/_bootstrap.py and other sources
  105. # And more recently:
  106. # https://github.com/google/pytype/blob/main/pytype/pyc/magic.py
  107. # magic, canonic version number
  108. add_magic_from_int(39170, "1.0")
  109. add_magic_from_int(39171, "1.1") # covers 1.2 as well
  110. add_magic_from_int(11913, "1.3")
  111. add_magic_from_int(5892, "1.4")
  112. # 1.5, 1.5.1, 1.5.2
  113. add_magic_from_int(20121, "1.5") # 1.5.1, 1.5.2
  114. add_magic_from_int(50428, "1.6") # 1.6
  115. add_magic_from_int(50823, "2.0") # 2.0, 2.0.1
  116. add_magic_from_int(60202, "2.1") # 2.1, 2.1.1, 2.1.2
  117. add_magic_from_int(60717, "2.2") # 2.2
  118. # Two magics one version!
  119. add_magic_from_int(62011, "2.3a0")
  120. add_magic_from_int(62021, "2.3a0") # two distinct magics for the same release
  121. add_magic_from_int(62041, "2.4a0")
  122. add_magic_from_int(62051, "2.4a3")
  123. add_magic_from_int(62061, "2.4b1")
  124. add_magic_from_int(62071, "2.5a0")
  125. # ast-branch
  126. add_magic_from_int(62081, "2.5a0")
  127. add_magic_from_int(62091, "2.5a0") # with
  128. add_magic_from_int(62092, "2.5a0") # changed WITH_CLEANUP opcode
  129. add_magic_from_int(62101, "2.5b3") # fix wrong code: for x, in ...
  130. add_magic_from_int(62111, "2.5b3") # fix wrong code: x += yield
  131. # Fix wrong lnotab with for loops and storing constants that should
  132. # have been removed
  133. add_magic_from_int(62121, "2.5c1")
  134. # Fix wrong code: "for x, in ..." in listcomp/genexp
  135. add_magic_from_int(62131, "2.5c2")
  136. # Dropbox-modified Python 2.5 used in versions 1.1x and before of Dropbox
  137. add_magic_from_int(62135, "2.5dropbox")
  138. # peephole optimizations & STORE_MAP
  139. add_magic_from_int(62151, "2.6a0")
  140. # WITH_CLEANUP optimization
  141. add_magic_from_int(62161, "2.6a1")
  142. # Optimize list comprehensions/change LIST_APPEND
  143. add_magic_from_int(62171, "2.7a0")
  144. # Optimize conditional branches: introduce POP_JUMP_IF_FALSE and
  145. # POP_JUMP_IF_TRUE
  146. add_magic_from_int(62181, "2.7a0+1")
  147. add_magic_from_int(62191, "2.7a0+2") # introduce SETUP_WITH
  148. add_magic_from_int(62201, "2.7a0+3") # introduce BUILD_SET
  149. add_magic_from_int(62211, "2.7") # introduce MAP_ADD and SET_ADD
  150. add_magic_from_int(2657, "2.7pyston-0.6.1")
  151. # PyPy including pypy-2.6.1, pypy-5.0.1 PyPy adds 7 to the corresponding CPython number
  152. add_magic_from_int(62211 + 7, "2.7pypy")
  153. add_magic_from_int(3000, "3.000")
  154. add_magic_from_int(3010, "3.000+1") # removed UNARY_CONVERT
  155. add_magic_from_int(3020, "3.000+2") # added BUILD_SET
  156. add_magic_from_int(3030, "3.000+3") # added keyword-only parameters
  157. add_magic_from_int(3040, "3.000+4") # added signature annotations
  158. add_magic_from_int(3050, "3.000+5") # print becomes a function
  159. add_magic_from_int(3060, "3.000+6") # PEP 3115 metaclass syntax
  160. add_magic_from_int(3061, "3.000+7") # string literals become unicode
  161. add_magic_from_int(3071, "3.000+8") # PEP 3109 raise changes
  162. add_magic_from_int(3081, "3.000+9") # PEP 3137 make __file__ and __name__ unicode
  163. add_magic_from_int(3091, "3.000+10") # kill str8 interning
  164. add_magic_from_int(3101, "3.000+11") # merge from 2.6a0, see 62151
  165. add_magic_from_int(3103, "3.000+12") # __file__ points to source file
  166. add_magic_from_int(3111, "3.0a4") # WITH_CLEANUP optimization
  167. add_magic_from_int(3131, "3.0a5") # lexical exception stacking, including POP_EXCEPT
  168. add_magic_from_int(3141, "3.1a0") # optimize list, set and dict comprehensions
  169. add_magic_from_int(3151, "3.1a0+") # optimize conditional branches
  170. add_magic_from_int(3160, "3.2a0") # add SETUP_WITH
  171. add_magic_from_int(3170, "3.2a1") # add DUP_TOP_TWO, remove DUP_TOPX and ROT_FOUR
  172. add_magic_from_int(3180, "3.2a2") # 3.2a2 (add DELETE_DEREF)
  173. # Python 3.2.5 - PyPy 2.3.4 PyPy adds 7 to the corresponding CPython
  174. # number
  175. add_magic_from_int(3180 + 7, "3.2pypy")
  176. add_magic_from_int(3190, "3.3a0") # __class__ super closure changed
  177. add_magic_from_int(3200, "3.3a0+") # __qualname__ added
  178. add_magic_from_int(3220, "3.3a1") # changed PEP 380 implementation
  179. # Added size modulo 2**32 to the pyc header
  180. # NOTE: 3.3a2 is our name, other places call it 3.3
  181. # but most 3.3 versions are 3.3a4 which comes next.
  182. # FIXME: figure out what the history is and
  183. # what the right thing to do if this isn't it.
  184. add_magic_from_int(3210, "3.3a2")
  185. add_magic_from_int(3230, "3.3a4") # revert changes to implicit __class__ closure
  186. # Evaluate positional default arg keyword-only defaults
  187. add_magic_from_int(3250, "3.4a1")
  188. # Add LOAD_CLASSDEREF; add_magic_from_int locals, f class to override free vars
  189. add_magic_from_int(3260, "3.4a1+1")
  190. add_magic_from_int(3270, "3.4a1+2") # various tweaks to the __class__ closure
  191. add_magic_from_int(3280, "3.4a1+3") # remove implicit class argument
  192. add_magic_from_int(3290, "3.4a4") # changes to __qualname__ computation
  193. add_magic_from_int(3300, "3.4a4+") # more changes to __qualname__ computation
  194. add_magic_from_int(3310, "3.4rc2") # alter __qualname__ computation
  195. add_magic_from_int(3320, "3.5a0") # matrix multiplication operator
  196. add_magic_from_int(3330, "3.5b1") # pep 448: additional unpacking generalizations
  197. add_magic_from_int(3340, "3.5b2") # fix dictionary display evaluation order #11205
  198. add_magic_from_int(3350, "3.5") # add GET_YIELD_FROM_ITER opcode #24400 (also 3.5b2)
  199. add_magic_from_int(
  200. 3351, "3.5.2"
  201. ) # fix BUILD_MAP_UNPACK_WITH_CALL opcode #27286; 3.5.3, 3.5.4, 3.5.5
  202. add_magic_from_int(3360, "3.6a0") # add FORMAT_VALUE opcode #25483
  203. add_magic_from_int(3361, "3.6a0+1") # lineno delta of code.co_lnotab becomes signed
  204. add_magic_from_int(3370, "3.6a1") # 16 bit wordcode
  205. add_magic_from_int(3371, "3.6a1+1") # add BUILD_CONST_KEY_MAP opcode #27140
  206. add_magic_from_int(
  207. 3372, "3.6a1+2"
  208. ) # MAKE_FUNCTION simplification, remove MAKE_CLOSURE #27095
  209. add_magic_from_int(3373, "3.6b1") # add BUILD_STRING opcode #27078
  210. # add SETUP_ANNOTATIONS and STORE_ANNOTATION opcodes #27985
  211. add_magic_from_int(3375, "3.6b1+1")
  212. # simplify CALL_FUNCTION* & BUILD_MAP_UNPACK_WITH_CALL
  213. add_magic_from_int(3376, "3.6b1+2")
  214. # set __class__ cell from type.__new__ #23722
  215. add_magic_from_int(3377, "3.6b1+3")
  216. # add BUILD_TUPLE_UNPACK_WITH_CALL #28257
  217. add_magic_from_int(3378, "3.6b2")
  218. # more thorough __class__ validation #23722
  219. add_magic_from_int(3379, "3.6rc1")
  220. # add LOAD_METHOD and CALL_METHOD opcodes #26110
  221. add_magic_from_int(3390, "3.7.0alpha0")
  222. # update GET_AITER #31709
  223. add_magic_from_int(3391, "3.7.0alpha3")
  224. # Initial PEP 552 - Deterministic pycs #31650
  225. # Additional word in header and possibly no timestamp
  226. add_magic_from_int(3392, "3.7.0beta2")
  227. # Final PEP 552: timestamp + size field or no timestamp + SipHash
  228. # remove STORE_ANNOTATION opcode #3255
  229. add_magic_from_int(3393, "3.7.0beta3")
  230. # restored docstring as the first stmt in the body; this might
  231. # affect the first line number #32911
  232. add_magic_from_int(3394, "3.7.0")
  233. # move frame block handling to compiler #17611
  234. add_magic_from_int(3400, "3.8.0a1")
  235. # add END_ASYNC_FOR #33041
  236. add_magic_from_int(3401, "3.8.0a3+")
  237. # PEP570 Python Positional-Only Parameters #36540
  238. add_magic_from_int(3410, "3.8.0a1+")
  239. # Reverse evaluation order of key: value in dict comprehensions #35224
  240. add_magic_from_int(3411, "3.8.0b2+")
  241. # Swap the position of positional args and positional only args in
  242. # ast.arguments #37593
  243. add_magic_from_int(3412, "3.8.0beta2")
  244. # Fix "break" and "continue" in "finally" #37830
  245. add_magic_from_int(3413, "3.8.0rc1+")
  246. # add LOAD_ASSERTION_ERROR #34880
  247. add_magic_from_int(3420, "3.9.0a0")
  248. # simplified bytecode for with blocks #32949
  249. add_magic_from_int(3421, "3.9.0a0")
  250. # Remove BEGIN_FINALLY, END_FINALLY, CALL_FINALLY, POP_FINALLY bytecodes #33387
  251. add_magic_from_int(3422, "3.9.0alpha1")
  252. # add IS_OP, CONTAINS_OP and JUMP_IF_NOT_EXC_MATCH bytecodes #39156
  253. add_magic_from_int(3423, "3.9.0a0")
  254. # simplify bytecodes for *value unpacking
  255. add_magic_from_int(3424, "3.9.0a2")
  256. # simplify bytecodes for **value unpacking
  257. add_magic_from_int(3425, "3.9.0beta5")
  258. # Make 'annotations' future by default
  259. add_magic_from_int(3430, "3.10a1")
  260. # New line number table format -- PEP 626
  261. add_magic_from_int(3431, "3.10a1")
  262. # Function annotation for MAKE_FUNCTION is changed from dict to tuple bpo-42202
  263. add_magic_from_int(3432, "3.10a2")
  264. # RERAISE restores f_lasti if oparg != 0
  265. add_magic_from_int(3433, "3.10a2")
  266. # PEP 634: Structural Pattern Matching
  267. add_magic_from_int(3434, "3.10a6")
  268. # Use instruction offsets (as opposed to byte offsets)
  269. add_magic_from_int(3435, "3.10a7")
  270. # Add GEN_START bytecode #43683
  271. add_magic_from_int(3436, "3.10b1a")
  272. # Undo making 'annotations' future by default - We like to dance among core devs!
  273. add_magic_from_int(3437, "3.10b1b")
  274. # Safer line number table handling.
  275. add_magic_from_int(3438, "3.10b1c")
  276. # Add ROT_N
  277. add_magic_from_int(3439, "3.10.b1")
  278. # Use exception table for unwinding ("zero cost" exception handling)
  279. add_magic_from_int(3450, "3.11a1a")
  280. # Add CALL_METHOD_KW
  281. add_magic_from_int(3451, "3.11a1b")
  282. # drop nlocals from marshaled code objects
  283. add_magic_from_int(3452, "3.11a1c")
  284. # add co_fastlocalnames and co_fastlocalkinds
  285. add_magic_from_int(3453, "3.11a1d")
  286. # compute cell offsets relative to locals bpo-43693
  287. add_magic_from_int(3454, "3.11a1e")
  288. # add MAKE_CELL bpo-43693
  289. add_magic_from_int(3455, "3.11a1f")
  290. # interleave cell args bpo-43693
  291. add_magic_from_int(3456, "3.11a1g")
  292. # Change localsplus to a bytes object bpo-43693
  293. add_magic_from_int(3457, "3.11a1h")
  294. # imported objects now don't use LOAD_METHOD/CALL_METHOD
  295. add_magic_from_int(3458, "3.11a1i")
  296. # PEP 657: add end line numbers and column offsets for instructions
  297. add_magic_from_int(3459, "3.11a1j")
  298. # Add co_qualname field to PyCodeObject bpo-44530
  299. add_magic_from_int(3460, "3.11a1k")
  300. # JUMP_ABSOLUTE must jump backwards
  301. add_magic_from_int(3461, "3.11a1l")
  302. # bpo-44511: remove COPY_DICT_WITHOUT_KEYS, change
  303. # MATCH_CLASS and MATCH_KEYS, and add COPY
  304. add_magic_from_int(3462, "3.11a2")
  305. # bpo-45711: JUMP_IF_NOT_EXC_MATCH no longer pops the
  306. # active exception)
  307. add_magic_from_int(3463, "3.11a3a")
  308. # bpo-45636: Merge numeric BINARY_*/INPLACE_* into
  309. # BINARY_OP
  310. add_magic_from_int(3464, "3.11a3b")
  311. # Add COPY_FREE_VARS opcode
  312. add_magic_from_int(3465, "3.11a4a")
  313. # bpo-45292: PEP-654 except*
  314. add_magic_from_int(3466, "3.11a4b")
  315. # Change CALL_xxx opcodes
  316. add_magic_from_int(3466, "3.11a4c")
  317. add_magic_from_int(3467, "3.11a4d")
  318. add_magic_from_int(3468, "3.11a4e")
  319. add_magic_from_int(3469, "3.11a4f")
  320. add_magic_from_int(3470, "3.11a4g")
  321. add_magic_from_int(3471, "3.11a4h")
  322. add_magic_from_int(3472, "3.11a4i")
  323. add_magic_from_int(3473, "3.11a4j")
  324. add_magic_from_int(3474, "3.11a4k")
  325. add_magic_from_int(3475, "3.11a5a")
  326. add_magic_from_int(3476, "3.11a5b")
  327. add_magic_from_int(3477, "3.11a5c")
  328. add_magic_from_int(3478, "3.11a5d")
  329. add_magic_from_int(3479, "3.11a5e")
  330. add_magic_from_int(3480, "3.11a5e")
  331. add_magic_from_int(3481, "3.11a5f")
  332. add_magic_from_int(3482, "3.11a5g")
  333. add_magic_from_int(3483, "3.11a5h")
  334. add_magic_from_int(3484, "3.11a5i")
  335. add_magic_from_int(3485, "3.11a5j")
  336. add_magic_from_int(3486, "3.11a6a")
  337. add_magic_from_int(3487, "3.11a6b")
  338. add_magic_from_int(3488, "3.11a6c")
  339. add_magic_from_int(3489, "3.11a6d")
  340. add_magic_from_int(3490, "3.11a6d")
  341. add_magic_from_int(3491, "3.11a7a")
  342. add_magic_from_int(3492, "3.11a7b")
  343. add_magic_from_int(3493, "3.11a7c")
  344. add_magic_from_int(3494, "3.11a7d")
  345. add_magic_from_int(3495, "3.11a7e")
  346. # 3.12
  347. # Remove PRECALL opcode)
  348. add_magic_from_int(3500, "3.12a1a")
  349. # YIELD_VALUE oparg == stack_depth
  350. add_magic_from_int(3501, "3.12a1b")
  351. # LOAD_FAST_CHECK, no NULL-check in LOAD_FAST
  352. add_magic_from_int(3502, "3.12a1c")
  353. # Shrink LOAD_METHOD cache
  354. add_magic_from_int(3503, "3.12a1d")
  355. # Merge LOAD_METHOD back into LOAD_ATTR
  356. add_magic_from_int(3504, "3.12a1e")
  357. # Specialization/Cache for FOR_ITER
  358. add_magic_from_int(3505, "3.12a1f")
  359. # Add BINARY_SLICE and STORE_SLICE instructions
  360. add_magic_from_int(3506, "3.12a1g")
  361. # Set lineno of module's RESUME to 0
  362. add_magic_from_int(3507, "3.12a1h")
  363. # Add CLEANUP_THROW
  364. add_magic_from_int(3508, "3.12a1i")
  365. add_magic_from_int(3509, "3.12a1j")
  366. add_magic_from_int(3510, "3.12a2a")
  367. add_magic_from_int(3511, "3.12a2b")
  368. add_magic_from_int(3512, "3.12a2c")
  369. add_magic_from_int(3513, "3.12a4a")
  370. add_magic_from_int(3514, "3.12a4b")
  371. add_magic_from_int(3515, "3.12a5a")
  372. add_magic_from_int(3516, "3.12a5b")
  373. add_magic_from_int(3517, "3.12a5c")
  374. add_magic_from_int(3518, "3.12a6a")
  375. add_magic_from_int(3519, "3.12a6b")
  376. add_magic_from_int(3520, "3.12a6c")
  377. add_magic_from_int(3521, "3.12a7a")
  378. add_magic_from_int(3522, "3.12a7b")
  379. add_magic_from_int(3523, "3.12a7c")
  380. add_magic_from_int(3524, "3.12a7d")
  381. add_magic_from_int(3525, "3.12b1a")
  382. add_magic_from_int(3526, "3.12b1b")
  383. add_magic_from_int(3527, "3.12b1c")
  384. add_magic_from_int(3528, "3.12b1d")
  385. add_magic_from_int(3529, "3.12b1e")
  386. add_magic_from_int(3530, "3.12b1f")
  387. add_magic_from_int(3531, "3.12b1g")
  388. add_magic_from_int(3531, "3.12.0rc2")
  389. add_magic_from_int(3531, "3.12.0rc2")
  390. # 3.13
  391. # Plugin optimizer support
  392. add_magic_from_int(3550, "3.13a1a")
  393. # Compact superinstructions
  394. add_magic_from_int(3551, "3.13a1b")
  395. # Remove LOAD_FAST__LOAD_CONST and LOAD_CONST__LOAD_FAST
  396. add_magic_from_int(3552, "3.13a1c")
  397. # Add SET_FUNCTION_ATTRIBUTE
  398. add_magic_from_int(3553, "3.13a1d")
  399. # more efficient bytecodes for f-strings
  400. add_magic_from_int(3554, "3.13a1e")
  401. # generate specialized opcodes metadata from bytecodes.c
  402. add_magic_from_int(3555, "3.13a1f")
  403. # Convert LOAD_CLOSURE to a pseudo-op
  404. add_magic_from_int(3556, "3.13a1g")
  405. add_magic_from_int(3557, "3.13a1h")
  406. add_magic_from_int(3558, "3.13a1i")
  407. add_magic_from_int(3559, "3.13a1j")
  408. add_magic_from_int(3560, "3.13a1k")
  409. add_magic_from_int(3561, "3.13a1l")
  410. add_magic_from_int(3562, "3.13a1m")
  411. add_magic_from_int(3563, "3.13a1n")
  412. add_magic_from_int(3564, "3.13a1o")
  413. add_magic_from_int(3565, "3.13a1p")
  414. add_magic_from_int(3566, "3.13a1q")
  415. add_magic_from_int(3567, "3.13a1e")
  416. add_magic_from_int(3568, "3.13a1s")
  417. add_magic_from_int(3569, "3.13a5")
  418. add_magic_from_int(3570, "3.13a6")
  419. add_magic_from_int(3571, "3.13.0rc3")
  420. # Add LOAD_COMMON_CONSTANT
  421. add_magic_from_int(3600, "3.14a1a")
  422. # Fix miscompilation of private names in generic classes
  423. add_magic_from_int(3601, "3.14a1b")
  424. # Add LOAD_SPECIAL. Remove BEFORE_WITH and BEFORE_ASYNC_WITH
  425. add_magic_from_int(3602, "3.14a1c")
  426. # Remove BUILD_CONST_KEY_MAP
  427. add_magic_from_int(3603, "3.14a1d")
  428. # Do not duplicate test at end of while statements
  429. add_magic_from_int(3604, "3.14a1e")
  430. # Move ENTER_EXECUTOR to opcode 255
  431. add_magic_from_int(3605, "3.14a1f")
  432. # Specialize CALL_KW
  433. add_magic_from_int(3606, "3.14a1g")
  434. # Add pseudo instructions JUMP_IF_TRUE/FALSE
  435. add_magic_from_int(3607, "3.14a1h")
  436. # Add support for slices
  437. add_magic_from_int(3608, "3.14a1i")
  438. # Add LOAD_SMALL_INT and LOAD_CONST_IMMORTAL instructions, remove RETURN_CONST
  439. add_magic_from_int(3608, "3.14a2")
  440. # Add VALUE_WITH_FAKE_GLOBALS format to annotationlib
  441. add_magic_from_int(3610, "3.14a4a")
  442. # Add NOT_TAKEN instruction
  443. add_magic_from_int(3611, "3.14a4b")
  444. # Add LOAD_CONST_MORTAL instruction
  445. add_magic_from_int(3613, "3.14a4c")
  446. # Add BINARY_OP_EXTEND
  447. add_magic_from_int(3614, "3.14a4d")
  448. # Add BINARY_OP_EXTEND
  449. add_magic_from_int(3615, "3.14a5a")
  450. # Add BINARY_OP_EXTEND
  451. add_magic_from_int(3616, "3.14a5a")
  452. # Branch monitoring for async for loops
  453. add_magic_from_int(3617, "3.14a6a")
  454. # Add oparg to END_ASYNC_FOR
  455. add_magic_from_int(3618, "3.14a6b")
  456. # Renumber RESUME opcode from 149 to 128
  457. add_magic_from_int(3619, "3.14a6c")
  458. # Optimize bytecode for all/any/tuple called on a genexp
  459. add_magic_from_int(3620, "3.14a7a")
  460. # Optimize LOAD_FAST opcodes into LOAD_FAST_BORROW
  461. add_magic_from_int(3621, "3.14a7b")
  462. # Store annotations in different class dict keys
  463. add_magic_from_int(3622, "3.14a7c")
  464. # Add BUILD_INTERPOLATION & BUILD_TEMPLATE opcodes
  465. add_magic_from_int(3623, "3.14a7d")
  466. # Don't optimize LOAD_FAST when local is killed by DELETE_FAST
  467. add_magic_from_int(3624, "3.14b1")
  468. # Fix handling of opcodes that may leave operands on the stack when optimizing LOAD_FAST
  469. add_magic_from_int(3625, "3.14b3")
  470. add_magic_from_int(3627, "3.14rc3")
  471. # add_magic_from_int(3655, "3.15.0a0")
  472. # NOTE: this will change on release!
  473. add_magic_from_int(3655, "3.15.0")
  474. # Weird ones
  475. # WTF? Python 3.2.5 and PyPy have weird magic numbers
  476. # Often, PyPY increases its magic number by 16.
  477. add_magic_from_int(48, "3.2a2")
  478. add_magic_from_int(64, "3.3pypy")
  479. add_magic_from_int(112, "3.5pypy") # pypy3.5-c-jit-latest
  480. add_magic_from_int(160, "3.6.1pypy") # '3.6.1 ... PyPy 7.1.0-beta0'
  481. add_magic_from_int(192, "3.6pypy") # '3.6.9 ... PyPy 7.1.0-beta0'
  482. add_magic_from_int(224, "3.7pypy") # PyPy 3.7.9-beta0
  483. add_magic_from_int(240, "3.7pypy") # PyPy 3.7.9-beta0
  484. add_magic_from_int(256, "3.8pypy") # PyPy 3.8.15
  485. add_magic_from_int(320, "3.9pypy") # PyPy 3.9-v7.3.8
  486. add_magic_from_int(336, "3.9pypy") # PyPy 3.9.15, PyPy 3.9.17
  487. add_magic_from_int(384, "3.10pypy") # PyPy 3.10.12
  488. add_magic_from_int(416, "3.11.13pypy") # PyPy 3.11.13 or pypy3.11-7.3.20
  489. add_magic_from_int(12641, "3.12.0a.rust") # RustPython 3.12.0
  490. add_magic_from_int(12897, "3.13.0b.rust") # RustPython 3.12.0
  491. add_magic_from_int(13413, "3.13.0a.rust") # RustPython 3.13.0
  492. add_magic_from_int(24881, "3.13.0b.rust") # RustPython 3.13.0
  493. # Graal uses JVM bytecode, not Python bytecode
  494. add_magic_from_int(21150, "3.8.5Graal")
  495. # Graal Java 21.0.2
  496. add_magic_from_int(21280, "3.10.8Graal")
  497. add_magic_from_int(21290, "3.11.7Graal")
  498. # Jython uses JVM bytecode, not Python bytecode.
  499. add_magic_from_int(1011, "2.7.1b3Jython") # Jython 2.7.2b3
  500. add_magic_from_int(65226, "2.7.4Jython") # Jython 2.7.4
  501. # Pyston
  502. add_magic_from_int(22138, "2.7.7Pyston") # 2.7.8pyston, pyston-0.6.0
  503. magics = __by_version(versions)
  504. magics["3.8.12pypy"] = magics["3.8.0rc1+"]
  505. magics["3.9.15pypy"] = magics["3.9.0alpha1"]
  506. magics["3.9.16pypy"] = magics["3.9.0alpha1"]
  507. # From a Python version given in sys.info, e.g. 3.6.1,
  508. # what is the "canonic" version number, e.g. '3.6.0rc1'
  509. canonic_python_version = {}
  510. def add_canonic_versions(release_versions: str, canonic: str) -> None:
  511. for version in release_versions.split():
  512. canonic_python_version[version] = canonic
  513. magics[version] = magics[canonic]
  514. add_canonic_versions("1.5.1 1.5.2", "1.5")
  515. add_canonic_versions("2.0.1", "2.0")
  516. add_canonic_versions("2.1.1 2.1.2 2.1.3", "2.1")
  517. add_canonic_versions("2.2.3", "2.2")
  518. add_canonic_versions("2.3 2.3.7", "2.3a0")
  519. add_canonic_versions("2.4 2.4.0 2.4.1 2.4.2 2.4.3 2.4.5 2.4.6", "2.4b1")
  520. add_canonic_versions("2.5 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6", "2.5c2")
  521. add_canonic_versions("2.6 2.6.6 2.6.7 2.6.8 2.6.9", "2.6a1")
  522. add_canonic_versions(
  523. "2.7.0 2.7.1 2.7.2 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 "
  524. "2.7.8 2.7.9 2.7.10 2.7.11 2.7.12 2.7.13 2.7.14 2.7.15 "
  525. "2.7.15candidate1 "
  526. "2.7.16 "
  527. "2.7.17rc1 2.7.17candidate1 2.7.17 2.7.18 2.7.18candidate1",
  528. "2.7",
  529. )
  530. add_canonic_versions("3.0 3.0.0 3.0.1", "3.0a5")
  531. add_canonic_versions("3.1 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5", "3.1a0+")
  532. add_canonic_versions("3.2 3.2.0 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6", "3.2a2")
  533. add_canonic_versions(
  534. "3.3 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7rc1 3.3.7", "3.3a4"
  535. )
  536. add_canonic_versions(
  537. "3.4 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.6 3.4.7 3.4.8 3.4.9 3.4.10", "3.4rc2"
  538. )
  539. add_canonic_versions("3.5 3.5.0 3.5.1", "3.5")
  540. add_canonic_versions(
  541. "3.5.2 3.5.3 3.5.4 3.5.5 3.5.6 3.5.7 3.5.8 3.5.9 " "3.5.10", "3.5.2"
  542. )
  543. add_canonic_versions(
  544. "3.6b2 3.6 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.6.8 "
  545. "3.6.9 3.6.10 3.6.11 3.6.12 3.6.13 3.6.14 3.6.15",
  546. "3.6rc1",
  547. )
  548. add_canonic_versions("3.7b1", "3.7.0beta3")
  549. add_canonic_versions("3.8a1", "3.8.0beta2")
  550. add_canonic_versions("2.7.10pypy 2.7.12pypy 2.7.13pypy 2.7.18pypy", "2.7pypy")
  551. add_canonic_versions("2.7.3b0Jython", "2.7.1b3Jython")
  552. add_canonic_versions("3.8.5Graal", "3.8.5Graal")
  553. add_canonic_versions("3.8.10Graal", "3.8.0rc1+")
  554. add_canonic_versions("3.2.5pypy", "3.2pypy")
  555. add_canonic_versions("3.3.5pypy", "3.3pypy")
  556. add_canonic_versions("3.5.3pypy", "3.5pypy")
  557. add_canonic_versions("3.6.9pypy 3.6.12pypy", "3.6pypy")
  558. add_canonic_versions("3.7.0pypy 3.7.9pypy 3.7.10pypy 3.7.12pypy 3.7.13pypy", "3.7pypy")
  559. add_canonic_versions("3.8.0pypy 3.8.12pypy 3.8.13pypy 3.8.15pypy", "3.8.12pypy")
  560. add_canonic_versions("3.8.16pypy", "3.8pypy")
  561. add_canonic_versions("3.9.17pypy 3.9.18pypy 3.9.19pypy", "3.9pypy")
  562. add_canonic_versions("3.10.12pypy 3.10.13pypy 3.10.14pypy 3.10pypy", "3.10pypy")
  563. add_canonic_versions("2.7.8Pyston", "2.7.7Pyston")
  564. add_canonic_versions("3.7.0alpha3", "3.7.0alpha3")
  565. add_canonic_versions(
  566. "3.7 3.7.0beta5 3.7.1 3.7.2 3.7.3 3.7.4 3.7.5 3.7.6 3.7.7 3.7.8 3.7.9 "
  567. "3.7.10 3.7.11 3.7.12 3.7.13 3.7.14 3.7.15 3.7.16 3.7.17",
  568. "3.7.0",
  569. )
  570. add_canonic_versions("3.8.0alpha0 3.8.0alpha3 3.8.0a0", "3.8.0a3+")
  571. add_canonic_versions(
  572. "3.8b4 3.8.0candidate1 3.8 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.8.6 3.8.7 3.8.8 "
  573. "3.8.9 3.8.10 3.8.11 3.8.12 3.8.13 3.8.14 3.8.15 3.8.16 3.8.17 3.8.18 3.8.19 3.8.20",
  574. "3.8.0rc1+",
  575. )
  576. add_canonic_versions(
  577. "3.9 3.9.0 3.9.0a1+ 3.9.0a2+ 3.9.0alpha1 3.9.0alpha2", "3.9.0alpha1"
  578. )
  579. add_canonic_versions(
  580. "3.9 3.9.0 3.9.1 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9 3.9.10 3.9.11 "
  581. "3.9.12 3.9.13 3.9.14 3.9.14 3.9.15 3.9.16 3.9.17 3.9.18 3.9.19 3.9.10pypy 3.9.11pypy 3.9.12pypy "
  582. "3.9.15pypy 3.9.16pypy 3.9.0b5+ 3.9.17 3.9.18 3.9.19 3.9.20 3.9.21 3.9.22 3.9.23 3.9.24",
  583. "3.9.0beta5",
  584. )
  585. add_canonic_versions(
  586. "3.10 3.10.0 3.10.1 3.10.2 3.10.3 3.10.4 3.10.5 3.10.6 3.10.7 3.10.8 3.10.9 "
  587. "3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.16 3.10.17 3.10.18 3.10.19",
  588. "3.10.b1",
  589. )
  590. add_canonic_versions("3.10.13Graal", "3.10.8Graal")
  591. add_canonic_versions(
  592. "3.11 3.11.0 3.11.1 3.11.2 3.11.3 3.11.4 3.11.5 3.11.6 3.11.7 3.11.8 3.11.9 3.11.10 "
  593. "3.11.11 3.11.12 3.11.13 3.11.14",
  594. "3.11a7e",
  595. )
  596. add_canonic_versions(
  597. "3.12 3.12.0 3.12.1 3.12.2 3.12.3 3.12.4 3.12.5 3.12.6 3.12.7 3.12.8 3.12.9 3.12.10 3.12.11 3.12.12",
  598. "3.12.0rc2",
  599. )
  600. add_canonic_versions(
  601. "3.13 3.13.0 3.13.1 3.13.2 3.13.3 3.13.4 3.13.5 3.13.6 3.13.7 3.13.8 3.13.9",
  602. "3.13.0rc3",
  603. )
  604. add_canonic_versions("3.14-dev", "3.14b3")
  605. add_canonic_versions("3.14 3.14.0", "3.14rc3")
  606. add_canonic_versions(
  607. "3.15 3.15.0a1 3.15-dev 3.15.0a0",
  608. "3.15.0",
  609. )
  610. # The canonic version for a canonic version is itself
  611. for v in versions.values():
  612. canonic_python_version[v] = v
  613. # A set of all Python versions we know about
  614. python_versions = set(canonic_python_version.keys())
  615. def __show(text, magic) -> None:
  616. print(text, struct.unpack("BBBB", magic), struct.unpack("<HBB", magic))
  617. def magic_int2tuple(magic_int: int) -> tuple:
  618. """Convert a Python magic int into a 'canonic' tuple
  619. e.g. (2, 7), (3, 7). runtime error is raised if "version" is not found.
  620. Note that there can be several magic_int's that map to a single floating-point
  621. number. For example 3320 (3.5.a0), 3340 (3.5b1)
  622. all map to 3.5.
  623. """
  624. return py_str2tuple(magicint2version[magic_int])
  625. def py_str2tuple(orig_version: str) -> tuple[int, int] | tuple[int, int, int]:
  626. """Convert a Python version into a tuple number,
  627. e.g. (2, 5), (3, 6).
  628. A runtime error is raised if "version" is not found.
  629. Note that there can be several strings that map to a single
  630. tuple. For example 3.2a1, 3.2.0, 3.2.2, 3.2.6 among others all map
  631. to (3, 2).
  632. """
  633. version = re.sub(r"(pypy|dropbox)$", "", orig_version)
  634. if version in magics:
  635. m = re.match(r"^(\d)\.(\d+)\.(\d+)", version)
  636. if m:
  637. return int(m.group(1)), int(m.group(2)), int(m.group(3))
  638. else:
  639. # Match things like 3.5a0, 3.5b2, 3.6a1+1, 3.6rc1, 3.7.0beta3
  640. m = re.match(r"^(\d)\.(\d(\d+)?)[abr]?", version)
  641. if m:
  642. return int(m.group(1)), int(m.group(2))
  643. pass
  644. pass
  645. raise RuntimeError(
  646. "Can't find a valid Python version for version %s" % orig_version
  647. )
  648. def sysinfo2magic(version_info: tuple = tuple(sys.version_info)) -> bytes:
  649. """Convert a list sys.versions_info compatible list into a 'canonic'
  650. The magic bytes value found at the beginning of a bytecode file.
  651. b'?!\r\n' is returned if we can't find a version.
  652. """
  653. vers_str = version_tuple_to_str(version_info)
  654. if version_info[3] != "final":
  655. vers_str += version_tuple_to_str(version_info, start=3)
  656. if IS_PYPY:
  657. vers_str += "pypy"
  658. elif IS_GRAAL:
  659. vers_str += "Graal"
  660. elif IS_RUST:
  661. vers_str += "Rust"
  662. else:
  663. try:
  664. import platform
  665. platform_str = platform.python_implementation()
  666. if platform_str in ("GraalVM", "Jython", "Pyston", "RustPython"):
  667. vers_str += platform_str
  668. pass
  669. except ImportError:
  670. # Python may be too old, e.g. < 2.6 or implementation may
  671. # just not have platform
  672. pass
  673. return magics.get(vers_str, b"?!\r\n")
  674. def test() -> None:
  675. magic_20 = magics["2.0"]
  676. magic_current = by_magic[MAGIC]
  677. print(type(magic_20), len(magic_20), repr(magic_20))
  678. print()
  679. print("This Python interpreter has versions:", magic_current)
  680. print("Magic code: ", PYTHON_MAGIC_INT)
  681. print(type(magic_20), len(magic_20), repr(magic_20))
  682. assert sysinfo2magic() == MAGIC, (sysinfo2magic(), MAGIC)
  683. if __name__ == "__main__":
  684. test()