Core: add python 3.13 support (#5357)

* Core: fix freeze support for py3.13+

Loading Utils now patches multiprocessing.freeze_support()
Utils.freeze_support() is now deprecated

* WebHost: use pony fork on py3.13

* CI: test with py3.13
This commit is contained in:
black-sliver
2025-08-25 17:36:39 +00:00
committed by GitHub
parent d146d90131
commit 1fa342b085
4 changed files with 20 additions and 12 deletions

View File

@@ -41,12 +41,13 @@ jobs:
python: python:
- {version: '3.11.2'} # Change to '3.11' around 2026-06-10 - {version: '3.11.2'} # Change to '3.11' around 2026-06-10
- {version: '3.12'} - {version: '3.12'}
- {version: '3.13'}
include: include:
- python: {version: '3.11'} # old compat - python: {version: '3.11'} # old compat
os: windows-latest os: windows-latest
- python: {version: '3.12'} # current - python: {version: '3.13'} # current
os: windows-latest os: windows-latest
- python: {version: '3.12'} # current - python: {version: '3.13'} # current
os: macos-latest os: macos-latest
steps: steps:
@@ -74,7 +75,7 @@ jobs:
os: os:
- ubuntu-latest - ubuntu-latest
python: python:
- {version: '3.12'} # current - {version: '3.13'} # current
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4

View File

@@ -484,7 +484,7 @@ def main(args: argparse.Namespace | dict | None = None):
if __name__ == '__main__': if __name__ == '__main__':
init_logging('Launcher') init_logging('Launcher')
Utils.freeze_support() multiprocessing.freeze_support()
multiprocessing.set_start_method("spawn") # if launched process uses kivy, fork won't work multiprocessing.set_start_method("spawn") # if launched process uses kivy, fork won't work
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description='Archipelago Launcher', description='Archipelago Launcher',

View File

@@ -940,15 +940,15 @@ class DeprecateDict(dict):
def _extend_freeze_support() -> None: def _extend_freeze_support() -> None:
"""Extend multiprocessing.freeze_support() to also work on Non-Windows for spawn.""" """Extend multiprocessing.freeze_support() to also work on Non-Windows and without setting spawn method first."""
# upstream issue: https://github.com/python/cpython/issues/76327 # original upstream issue: https://github.com/python/cpython/issues/76327
# code based on https://github.com/pyinstaller/pyinstaller/blob/develop/PyInstaller/hooks/rthooks/pyi_rth_multiprocessing.py#L26 # code based on https://github.com/pyinstaller/pyinstaller/blob/develop/PyInstaller/hooks/rthooks/pyi_rth_multiprocessing.py#L26
import multiprocessing import multiprocessing
import multiprocessing.spawn import multiprocessing.spawn
def _freeze_support() -> None: def _freeze_support() -> None:
"""Minimal freeze_support. Only apply this if frozen.""" """Minimal freeze_support. Only apply this if frozen."""
from subprocess import _args_from_interpreter_flags from subprocess import _args_from_interpreter_flags # noqa
# Prevent `spawn` from trying to read `__main__` in from the main script # Prevent `spawn` from trying to read `__main__` in from the main script
multiprocessing.process.ORIGINAL_DIR = None multiprocessing.process.ORIGINAL_DIR = None
@@ -975,17 +975,23 @@ def _extend_freeze_support() -> None:
multiprocessing.spawn.spawn_main(**kwargs) multiprocessing.spawn.spawn_main(**kwargs)
sys.exit() sys.exit()
if not is_windows and is_frozen(): def _noop() -> None:
multiprocessing.freeze_support = multiprocessing.spawn.freeze_support = _freeze_support pass
multiprocessing.freeze_support = multiprocessing.spawn.freeze_support = _freeze_support if is_frozen() else _noop
def freeze_support() -> None: def freeze_support() -> None:
"""This behaves like multiprocessing.freeze_support but also works on Non-Windows.""" """This now only calls multiprocessing.freeze_support since we are patching freeze_support on module load."""
import multiprocessing import multiprocessing
_extend_freeze_support()
deprecate("Use multiprocessing.freeze_support() instead")
multiprocessing.freeze_support() multiprocessing.freeze_support()
_extend_freeze_support()
def visualize_regions(root_region: Region, file_name: str, *, def visualize_regions(root_region: Region, file_name: str, *,
show_entrance_names: bool = False, show_locations: bool = True, show_other_regions: bool = True, show_entrance_names: bool = False, show_locations: bool = True, show_other_regions: bool = True,
linetype_ortho: bool = True, regions_to_highlight: set[Region] | None = None) -> None: linetype_ortho: bool = True, regions_to_highlight: set[Region] | None = None) -> None:

View File

@@ -1,6 +1,7 @@
flask>=3.1.1 flask>=3.1.1
werkzeug>=3.1.3 werkzeug>=3.1.3
pony>=0.7.19 pony>=0.7.19; python_version <= '3.12'
pony @ git+https://github.com/black-sliver/pony@7feb1221953b7fa4a6735466bf21a8b4d35e33ba#0.7.19; python_version >= '3.13'
waitress>=3.0.2 waitress>=3.0.2
Flask-Caching>=2.3.0 Flask-Caching>=2.3.0
Flask-Compress>=1.17 Flask-Compress>=1.17