From eafc36fd699ca35198bb8e62c1d9e29b475a6f16 Mon Sep 17 00:00:00 2001 From: elliot Date: Tue, 23 Dec 2025 14:59:33 -0600 Subject: [PATCH 1/5] automatically make testing dirs --- test_crossversion/Makefile | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/test_crossversion/Makefile b/test_crossversion/Makefile index fa1cec3f..c656efd9 100644 --- a/test_crossversion/Makefile +++ b/test_crossversion/Makefile @@ -1,4 +1,4 @@ -.PHONY: help clean get_sources setup_pyenv compile prepare test +.PHONY: help clean get_sources setup_pyenv setup_uv compile prepare .prepare_msg test .mkdirs SOURCE=./templates/source/ COMPILED=./templates/compiled/ @@ -29,18 +29,23 @@ clean: rm -rf $(COMPILED)/* rm -rf $(SERIALIZED)/* +.mkdirs: + mkdir -p "$(SOURCE)" "$(COMPILED)" "$(SERIALIZED)" + #: copy all .py files in ./ -> ./templates/source/ get_sources: cp -f *.py $(SOURCE) .python-version: tox --listenvs | xargs pyenv local + #: setup local pyenv versions to be used by tox -setup_pyenv: .python-version +setup_pyenv: .mkdirs .python-version #: setup tox-uv so tox can use uv -setup_uv: +setup_uv: .mkdirs uv tool install tox --with tox-uv + tox --listenvs | xargs uv python install #: with each tox env, compile all sources in ./templates/source/ to ./templates/compiled/, then serialize with dis to ./templates/serialized/ compile: From 686dfdbccecbaf6e89a8485a5892b2519a48cd20 Mon Sep 17 00:00:00 2001 From: elliot Date: Tue, 23 Dec 2025 15:02:47 -0600 Subject: [PATCH 2/5] copy test files with find --- test_crossversion/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_crossversion/Makefile b/test_crossversion/Makefile index c656efd9..db5e02c6 100644 --- a/test_crossversion/Makefile +++ b/test_crossversion/Makefile @@ -34,7 +34,7 @@ clean: #: copy all .py files in ./ -> ./templates/source/ get_sources: - cp -f *.py $(SOURCE) + cp $(shell find . -name "*.py" | head -n 10 | xargs) $(SOURCE) .python-version: tox --listenvs | xargs pyenv local From de13b9618eb37bc2ddc33032a16f3e2bfe4b25f5 Mon Sep 17 00:00:00 2001 From: elliot Date: Tue, 23 Dec 2025 15:03:30 -0600 Subject: [PATCH 3/5] add better debug messages --- test_crossversion/test_xdis.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test_crossversion/test_xdis.py b/test_crossversion/test_xdis.py index 6cdc6319..270f5d18 100644 --- a/test_crossversion/test_xdis.py +++ b/test_crossversion/test_xdis.py @@ -28,8 +28,9 @@ def __init__(self, pyc: Path, serialized_txt: Path) -> None: # read serialized bytecode self.serialized_dis = serialized_txt.read_text() self.serialized_xdis = serialize_pyc(pyc, use_xdis=True, output_file=None) - # debug message + # debug messages self.message = f"{SYS_VERSION}: Checking equivalence: {self.pyc_path} <---> {self.serialized_txt_path}" + self.fail_message = f"{SYS_VERSION} failed equivalence; xdis:{self.pyc_path.name} != dis:{self.serialized_txt_path.name}" def __str__(self) -> str: return self.message @@ -64,7 +65,7 @@ def get_tests_by_version(v: str) -> Iterable[SerializedTestCase]: def test_version(version): """Test each version in compiled template folder.""" for case in get_tests_by_version(version): - assert case.serialized_dis.splitlines() == case.serialized_xdis.splitlines() + assert case.serialized_dis.splitlines() == case.serialized_xdis.splitlines(), case.fail_message ### LESS VERBOSE (fail early) ### @@ -72,4 +73,4 @@ def test_version(version): # "case", chain.from_iterable(get_tests_by_version(v) for v in get_versions()) #) #def test_case(case: SerializedTestCase) -> None: -# assert case.serialized_dis.splitlines() == case.serialized_xdis.splitlines() +# assert case.serialized_dis.splitlines() == case.serialized_xdis.splitlines(), case.fail_message From d8336dcd080fe24c38a642c81d3e9d8e2d707dc1 Mon Sep 17 00:00:00 2001 From: elliot Date: Tue, 23 Dec 2025 15:19:23 -0600 Subject: [PATCH 4/5] update usage.md --- test_crossversion/USAGE.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/test_crossversion/USAGE.md b/test_crossversion/USAGE.md index a774c367..879e959e 100644 --- a/test_crossversion/USAGE.md +++ b/test_crossversion/USAGE.md @@ -1,11 +1,11 @@ # Automated crossversion testing This testing suite is used for automatic testing of differences found between xdis and dis. -This is done by having a way to identically "serialize" important attributes in xdis and dis bytecodes. -We then can check a diff between a serialized xdis and dis bytecode to find if xdis is parsing something incorrectly. +This is done by having a way to identically "serialize" important attributes in bytecodes with xdis and dis. +Using a diff between a bytecode serialized with xdis and dis, we can find if xdis is parsing something incorrectly. Most tests should be ran using the makefile. # Parsing results -When running `make test`, tox will serialize bytecode to be put into text form. Given a bytecode compiled in 3.11 and natively disassembled, we go through each of our test versions, say 3.9 ... 3.14, and disassemble the same 3.11 bytecode. +When running `make test`, two main steps take place. 1st, we compile and serialize bytecode in each target version. 2nd, we disasm the same bytecode using xdis, serialize again, and check the diff. In other words, given a bytecode compiled in 3.11 and natively disassembled (dis), we go through each of our test versions, say 3.9 ... 3.14, and disassemble the same 3.11 bytecode. Given the 3.11 serialized disasembly, disassembled from 3.11, we take the diff between that and a serialized 3.11 disassembled from any of our test versions. This lets us see if there are any differences in how xdis handles native vs cross version. @@ -22,18 +22,20 @@ for native in test_vers: Pytest will fail early, so not all tests may be ran. -# System Requirements +# Usage +## Requirements - `uv` - uv will handle everything on its own +run `make setup_uv` ---OR--- - `pyenv` and `pyenv-virtualenv` - Each version needing to be tested should be installed with pyenv - `tox` +run `make setup_pyenv` -# Usage -## Makefile +## Running tests Run `make` or `make help` to show the help menu for running and preparing tests, or with `remake`, `remake --tasks`. To simply run tests, `make test` will copy some sources, prepare template files, and run tests. From 7c1dfbd0192dcfcd836995780f24f4f52711048f Mon Sep 17 00:00:00 2001 From: elliot Date: Tue, 23 Dec 2025 15:21:45 -0600 Subject: [PATCH 5/5] improve debug message --- test_crossversion/test_xdis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_crossversion/test_xdis.py b/test_crossversion/test_xdis.py index 270f5d18..83148b41 100644 --- a/test_crossversion/test_xdis.py +++ b/test_crossversion/test_xdis.py @@ -30,7 +30,7 @@ def __init__(self, pyc: Path, serialized_txt: Path) -> None: self.serialized_xdis = serialize_pyc(pyc, use_xdis=True, output_file=None) # debug messages self.message = f"{SYS_VERSION}: Checking equivalence: {self.pyc_path} <---> {self.serialized_txt_path}" - self.fail_message = f"{SYS_VERSION} failed equivalence; xdis:{self.pyc_path.name} != dis:{self.serialized_txt_path.name}" + self.fail_message = f"Running version {SYS_VERSION}, failed equivalence; xdis:{self.pyc_path.name} != dis:{self.serialized_txt_path.name}" def __str__(self) -> str: return self.message