Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python 3.13 Support Draft #153

Draft
wants to merge 31 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
128577c
add old 3.12 magics
2elli Oct 3, 2024
ef4509b
update versions and organize
2elli Oct 3, 2024
5c86267
add 3.13 to op_imports and init opcodes
2elli Oct 3, 2024
ac6ceb0
add old 3.12 table forgot to add
2elli Oct 4, 2024
38b05ee
fix 3.13 compare ops formatting
2elli Oct 4, 2024
c2c4450
init 3.13 opcodes (unfinished)
2elli Oct 4, 2024
e0f4d8e
add hasexc table to 3.12
2elli Oct 7, 2024
f60f1c2
update which tables to copy for python versions 3.13+
2elli Oct 7, 2024
911a666
fix 3.13.0rc3 magic number
2elli Oct 7, 2024
f37a60c
add new 3.13 tables
2elli Oct 7, 2024
397fa1e
mistyped ops
2elli Oct 8, 2024
c84d31b
remove nonexistent ops in 3.12
2elli Oct 8, 2024
028d586
fix 3.13 hasfree table
2elli Oct 8, 2024
0a57ac7
init all changed opcodes in 3.13
2elli Oct 8, 2024
126e578
add test for matching opname and "has<xyz>" tables in xdis and dis
2elli Oct 8, 2024
43b2915
init stack effects
2elli Oct 9, 2024
b35b33c
add jump target increment on cache size
2elli Oct 9, 2024
591c45d
update stack effects
2elli Oct 9, 2024
25a9ab3
enable pydisasm on 3.13
2elli Oct 9, 2024
bdf55ab
formatting
2elli Oct 9, 2024
59de559
add setuptools so 'make check' works
2elli Oct 9, 2024
1f40b1a
remove MAKE_FUNCTION formatting
2elli Oct 9, 2024
8ed9f32
update new "HAVE_ARGUMENT" val
2elli Oct 10, 2024
409cbe0
fix CALL_KW pop and push vals
2elli Oct 11, 2024
00a4c7b
remove incorrect 3.12 import
2elli Oct 11, 2024
2bae951
fix formatting tables
2elli Oct 11, 2024
f82c0c9
Adjust Stack effect for 3.13 CALL_KW
Oct 13, 2024
97626ed
add new formatting for LOCAL_OPs with two args
2elli Oct 17, 2024
1323cd3
WIP: new code313 type with "Opaque" line table parsing (NEEDS WORK)
2elli Oct 23, 2024
375d918
Merge remote-tracking branch 'origin/3.13-more' into python-3.13
2elli Oct 23, 2024
9c2170b
finalize codetype 313 and findlinestarts313
2elli Oct 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ nose
flake8
six
pytest
setuptools
38 changes: 38 additions & 0 deletions test_unit/test_modules.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import sys
import dis
import unittest
import xdis.std as xdis
from xdis.version_info import version_tuple_to_str


class TestModules(unittest.TestCase):
def test_basic(self):
# test all ops match
if hasattr(sys, "version_info"):
print(f"Testing Python Version : {version_tuple_to_str()}")
try:
self.assertEqual(dis.opname, xdis.opname)
except AssertionError as ae:
if len(dis.opname) != len(xdis.opname):
print("Opname table length mismatch between dis and xdis")
ae.add_note("OPNAME TABLE LENGTH MISMATCH, LONGER TABLE WILL BE TRUNCATED")
for index, (dop, xop) in enumerate(zip(dis.opname, xdis.opname)):
if dop != xop:
print("-"*20)
print(f"Mismatch at op {index}")
print(f"dis opname : {dop}")
print(f"xdis opname : {xop}")
raise ae

# test "has.." tables
xmod = xdis.get_opcode_module()
attrs = (attr for attr in dir(dis) if attr.startswith("has"))
for attr in attrs:
try:
self.assertEqual(sorted(getattr(dis, attr)), sorted(getattr(xmod, attr)))
except AssertionError as ae:
ae.add_note(f"Mismatch 'has' table : {attr}")
raise ae

