diff --git a/add_to_pydotorg.py b/add_to_pydotorg.py index a10be889..e4c5ec5d 100755 --- a/add_to_pydotorg.py +++ b/add_to_pydotorg.py @@ -128,6 +128,33 @@ def get_file_descriptions( rx(r"-embed-arm64\.zip$"), ("Windows embeddable package (ARM64)", "windows", False, ""), ), + ( + rx(r"\dt-amd64\.zip$"), + ( + "Windows free-threaded 64-bit embeddable package", + "windows", + False, + "", + ), + ), + ( + rx(r"\dt-arm64\.zip$"), + ( + "Windows free-threaded ARM64 embeddable package", + "windows", + False, + "", + ), + ), + ( + rx(r"\dt-win32\.zip$"), + ( + "Windows free-threaded 32-bit embeddable package", + "windows", + False, + "", + ), + ), ( rx(r"-arm64\.exe$"), ("Windows installer (ARM64)", "windows", False, "Experimental"), @@ -262,6 +289,7 @@ def list_files( ) -> Generator[tuple[str, str, str, bool, str], None, None]: """List all of the release's download files.""" reldir = base_version(release) + version_prefixes = (release + "-", release + ".", release + "t-") for rfile in sorted(os.listdir(path.join(ftp_root, reldir))): if not path.isfile(path.join(ftp_root, reldir, rfile)): continue @@ -275,7 +303,7 @@ def list_files( print(f" File {reldir}/{rfile} has wrong prefix") continue - if not rest.startswith((release + "-", release + ".")): + if not rest.startswith(version_prefixes): print(f" File {reldir}/{rfile} has a different version") continue diff --git a/tests/test_add_to_pydotorg.py b/tests/test_add_to_pydotorg.py index 83d780fb..7ce43c7f 100644 --- a/tests/test_add_to_pydotorg.py +++ b/tests/test_add_to_pydotorg.py @@ -213,6 +213,27 @@ def test_list_files(fs: FakeFilesystem) -> None: "", ), ("python-3.14.0b3.exe", "Windows installer (32-bit)", "windows", False, ""), + ( + "python-3.14.0b3t-amd64.zip", + "Windows free-threaded 64-bit embeddable package", + "windows", + False, + "", + ), + ( + "python-3.14.0b3t-arm64.zip", + "Windows free-threaded ARM64 embeddable package", + "windows", + False, + "", + ), + ( + "python-3.14.0b3t-win32.zip", + "Windows free-threaded 32-bit embeddable package", + "windows", + False, + "", + ), ( "windows-3.14.0b3.json", "Windows release manifest", @@ -221,3 +242,67 @@ def test_list_files(fs: FakeFilesystem) -> None: "Install with 'py install 3.14'", ), ] + + +def test_list_files_accepts_final_free_threaded_windows_names( + fs: FakeFilesystem, +) -> None: + fake_ftp_root = "/fake_ftp_root" + release_dir = Path(fake_ftp_root) / "3.14.0" + fs.create_dir(release_dir) + fs.create_file(release_dir / "python-3.14.0t-amd64.zip") + + files = list(add_to_pydotorg.list_files(fake_ftp_root, "3.14.0")) + + assert files == [ + ( + "python-3.14.0t-amd64.zip", + "Windows free-threaded 64-bit embeddable package", + "windows", + False, + "", + ) + ] + + +def test_free_threaded_windows_zip_file_dicts_have_unique_metadata( + fs: FakeFilesystem, +) -> None: + fake_ftp_root = "/fake_ftp_root" + release = "3.14.0b3" + release_dir = Path(fake_ftp_root) / "3.14.0" + fs.create_dir(release_dir) + files = [ + "python-3.14.0b3t-amd64.zip", + "python-3.14.0b3t-arm64.zip", + "python-3.14.0b3t-win32.zip", + ] + for rfile in files: + fs.create_file(release_dir / rfile) + + file_dicts = [] + for ( + rfile, + name, + _os_slug, + download_button, + description, + ) in add_to_pydotorg.list_files( + fake_ftp_root, + release, + ): + file_dicts.append( + add_to_pydotorg.build_file_dict( + fake_ftp_root, + release, + rfile, + 1, + name, + 2, + download_button, + description, + ) + ) + + assert len({file_dict["slug"] for file_dict in file_dicts}) == len(files) + assert {file_dict["download_button"] for file_dict in file_dicts} == {False}