diff --git a/.gitignore b/.gitignore index 7608dc7a..53ab61f7 100644 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,6 @@ dist/ downloads/ eggs/ .eggs/ -lib/ lib64/ parts/ sdist/ diff --git a/run_release.py b/run_release.py index 3bcf8b3d..e671dc0e 100755 --- a/run_release.py +++ b/run_release.py @@ -375,6 +375,49 @@ def check_cpython_repo_is_clean(db: ReleaseShelf) -> None: raise ReleaseException("Git repository is not clean") +def check_magic_number(db: ReleaseShelf) -> None: + release_tag = db["release"] + if release_tag.is_final or release_tag.is_release_candidate: + + def out(msg: str) -> None: + raise ReleaseException(msg) + + else: + + def out(msg: str) -> None: + print("warning:", msg, file=sys.stderr, flush=True) + + def get_magic(source: Path, regex: re.Pattern[str]) -> str: + if m := regex.search(source.read_text()): + return m.group("magic") + + out(f"Cannot find magic in {source}, tried {regex.pattern}") + return "unknown" + + work_dir = Path(db["git_repo"]) + magic_actual_file = work_dir / "Include" / "internal" / "pycore_magic_number.h" + magic_actual_re = re.compile( + r"^#define\s+PYC_MAGIC_NUMBER\s+(?P\d+)$", re.MULTILINE + ) + magic_actual = get_magic(magic_actual_file, magic_actual_re) + + magic_expected_file = work_dir / "Lib" / "test" / "test_importlib" / "test_util.py" + magic_expected_re = re.compile( + r"^\s+EXPECTED_MAGIC_NUMBER = (?P\d+)$", re.MULTILINE + ) + magic_expected = get_magic(magic_expected_file, magic_expected_re) + + if magic_actual == magic_expected: + return + + out( + f"Magic numbers in {magic_actual_file} ({magic_actual})" + f" and {magic_expected_file} ({magic_expected}) don't match." + ) + if not ask_question("Do you want to continue? This will fail tests in RC stage."): + raise ReleaseException("Magic numbers don't match!") + + def prepare_temporary_branch(db: ReleaseShelf) -> None: subprocess.check_call( ["git", "checkout", "-b", f"branch-{db['release']}"], cwd=db["git_repo"] @@ -1179,6 +1222,7 @@ def _api_key(api_key: str) -> str: ), Task(check_buildbots, "Check buildbots are good"), Task(check_cpython_repo_is_clean, "Checking Git repository is clean"), + Task(check_magic_number, "Checking the magic number is up-to-date"), Task(prepare_temporary_branch, "Checking out a temporary release branch"), Task(run_blurb_release, "Run blurb release"), Task(check_cpython_repo_is_clean, "Checking Git repository is clean"), diff --git a/tests/magicdata/Include/internal/pycore_magic_number.h b/tests/magicdata/Include/internal/pycore_magic_number.h new file mode 100644 index 00000000..e7c1893d --- /dev/null +++ b/tests/magicdata/Include/internal/pycore_magic_number.h @@ -0,0 +1,11 @@ +// copied from cpython bd3d31f380cd451a4ab6da5fbfde463fed95b5b5 +// ... + +#ifndef Py_INTERNAL_MAGIC_NUMBER_H +#define Py_INTERNAL_MAGIC_NUMBER_H + +#define PYC_MAGIC_NUMBER 3603 + +#endif // !Py_INTERNAL_MAGIC_NUMBER_H + +// ... diff --git a/tests/magicdata/Lib/test/test_importlib/test_util.py b/tests/magicdata/Lib/test/test_importlib/test_util.py new file mode 100644 index 00000000..c6164096 --- /dev/null +++ b/tests/magicdata/Lib/test/test_importlib/test_util.py @@ -0,0 +1,7 @@ +# copied from cpython bd3d31f380cd451a4ab6da5fbfde463fed95b5b5 + + +class SomeClass: + def some_method(self) -> None: + EXPECTED_MAGIC_NUMBER = 3495 + print(EXPECTED_MAGIC_NUMBER) diff --git a/tests/test_run_release.py b/tests/test_run_release.py index 7268ccfb..8f545bd0 100644 --- a/tests/test_run_release.py +++ b/tests/test_run_release.py @@ -1,6 +1,10 @@ +from pathlib import Path +from typing import cast + import pytest import run_release +from release import ReleaseShelf, Tag @pytest.mark.parametrize( @@ -22,3 +26,14 @@ def test_invalid_extract_github_owner() -> None: "https://example.com", ): run_release.extract_github_owner("https://example.com") + + +def test_check_magic_number() -> None: + db = { + "release": Tag("3.13.0rc1"), + "git_repo": str(Path(__file__).parent / "magicdata"), + } + with pytest.raises( + run_release.ReleaseException, match="Magic numbers in .* don't match" + ): + run_release.check_magic_number(cast(ReleaseShelf, db))