if __name__ == "__main__":
unittest.main()
2 changes: 2 additions & 0 deletions xdis/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
Code38,
Code310,
Code311,
Code313,
codeType2Portable,
)
from xdis.codetype.base import code_has_star_arg, code_has_star_star_arg, iscode
Expand Down Expand Up @@ -183,6 +184,7 @@
"Code3",
"Code310",
"Code311",
"Code313",
"Code38",
"code_has_star_star_arg",
"code_has_star_arg",
Expand Down
4 changes: 2 additions & 2 deletions xdis/bin/pydisasm.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ def main(format, show_source: bool, files):
the Python interpreter used to run this program. For example, you can disassemble Python 3.6.9
bytecode from Python 2.7.15 and vice versa.
"""
if not ((2, 7) <= PYTHON_VERSION_TRIPLE < (3, 13)):
mess = "This code works on 3.6 to 3.12; you have %s."
if not ((2, 7) <= PYTHON_VERSION_TRIPLE < (3, 14)):
mess = "This code works on 3.6 to 3.13; you have %s."
if (2, 4) <= PYTHON_VERSION_TRIPLE <= (2, 7):
mess += " Code that works for %s can be found in the python-2.4 branch\n"
elif (3, 1) <= PYTHON_VERSION_TRIPLE <= (3, 2):
Expand Down
21 changes: 15 additions & 6 deletions xdis/bytecode.py
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,14 @@ def get_instructions_bytes(
argval = get_jump_val(arg, opc.python_version)
argrepr = "to " + repr(argval)
elif op in opc.LOCAL_OPS:
if opc.version_tuple >= (3, 11):
if opc.version_tuple >= (3, 13) and opc.opname[op] in ("LOAD_FAST_LOAD_FAST", "STORE_FAST_LOAD_FAST", "STORE_FAST_STORE_FAST"):
arg1 = arg >> 4
arg2 = arg & 15
argval1, argrepr1 = _get_name_info(arg1, (varnames or tuple()) + (cells or tuple()))
argval2, argrepr2 = _get_name_info(arg2, (varnames or tuple()) + (cells or tuple()))
argval = argval1, argval2
argrepr = argrepr1 + ", " + argrepr2
elif opc.version_tuple >= (3, 11):
argval, argrepr = _get_name_info(
arg, (varnames or tuple()) + (cells or tuple())
)
Expand All @@ -355,11 +362,13 @@ def get_instructions_bytes(
else:
argval, argrepr = _get_name_info(arg, cells)
elif op in opc.COMPARE_OPS:
argval = (
opc.cmp_op[arg >> 4]
if opc.python_version >= (3, 12)
else opc.cmp_op[arg]
)
if opc.python_version >= (3,13):
# The fifth-lowest bit of the oparg now indicates a forced conversion to bool.
argval = (opc.cmp_op[arg >> 5])
elif opc.python_version >= (3,12):
argval = (opc.cmp_op[arg >> 4])
else:
argval = (opc.cmp_op[arg])
argrepr = argval
elif op in opc.NARGS_OPS:
opname = opc.opname[op]
Expand Down
28 changes: 26 additions & 2 deletions xdis/codetype/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from xdis.codetype.code38 import Code38
from xdis.codetype.code310 import Code310
from xdis.codetype.code311 import Code311, Code311FieldNames
from xdis.codetype.code313 import Code313
from xdis.version_info import PYTHON_VERSION_TRIPLE


Expand Down Expand Up @@ -100,7 +101,7 @@ def codeType2Portable(code, version_tuple=PYTHON_VERSION_TRIPLE):
co_firstlineno=code.co_firstlineno,
co_linetable=line_table,
)
else: # version tuple >= 3, 11
elif version_tuple[:2] < (3,13): # version tuple >= 3, 11
return Code311(
co_argcount=code.co_argcount,
co_posonlyargcount=code.co_posonlyargcount,
Expand All @@ -121,6 +122,27 @@ def codeType2Portable(code, version_tuple=PYTHON_VERSION_TRIPLE):
co_linetable=line_table,
co_exceptiontable=code.co_exceptiontable,
)
else:
return Code313(
co_argcount=code.co_argcount,
co_posonlyargcount=code.co_posonlyargcount,
co_kwonlyargcount=code.co_kwonlyargcount,
co_nlocals=code.co_nlocals,
co_stacksize=code.co_stacksize,
co_flags=code.co_flags,
co_consts=code.co_consts,
co_code=code.co_code,
co_names=code.co_names,
co_varnames=code.co_varnames,
co_freevars=code.co_freevars,
co_cellvars=code.co_cellvars,
co_filename=code.co_filename,
co_name=code.co_name,
co_qualname=code.co_qualname,
co_firstlineno=code.co_firstlineno,
co_linetable=line_table,
co_exceptiontable=code.co_exceptiontable,
)
elif version_tuple > (2, 0):
# 2.0 .. 2.7
return Code2(
Expand Down Expand Up @@ -187,9 +209,11 @@ def portableCodeType(version_tuple=PYTHON_VERSION_TRIPLE):
elif version_tuple[:2] == (3, 10):
# 3.10
return Code310
else:
elif version_tuple[:2] < (3,13):
# 3.11 ...
return Code311
else:
return Code313
elif version_tuple > (2, 0):
# 2.0 .. 2.7
return Code2
Expand Down
Loading