]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.14] gh-139590: Stricter `ruff` rules for `Tools/wasm` (GH-139752) (#139811)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Tue, 14 Oct 2025 07:29:32 +0000 (09:29 +0200)
committerGitHub <noreply@github.com>
Tue, 14 Oct 2025 07:29:32 +0000 (10:29 +0300)
Co-authored-by: sobolevn <mail@sobolevn.me>
Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
.github/workflows/mypy.yml
.pre-commit-config.yaml
Tools/wasm/.ruff.toml
Tools/wasm/emscripten/__main__.py
Tools/wasm/emscripten/wasm_assets.py
Tools/wasm/mypy.ini [deleted file]
Tools/wasm/wasi/__main__.py
Tools/wasm/wasm_build.py

index 498a7d0a84411000b03b8fb65cf4a6533b994c5b..5d5d77f29f6eb1ebbf6518aad1ea439795699689 100644 (file)
@@ -29,7 +29,6 @@ on:
       - "Tools/jit/**"
       - "Tools/peg_generator/**"
       - "Tools/requirements-dev.txt"
-      - "Tools/wasm/**"
   workflow_dispatch:
 
 permissions:
@@ -61,7 +60,6 @@ jobs:
           "Tools/clinic",
           "Tools/jit",
           "Tools/peg_generator",
-          "Tools/wasm",
         ]
     steps:
       - uses: actions/checkout@v4
index 0e00ffb3bd2d66986953238a2ebff68eaa072745..b0311f052798adc58618f4bc351fe3c85c80c0f3 100644 (file)
@@ -26,6 +26,10 @@ repos:
         name: Run Ruff (lint) on Tools/peg_generator/
         args: [--exit-non-zero-on-fix, --config=Tools/peg_generator/.ruff.toml]
         files: ^Tools/peg_generator/
+      - id: ruff-check
+        name: Run Ruff (lint) on Tools/wasm/
+        args: [--exit-non-zero-on-fix, --config=Tools/wasm/.ruff.toml]
+        files: ^Tools/wasm/
       - id: ruff-format
         name: Run Ruff (format) on Doc/
         args: [--check]
index aabcf8dc4f502e0bd7fed972a0ba083fffc700fe..3d8e59fa3f22c41573b7f1cb3d64c5246e968127 100644 (file)
@@ -22,7 +22,4 @@ select = [
 ]
 ignore = [
     "E501",    # Line too long
-    "F541",    # f-string without any placeholders
-    "PYI024",  # Use `typing.NamedTuple` instead of `collections.namedtuple`
-    "PYI025",  # Use `from collections.abc import Set as AbstractSet`
 ]
index fdf3142c0a3b1a245984a803dd9d8f5e75048bcf..c88e9edba6d230f250558b0218bc7ff14aadd3a6 100644 (file)
@@ -3,16 +3,16 @@
 import argparse
 import contextlib
 import functools
+import hashlib
 import os
 import shutil
 import subprocess
 import sys
 import sysconfig
-import hashlib
 import tempfile
-from urllib.request import urlopen
 from pathlib import Path
 from textwrap import dedent
+from urllib.request import urlopen
 
 try:
     from os import process_cpu_count as cpu_count
@@ -33,9 +33,7 @@ HOST_DIR = HOST_BUILD_DIR / "python"
 PREFIX_DIR = CROSS_BUILD_DIR / HOST_TRIPLE / "prefix"
 
 LOCAL_SETUP = CHECKOUT / "Modules" / "Setup.local"
-LOCAL_SETUP_MARKER = "# Generated by Tools/wasm/emscripten.py\n".encode(
-    "utf-8"
-)
+LOCAL_SETUP_MARKER = b"# Generated by Tools/wasm/emscripten.py\n"
 
 
 def updated_env(updates={}):
@@ -432,6 +430,7 @@ def main():
         make_build,
         configure_host,
         make_host,
