mirror of
https://github.com/python/cpython.git
synced 2025-11-24 04:17:38 +00:00
[3.14] gh-139590: Stricter ruff rules for Tools/wasm (GH-139752) (#139811)
Co-authored-by: sobolevn <mail@sobolevn.me> Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
This commit is contained in:
parent
7a13953bc3
commit
5848d80536
8 changed files with 53 additions and 77 deletions
2
.github/workflows/mypy.yml
vendored
2
.github/workflows/mypy.yml
vendored
|
|
@ -29,7 +29,6 @@ on:
|
||||||
- "Tools/jit/**"
|
- "Tools/jit/**"
|
||||||
- "Tools/peg_generator/**"
|
- "Tools/peg_generator/**"
|
||||||
- "Tools/requirements-dev.txt"
|
- "Tools/requirements-dev.txt"
|
||||||
- "Tools/wasm/**"
|
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
|
|
@ -61,7 +60,6 @@ jobs:
|
||||||
"Tools/clinic",
|
"Tools/clinic",
|
||||||
"Tools/jit",
|
"Tools/jit",
|
||||||
"Tools/peg_generator",
|
"Tools/peg_generator",
|
||||||
"Tools/wasm",
|
|
||||||
]
|
]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,10 @@ repos:
|
||||||
name: Run Ruff (lint) on Tools/peg_generator/
|
name: Run Ruff (lint) on Tools/peg_generator/
|
||||||
args: [--exit-non-zero-on-fix, --config=Tools/peg_generator/.ruff.toml]
|
args: [--exit-non-zero-on-fix, --config=Tools/peg_generator/.ruff.toml]
|
||||||
files: ^Tools/peg_generator/
|
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
|
- id: ruff-format
|
||||||
name: Run Ruff (format) on Doc/
|
name: Run Ruff (format) on Doc/
|
||||||
args: [--check]
|
args: [--check]
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,4 @@ select = [
|
||||||
]
|
]
|
||||||
ignore = [
|
ignore = [
|
||||||
"E501", # Line too long
|
"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`
|
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -3,16 +3,16 @@
|
||||||
import argparse
|
import argparse
|
||||||
import contextlib
|
import contextlib
|
||||||
import functools
|
import functools
|
||||||
|
import hashlib
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import sysconfig
|
import sysconfig
|
||||||
import hashlib
|
|
||||||
import tempfile
|
import tempfile
|
||||||
from urllib.request import urlopen
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from textwrap import dedent
|
from textwrap import dedent
|
||||||
|
from urllib.request import urlopen
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from os import process_cpu_count as cpu_count
|
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"
|
PREFIX_DIR = CROSS_BUILD_DIR / HOST_TRIPLE / "prefix"
|
||||||
|
|
||||||
LOCAL_SETUP = CHECKOUT / "Modules" / "Setup.local"
|
LOCAL_SETUP = CHECKOUT / "Modules" / "Setup.local"
|
||||||
LOCAL_SETUP_MARKER = "# Generated by Tools/wasm/emscripten.py\n".encode(
|
LOCAL_SETUP_MARKER = b"# Generated by Tools/wasm/emscripten.py\n"
|
||||||
"utf-8"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def updated_env(updates={}):
|
def updated_env(updates={}):
|
||||||
|
|
@ -432,6 +430,7 @@ def main():
|
||||||
make_build,
|
make_build,
|
||||||
configure_host,
|
configure_host,
|
||||||
make_host,
|
make_host,
|
||||||
|
clean,
|
||||||
):
|
):
|
||||||
subcommand.add_argument(
|
subcommand.add_argument(
|
||||||
"--quiet",
|
"--quiet",
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ import pathlib
|
||||||
import sys
|
import sys
|
||||||
import sysconfig
|
import sysconfig
|
||||||
import zipfile
|
import zipfile
|
||||||
from typing import Dict
|
|
||||||
|
|
||||||
# source directory
|
# source directory
|
||||||
SRCDIR = pathlib.Path(__file__).parents[3].absolute()
|
SRCDIR = pathlib.Path(__file__).parents[3].absolute()
|
||||||
|
|
@ -134,7 +133,7 @@ def create_stdlib_zip(
|
||||||
pzf.writepy(entry, filterfunc=filterfunc)
|
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 = {}
|
modules = {}
|
||||||
|
|
||||||
# disabled by Modules/Setup.local ?
|
# disabled by Modules/Setup.local ?
|
||||||
|
|
@ -149,7 +148,7 @@ def detect_extension_modules(args: argparse.Namespace) -> Dict[str, bool]:
|
||||||
# disabled by configure?
|
# disabled by configure?
|
||||||
with open(args.sysconfig_data) as f:
|
with open(args.sysconfig_data) as f:
|
||||||
data = f.read()
|
data = f.read()
|
||||||
loc: Dict[str, Dict[str, str]] = {}
|
loc: dict[str, dict[str, str]] = {}
|
||||||
exec(data, globals(), loc)
|
exec(data, globals(), loc)
|
||||||
|
|
||||||
for key, value in loc["build_time_vars"].items():
|
for key, value in loc["build_time_vars"].items():
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -16,7 +16,6 @@ import sys
|
||||||
import sysconfig
|
import sysconfig
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
|
|
||||||
CHECKOUT = pathlib.Path(__file__).parent.parent.parent.parent
|
CHECKOUT = pathlib.Path(__file__).parent.parent.parent.parent
|
||||||
assert (CHECKOUT / "configure").is_file(), (
|
assert (CHECKOUT / "configure").is_file(), (
|
||||||
"Please update the location of the 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 = CHECKOUT / "Modules" / "Setup.local"
|
||||||
LOCAL_SETUP_MARKER = (
|
LOCAL_SETUP_MARKER = (
|
||||||
"# Generated by Tools/wasm/wasi .\n"
|
b"# Generated by Tools/wasm/wasi .\n"
|
||||||
"# Required to statically build extension modules."
|
b"# Required to statically build extension modules."
|
||||||
).encode("utf-8")
|
)
|
||||||
|
|
||||||
WASI_SDK_VERSION = 24
|
WASI_SDK_VERSION = 24
|
||||||
|
|
||||||
|
|
@ -154,8 +153,7 @@ def build_python_is_pydebug():
|
||||||
test = "import sys, test.support; sys.exit(test.support.Py_DEBUG)"
|
test = "import sys, test.support; sys.exit(test.support.Py_DEBUG)"
|
||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
[build_python_path(), "-c", test],
|
[build_python_path(), "-c", test],
|
||||||
stdout=subprocess.PIPE,
|
capture_output=True,
|
||||||
stderr=subprocess.PIPE,
|
|
||||||
)
|
)
|
||||||
return bool(result.returncode)
|
return bool(result.returncode)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@ changes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import enum
|
|
||||||
import dataclasses
|
import dataclasses
|
||||||
|
import enum
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import pathlib
|
import pathlib
|
||||||
|
|
@ -39,18 +39,12 @@ import tempfile
|
||||||
import time
|
import time
|
||||||
import warnings
|
import warnings
|
||||||
import webbrowser
|
import webbrowser
|
||||||
|
from collections.abc import Callable, Iterable
|
||||||
|
|
||||||
# for Python 3.8
|
# for Python 3.8
|
||||||
from typing import (
|
from typing import (
|
||||||
cast,
|
|
||||||
Any,
|
Any,
|
||||||
Callable,
|
cast,
|
||||||
Dict,
|
|
||||||
Iterable,
|
|
||||||
List,
|
|
||||||
Optional,
|
|
||||||
Tuple,
|
|
||||||
Union,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
logger = logging.getLogger("wasm_build")
|
logger = logging.getLogger("wasm_build")
|
||||||
|
|
@ -122,7 +116,7 @@ https://wasmtime.dev/ to install wasmtime.
|
||||||
|
|
||||||
def parse_emconfig(
|
def parse_emconfig(
|
||||||
emconfig: pathlib.Path = EM_CONFIG,
|
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.
|
"""Parse EM_CONFIG file and lookup EMSCRIPTEN_ROOT and NODE_JS.
|
||||||
|
|
||||||
The ".emscripten" config file is a Python snippet that uses "EM_CONFIG"
|
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:
|
with open(emconfig, encoding="utf-8") as f:
|
||||||
code = f.read()
|
code = f.read()
|
||||||
# EM_CONFIG file is a Python snippet
|
# EM_CONFIG file is a Python snippet
|
||||||
local: Dict[str, Any] = {}
|
local: dict[str, Any] = {}
|
||||||
exec(code, globals(), local)
|
exec(code, globals(), local)
|
||||||
emscripten_root = pathlib.Path(local["EMSCRIPTEN_ROOT"])
|
emscripten_root = pathlib.Path(local["EMSCRIPTEN_ROOT"])
|
||||||
node_js = pathlib.Path(local["NODE_JS"])
|
node_js = pathlib.Path(local["NODE_JS"])
|
||||||
|
|
@ -192,16 +186,16 @@ class Platform:
|
||||||
|
|
||||||
name: str
|
name: str
|
||||||
pythonexe: str
|
pythonexe: str
|
||||||
config_site: Optional[pathlib.PurePath]
|
config_site: pathlib.PurePath | None
|
||||||
configure_wrapper: Optional[pathlib.Path]
|
configure_wrapper: pathlib.Path | None
|
||||||
make_wrapper: Optional[pathlib.PurePath]
|
make_wrapper: pathlib.PurePath | None
|
||||||
environ: Dict[str, Any]
|
environ: dict[str, Any]
|
||||||
check: Callable[[], None]
|
check: Callable[[], None]
|
||||||
# Used for build_emports().
|
# Used for build_emports().
|
||||||
ports: Optional[pathlib.PurePath]
|
ports: pathlib.PurePath | None
|
||||||
cc: Optional[pathlib.PurePath]
|
cc: pathlib.PurePath | None
|
||||||
|
|
||||||
def getenv(self, profile: "BuildProfile") -> Dict[str, Any]:
|
def getenv(self, profile: "BuildProfile") -> dict[str, Any]:
|
||||||
return self.environ.copy()
|
return self.environ.copy()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -264,7 +258,7 @@ def _check_emscripten() -> None:
|
||||||
# git / upstream / tot-upstream installation
|
# git / upstream / tot-upstream installation
|
||||||
version = version[:-4]
|
version = version[:-4]
|
||||||
version_tuple = cast(
|
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:
|
if version_tuple < EMSDK_MIN_VERSION:
|
||||||
raise ConditionError(
|
raise ConditionError(
|
||||||
|
|
@ -388,7 +382,7 @@ class Host(enum.Enum):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def emport_args(self) -> List[str]:
|
def emport_args(self) -> list[str]:
|
||||||
"""Host-specific port args (Emscripten)."""
|
"""Host-specific port args (Emscripten)."""
|
||||||
cls = type(self)
|
cls = type(self)
|
||||||
if self is cls.wasm64_emscripten:
|
if self is cls.wasm64_emscripten:
|
||||||
|
|
@ -399,7 +393,7 @@ class Host(enum.Enum):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def embuilder_args(self) -> List[str]:
|
def embuilder_args(self) -> list[str]:
|
||||||
"""Host-specific embuilder args (Emscripten)."""
|
"""Host-specific embuilder args (Emscripten)."""
|
||||||
cls = type(self)
|
cls = type(self)
|
||||||
if self is cls.wasm64_emscripten:
|
if self is cls.wasm64_emscripten:
|
||||||
|
|
@ -422,7 +416,7 @@ class EmscriptenTarget(enum.Enum):
|
||||||
return self in {cls.browser, cls.browser_debug}
|
return self in {cls.browser, cls.browser_debug}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def emport_args(self) -> List[str]:
|
def emport_args(self) -> list[str]:
|
||||||
"""Target-specific port args."""
|
"""Target-specific port args."""
|
||||||
cls = type(self)
|
cls = type(self)
|
||||||
if self in {cls.browser_debug, cls.node_debug}:
|
if self in {cls.browser_debug, cls.node_debug}:
|
||||||
|
|
@ -448,9 +442,9 @@ class BuildProfile:
|
||||||
name: str
|
name: str
|
||||||
support_level: SupportLevel
|
support_level: SupportLevel
|
||||||
host: Host
|
host: Host
|
||||||
target: Union[EmscriptenTarget, None] = None
|
target: EmscriptenTarget | None = None
|
||||||
dynamic_linking: Union[bool, None] = None
|
dynamic_linking: bool | None = None
|
||||||
pthreads: Union[bool, None] = None
|
pthreads: bool | None = None
|
||||||
default_testopts: str = "-j2"
|
default_testopts: str = "-j2"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
@ -474,7 +468,7 @@ class BuildProfile:
|
||||||
return self.builddir / "Makefile"
|
return self.builddir / "Makefile"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def configure_cmd(self) -> List[str]:
|
def configure_cmd(self) -> list[str]:
|
||||||
"""Generate configure command"""
|
"""Generate configure command"""
|
||||||
# use relative path, so WASI tests can find lib prefix.
|
# use relative path, so WASI tests can find lib prefix.
|
||||||
# pathlib.Path.relative_to() does not work here.
|
# pathlib.Path.relative_to() does not work here.
|
||||||
|
|
@ -509,7 +503,7 @@ class BuildProfile:
|
||||||
return cmd
|
return cmd
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def make_cmd(self) -> List[str]:
|
def make_cmd(self) -> list[str]:
|
||||||
"""Generate make command"""
|
"""Generate make command"""
|
||||||
cmd = ["make"]
|
cmd = ["make"]
|
||||||
platform = self.host.platform
|
platform = self.host.platform
|
||||||
|
|
@ -517,7 +511,7 @@ class BuildProfile:
|
||||||
cmd.insert(0, os.fspath(platform.make_wrapper))
|
cmd.insert(0, os.fspath(platform.make_wrapper))
|
||||||
return cmd
|
return cmd
|
||||||
|
|
||||||
def getenv(self) -> Dict[str, Any]:
|
def getenv(self) -> dict[str, Any]:
|
||||||
"""Generate environ dict for platform"""
|
"""Generate environ dict for platform"""
|
||||||
env = os.environ.copy()
|
env = os.environ.copy()
|
||||||
if hasattr(os, "process_cpu_count"):
|
if hasattr(os, "process_cpu_count"):
|
||||||
|
|
@ -531,7 +525,7 @@ class BuildProfile:
|
||||||
env.pop(key, None)
|
env.pop(key, None)
|
||||||
elif key == "PATH":
|
elif key == "PATH":
|
||||||
# list of path items, prefix with extra paths
|
# 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(self.host.get_extra_paths())
|
||||||
new_path.extend(value)
|
new_path.extend(value)
|
||||||
env[key] = os.pathsep.join(os.fspath(p) for p in new_path)
|
env[key] = os.pathsep.join(os.fspath(p) for p in new_path)
|
||||||
|
|
@ -549,7 +543,7 @@ class BuildProfile:
|
||||||
self,
|
self,
|
||||||
cmd: Iterable[str],
|
cmd: Iterable[str],
|
||||||
args: Iterable[str] = (),
|
args: Iterable[str] = (),
|
||||||
cwd: Optional[pathlib.Path] = None,
|
cwd: pathlib.Path | None = None,
|
||||||
) -> int:
|
) -> int:
|
||||||
cmd = list(cmd)
|
cmd = list(cmd)
|
||||||
cmd.extend(args)
|
cmd.extend(args)
|
||||||
|
|
@ -587,7 +581,7 @@ class BuildProfile:
|
||||||
self._check_execute()
|
self._check_execute()
|
||||||
return self.run_make("pythoninfo", *args)
|
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"""
|
"""Run buildbottests"""
|
||||||
self._check_execute()
|
self._check_execute()
|
||||||
if testopts is None:
|
if testopts is None:
|
||||||
|
|
@ -823,10 +817,8 @@ parser.add_argument(
|
||||||
)
|
)
|
||||||
|
|
||||||
# Don't list broken and experimental variants in help
|
# Don't list broken and experimental variants in help
|
||||||
platforms_choices = list(p.name for p in _profiles) + ["cleanall"]
|
platforms_choices = [p.name for p in _profiles] + ["cleanall"]
|
||||||
platforms_help = list(p.name for p in _profiles if p.support_level) + [
|
platforms_help = [p.name for p in _profiles if p.support_level] + ["cleanall"]
|
||||||
"cleanall"
|
|
||||||
]
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"platform",
|
"platform",
|
||||||
metavar="PLATFORM",
|
metavar="PLATFORM",
|
||||||
|
|
@ -834,18 +826,18 @@ parser.add_argument(
|
||||||
choices=platforms_choices,
|
choices=platforms_choices,
|
||||||
)
|
)
|
||||||
|
|
||||||
ops = dict(
|
ops = {
|
||||||
build="auto build (build 'build' Python, emports, configure, compile)",
|
"build": "auto build (build 'build' Python, emports, configure, compile)",
|
||||||
configure="run ./configure",
|
"configure": "run ./configure",
|
||||||
compile="run 'make all'",
|
"compile": "run 'make all'",
|
||||||
pythoninfo="run 'make pythoninfo'",
|
"pythoninfo": "run 'make pythoninfo'",
|
||||||
test="run 'make buildbottest TESTOPTS=...' (supports parallel tests)",
|
"test": "run 'make buildbottest TESTOPTS=...' (supports parallel tests)",
|
||||||
hostrunnertest="run 'make hostrunnertest TESTOPTS=...'",
|
"hostrunnertest": "run 'make hostrunnertest TESTOPTS=...'",
|
||||||
repl="start interactive REPL / webserver + browser session",
|
"repl": "start interactive REPL / webserver + browser session",
|
||||||
clean="run 'make clean'",
|
"clean": "run 'make clean'",
|
||||||
cleanall="remove all build directories",
|
"cleanall": "remove all build directories",
|
||||||
emports="build Emscripten port with embuilder (only Emscripten)",
|
"emports": "build Emscripten port with embuilder (only Emscripten)",
|
||||||
)
|
}
|
||||||
ops_help = "\n".join(f"{op:16s} {help}" for op, help in ops.items())
|
ops_help = "\n".join(f"{op:16s} {help}" for op, help in ops.items())
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"ops",
|
"ops",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue