Skip to content

Commit a6861d2

Browse files
author
rocky
committed
Work on Python 3.4+ marshal. This uses ref objects
1 parent b296a87 commit a6861d2

File tree

6 files changed

+389
-238
lines changed

6 files changed

+389
-238
lines changed

test/Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ check: check-short check-roundtrip
2727
--bytecode-pypy35 --bytecode-pypy36 --bytecode-pypy37 \
2828
--bytecode-pypy38 --bytecode-pypy39 --bytecode-pypy310 $(COMPILE)
2929

30-
check-roundtrip: check-roundtrip-3.0 check-roundtrip-3.1 check-roundtrip-3.3
30+
check-roundtrip: check-roundtrip-3.0 check-roundtrip-3.1 check-roundtrip-3.3 check-roundtrip-3.4
3131

3232
check-roundtrip-3.0:
3333
./test_pyc_roundtrip.py --bytecode-3.0
@@ -38,6 +38,9 @@ check-roundtrip-3.1:
3838
check-roundtrip-3.3:
3939
./test_pyc_roundtrip.py --bytecode-3.3
4040

41+
check-roundtrip-3.4:
42+
./test_pyc_roundtrip.py --bytecode-3.4
43+
4144
check-short:
4245
$(PYTHON) test_pyenvlib.py --simple
4346

452 Bytes
Binary file not shown.

xdis/codetype/__init__.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
import types
1818
from collections import namedtuple
19-
from typing import Any, Dict, Optional, Tuple, Union
19+
from typing import Any, Dict, Optional, Set, Tuple, Union
2020

2121
from xdis.codetype.base import CodeBase
2222
from xdis.codetype.code13 import Code13
@@ -63,7 +63,8 @@ def codeType2Portable(code, version_tuple=PYTHON_VERSION_TRIPLE):
6363

6464
# THINK ABOUT: If collection_order isn't defined, i.e. native code
6565
# type, should we try to extract it?
66-
code.collection_order if hasattr(code, "collection_order") else {}
66+
code.collection_order if hasattr(code, "collection_order") else {},
67+
code.reference_objects if hasattr(code, "reference_objects") else set(),
6768
)
6869
elif version_tuple < (3, 10):
6970
return Code38(
@@ -207,7 +208,7 @@ def portableCodeType(version_tuple=PYTHON_VERSION_TRIPLE):
207208
# In contrast to Code3, Code2, etc. you can use CodeTypeUnint for building
208209
# an incomplete code type, which might be converted to another code type
209210
# later.
210-
CodeTypeUnionFields = tuple(Code311FieldNames.split() + ["collection_order"])
211+
CodeTypeUnionFields = tuple(Code311FieldNames.split() + ["collection_order", "reference_objects"])
211212
CodeTypeUnion = namedtuple("CodeTypeUnion", CodeTypeUnionFields)
212213

213214

@@ -235,6 +236,7 @@ def to_portable(
235236
co_exceptiontable=None, # 3.11+
236237
version_triple=PYTHON_VERSION_TRIPLE,
237238
collection_order: Dict[Union[set, frozenset, dict], Tuple[Any]] = {},
239+
reference_objects: Set[Any] = set(),
238240
):
239241
code = CodeTypeUnion(
240242
co_argcount=co_argcount,
@@ -256,6 +258,7 @@ def to_portable(
256258
co_cellvars=co_cellvars,
257259
co_exceptiontable=co_exceptiontable,
258260
collection_order=collection_order,
261+
reference_objects=reference_objects,
259262
)
260263
return codeType2Portable(code, version_triple)
261264

xdis/codetype/code30.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import types
1818
from copy import deepcopy
1919
from types import CodeType
20-
from typing import Any, Dict, Tuple, Union
20+
from typing import Any, Dict, Set, Tuple, Union
2121

2222
from xdis.codetype.code20 import Code2, Code2FieldTypes
2323
from xdis.version_info import PYTHON_VERSION_TRIPLE, version_tuple_to_str
@@ -61,7 +61,8 @@ def __init__(
6161
co_lnotab,
6262
co_freevars,
6363
co_cellvars,
64-
collection_order: Dict[Union[set, frozenset, dict], Tuple[Any]] = {}
64+
collection_order: Dict[Union[set, frozenset, dict], Tuple[Any]] = {},
65+
reference_objects: Set[Any] = set(),
6566
) -> None:
6667
# Keyword argument parameters in the call below is more robust.
6768
# Since things change around, robustness is good.
@@ -84,10 +85,19 @@ def __init__(
8485
self.co_kwonlyargcount = co_kwonlyargcount
8586
self.fieldtypes = Code3FieldTypes
8687

87-
# It is helpful to save the order in sets, frozensets and dictionary keys,
88-
# so that on writing a bytecode file we can duplicate this order.
88+
# The following fields are mostly useful in marshaling a code object.
89+
# Keeping marshal order exactly the same is useful in round-trip marshal
90+
# testing; but it may also have other benefits.
91+
92+
# By saving the order in sets, frozensets, and dictionary keys,
93+
# these collections can be written in the same order that appeared
94+
# in unmarshalling (if that's how the code object was created).
8995
self.collection_order = collection_order
9096

97+
# Keeping track of which objects were referenced, allows
98+
self.reference_objects = reference_objects
99+
100+
91101
if type(self) is Code3:
92102
self.check()
93103
return

0 commit comments

Comments
 (0)