+        clean,
     ):
         subcommand.add_argument(
             "--quiet",
index 90f318f319a9f16f1f162227edbdc17709ddbb3e..384790872353b25da148cb423fba94a9a5ebccce 100755 (executable)
@@ -15,7 +15,6 @@ import pathlib
 import sys
 import sysconfig
 import zipfile
-from typing import Dict
 
 # source directory
 SRCDIR = pathlib.Path(__file__).parents[3].absolute()
@@ -134,7 +133,7 @@ def create_stdlib_zip(
                 pzf.writepy(entry, filterfunc=filterfunc)
 
 
-def detect_extension_modules(args: argparse.Namespace) -> Dict[str, bool]:
+def detect_extension_modules(args: argparse.Namespace) -> dict[str, bool]:
     modules = {}
 
     # disabled by Modules/Setup.local ?
@@ -149,7 +148,7 @@ def detect_extension_modules(args: argparse.Namespace) -> Dict[str, bool]:
     # disabled by configure?
     with open(args.sysconfig_data) as f:
         data = f.read()
-    loc: Dict[str, Dict[str, str]] = {}
+    loc: dict[str, dict[str, str]] = {}
     exec(data, globals(), loc)
 
     for key, value in loc["build_time_vars"].items():
diff --git a/Tools/wasm/mypy.ini b/Tools/wasm/mypy.ini
deleted file mode 100644 (file)
index 4de0a30..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-[mypy]
-files = Tools/wasm/wasm_*.py
-pretty = True
-show_traceback = True
-
-# Make sure the wasm can be run using Python 3.8:
-python_version = 3.8
-
-# Be strict...
-strict = True
-enable_error_code = truthy-bool,ignore-without-code
index a0658cb351a86f4f02deb9edcc76e5a9b7008609..b2f643ddbfc2135ee45aff7e46569a03a5fbaf94 100644 (file)
@@ -16,7 +16,6 @@ import sys
 import sysconfig
 import tempfile
 
-
 CHECKOUT = pathlib.Path(__file__).parent.parent.parent.parent
 assert (CHECKOUT / "configure").is_file(), (
     "Please update the location of the file"
@@ -28,9 +27,9 @@ BUILD_DIR = CROSS_BUILD_DIR / sysconfig.get_config_var("BUILD_GNU_TYPE")
 
 LOCAL_SETUP = CHECKOUT / "Modules" / "Setup.local"
 LOCAL_SETUP_MARKER = (
-    "# Generated by Tools/wasm/wasi .\n"
-    "# Required to statically build extension modules."
-).encode("utf-8")
+    b"# Generated by Tools/wasm/wasi .\n"
+    b"# Required to statically build extension modules."
+)
 
 WASI_SDK_VERSION = 24
 
@@ -154,8 +153,7 @@ def build_python_is_pydebug():
     test = "import sys, test.support; sys.exit(test.support.Py_DEBUG)"
     result = subprocess.run(
         [build_python_path(), "-c", test],
-        stdout=subprocess.PIPE,
-        stderr=subprocess.PIPE,
+        capture_output=True,
     )
     return bool(result.returncode)
 
index 73875a2205e6a840bd002876e1d98fcfd255885f..3f1bde3853fce7a0ec07a5ac6dd39039f12af78d 100755 (executable)
@@ -23,8 +23,8 @@ changes.
 """
 
 import argparse
-import enum
 import dataclasses
+import enum
 import logging
 import os
 import pathlib
@@ -39,18 +39,12 @@ import tempfile
 import time
 import warnings
 import webbrowser
+from collections.abc import Callable, Iterable
 
 # for Python 3.8
 from typing import (
-    cast,
     Any,
-    Callable,
-    Dict,
-    Iterable,
-    List,
-    Optional,
-    Tuple,
-    Union,
+    cast,
 )
 
 logger = logging.getLogger("wasm_build")
@@ -122,7 +116,7 @@ https://wasmtime.dev/ to install wasmtime.
 
 def parse_emconfig(
     emconfig: pathlib.Path = EM_CONFIG,
-) -> Tuple[pathlib.Path, pathlib.Path]:
+) -> tuple[pathlib.Path, pathlib.Path]:
     """Parse EM_CONFIG file and lookup EMSCRIPTEN_ROOT and NODE_JS.
 
     The ".emscripten" config file is a Python snippet that uses "EM_CONFIG"
@@ -134,7 +128,7 @@ def parse_emconfig(
     with open(emconfig, encoding="utf-8") as f:
         code = f.read()
     # EM_CONFIG file is a Python snippet
-    local: Dict[str, Any] = {}
+    local: dict[str, Any] = {}
     exec(code, globals(), local)
     emscripten_root = pathlib.Path(local["EMSCRIPTEN_ROOT"])
     node_js = pathlib.Path(local["NODE_JS"])
@@ -192,16 +186,16 @@ class Platform:
 
     name: str
     pythonexe: str
-    config_site: Optional[pathlib.PurePath]
-    configure_wrapper: Optional[pathlib.Path]
-    make_wrapper: Optional[pathlib.PurePath]
-    environ: Dict[str, Any]
+    config_site: pathlib.PurePath | None
+    configure_wrapper: pathlib.Path | None
+    make_wrapper: pathlib.PurePath | None
+    environ: dict[str, Any]
     check: Callable[[], None]
     # Used for build_emports().
-    ports: Optional[pathlib.PurePath]
-    cc: Optional[pathlib.PurePath]
+    ports: pathlib.PurePath | None
+    cc: pathlib.PurePath | None
 
-    def getenv(self, profile: "BuildProfile") -> Dict[str, Any]:
+    def getenv(self, profile: "BuildProfile") -> dict[str, Any]:
         return self.environ.copy()
 
 
@@ -264,7 +258,7 @@ def _check_emscripten() -> None:
         # git / upstream / tot-upstream installation
         version = version[:-4]
     version_tuple = cast(
-        Tuple[int, int, int], tuple(int(v) for v in version.split("."))
+        tuple[int, int, int], tuple(int(v) for v in version.split("."))
     )
     if version_tuple < EMSDK_MIN_VERSION:
         raise ConditionError(
@@ -388,7 +382,7 @@ class Host(enum.Enum):
             return []
 
     @property
-    def emport_args(self) -> List[str]:
+    def emport_args(self) -> list[str]:
         """Host-specific port args (Emscripten)."""
         cls = type(self)
         if self is cls.wasm64_emscripten:
@@ -399,7 +393,7 @@ class Host(enum.Enum):
             return []
 
     @property
-    def embuilder_args(self) -> List[str]:
+    def embuilder_args(self) -> list[str]:
         """Host-specific embuilder args (Emscripten)."""
         cls = type(self)
         if self is cls.wasm64_emscripten:
@@ -422,7 +416,7 @@ class EmscriptenTarget(enum.Enum):
         return self in {cls.browser, cls.browser_debug}
 
     @property
-    def emport_args(self) -> List[str]:
+    def emport_args(self) -> list[str]:
         """Target-specific port args."""
         cls = type(self)
         if self in {cls.browser_debug, cls.node_debug}:
@@ -448,9 +442,9 @@ class BuildProfile:
     name: str
     support_level: SupportLevel
     host: Host
-    target: Union[EmscriptenTarget, None] = None
-    dynamic_linking: Union[bool, None] = None
-    pthreads: Union[bool, None] = None
+    target: EmscriptenTarget | None = None
+    dynamic_linking: bool | None = None
+    pthreads: bool | None = None
     default_testopts: str = "-j2"
 
     @property
@@ -474,7 +468,7 @@ class BuildProfile:
         return self.builddir / "Makefile"
 
     @property
-    def configure_cmd(self) -> List[str]:
+    def configure_cmd(self) -> list[str]:
         """Generate configure command"""
         # use relative path, so WASI tests can find lib prefix.
         # pathlib.Path.relative_to() does not work here.
@@ -509,7 +503,7 @@ class BuildProfile:
         return cmd
 
     @property
-    def make_cmd(self) -> List[str]:
+    def make_cmd(self) -> list[str]:
         """Generate make command"""
         cmd = ["make"]
         platform = self.host.platform
@@ -517,7 +511,7 @@ class BuildProfile:
             cmd.insert(0, os.fspath(platform.make_wrapper))
         return cmd
 
-    def getenv(self) -> Dict[str, Any]:
+    def getenv(self) -> dict[str, Any]:
         """Generate environ dict for platform"""
         env = os.environ.copy()
         if hasattr(os, "process_cpu_count"):
@@ -531,7 +525,7 @@ class BuildProfile:
                 env.pop(key, None)
             elif key == "PATH":
                 # list of path items, prefix with extra paths
-                new_path: List[pathlib.PurePath] = []
+                new_path: list[pathlib.PurePath] = []
                 new_path.extend(self.host.get_extra_paths())
                 new_path.extend(value)
                 env[key] = os.pathsep.join(os.fspath(p) for p in new_path)
@@ -549,7 +543,7 @@ class BuildProfile:
         self,
         cmd: Iterable[str],
         args: Iterable[str] = (),
-        cwd: Optional[pathlib.Path] = None,
+        cwd: pathlib.Path | None = None,
     ) -> int:
         cmd = list(cmd)
         cmd.extend(args)
@@ -587,7 +581,7 @@ class BuildProfile:
         self._check_execute()
         return self.run_make("pythoninfo", *args)
 
-    def run_test(self, target: str, testopts: Optional[str] = None) -> int:
+    def run_test(self, target: str, testopts: str | None = None) -> int:
         """Run buildbottests"""
         self._check_execute()
         if testopts is None:
@@ -823,10 +817,8 @@ parser.add_argument(
 )
 
 # Don't list broken and experimental variants in help
-platforms_choices = list(p.name for p in _profiles) + ["cleanall"]
-platforms_help = list(p.name for p in _profiles if p.support_level) + [
-    "cleanall"
-]
+platforms_choices = [p.name for p in _profiles] + ["cleanall"]
+platforms_help = [p.name for p in _profiles if p.support_level] + ["cleanall"]
 parser.add_argument(
     "platform",
     metavar="PLATFORM",
@@ -834,18 +826,18 @@ parser.add_argument(
     choices=platforms_choices,
 )
 
-ops = dict(
-    build="auto build (build 'build' Python, emports, configure, compile)",
-    configure="run ./configure",
-    compile="run 'make all'",
-    pythoninfo="run 'make pythoninfo'",
-    test="run 'make buildbottest TESTOPTS=...' (supports parallel tests)",
-    hostrunnertest="run 'make hostrunnertest TESTOPTS=...'",
-    repl="start interactive REPL / webserver + browser session",
-    clean="run 'make clean'",
-    cleanall="remove all build directories",
-    emports="build Emscripten port with embuilder (only Emscripten)",
-)
+ops = {
+    "build": "auto build (build 'build' Python, emports, configure, compile)",
+    "configure": "run ./configure",
+    "compile": "run 'make all'",
+    "pythoninfo": "run 'make pythoninfo'",
+    "test": "run 'make buildbottest TESTOPTS=...' (supports parallel tests)",
+    "hostrunnertest": "run 'make hostrunnertest TESTOPTS=...'",
+    "repl": "start interactive REPL / webserver + browser session",
+    "clean": "run 'make clean'",
+    "cleanall": "remove all build directories",
+    "emports": "build Emscripten port with embuilder (only Emscripten)",
+}
 ops_help = "\n".join(f"{op:16s} {help}" for op, help in ops.items())
 parser.add_argument(
     "ops",