mirror of
https://github.com/python/cpython.git
synced 2025-12-07 13:50:06 +00:00
gh-141691: Apply ruff rules to Apple folder. (#141694)
Add ruff configuration to run over the Apple build tooling and testbed script.
This commit is contained in:
parent
4cfa695c95
commit
17636ba48c
4 changed files with 126 additions and 91 deletions
|
|
@ -2,6 +2,10 @@ repos:
|
|||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.13.2
|
||||
hooks:
|
||||
- id: ruff-check
|
||||
name: Run Ruff (lint) on Apple/
|
||||
args: [--exit-non-zero-on-fix, --config=Apple/.ruff.toml]
|
||||
files: ^Apple/
|
||||
- id: ruff-check
|
||||
name: Run Ruff (lint) on Doc/
|
||||
args: [--exit-non-zero-on-fix]
|
||||
|
|
@ -30,6 +34,10 @@ repos:
|
|||
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 Apple/
|
||||
args: [--exit-non-zero-on-fix, --config=Apple/.ruff.toml]
|
||||
files: ^Apple
|
||||
- id: ruff-format
|
||||
name: Run Ruff (format) on Doc/
|
||||
args: [--check]
|
||||
|
|
|
|||
22
Apple/.ruff.toml
Normal file
22
Apple/.ruff.toml
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
extend = "../.ruff.toml" # Inherit the project-wide settings
|
||||
|
||||
[format]
|
||||
preview = true
|
||||
docstring-code-format = true
|
||||
|
||||
[lint]
|
||||
select = [
|
||||
"C4", # flake8-comprehensions
|
||||
"E", # pycodestyle
|
||||
"F", # pyflakes
|
||||
"I", # isort
|
||||
"ISC", # flake8-implicit-str-concat
|
||||
"LOG", # flake8-logging
|
||||
"PGH", # pygrep-hooks
|
||||
"PT", # flake8-pytest-style
|
||||
"PYI", # flake8-pyi
|
||||
"RUF100", # Ban unused `# noqa` comments
|
||||
"UP", # pyupgrade
|
||||
"W", # pycodestyle
|
||||
"YTT", # flake8-2020
|
||||
]
|
||||
|
|
@ -46,13 +46,12 @@
|
|||
import sys
|
||||
import sysconfig
|
||||
import time
|
||||
from collections.abc import Sequence
|
||||
from collections.abc import Callable, Sequence
|
||||
from contextlib import contextmanager
|
||||
from datetime import datetime, timezone
|
||||
from os.path import basename, relpath
|
||||
from pathlib import Path
|
||||
from subprocess import CalledProcessError
|
||||
from typing import Callable
|
||||
|
||||
EnvironmentT = dict[str, str]
|
||||
ArgsT = Sequence[str | Path]
|
||||
|
|
@ -140,8 +139,7 @@ def print_env(env: EnvironmentT) -> None:
|
|||
def apple_env(host: str) -> EnvironmentT:
|
||||
"""Construct an Apple development environment for the given host."""
|
||||
env = {
|
||||
"PATH": ":".join(
|
||||
[
|
||||
"PATH": ":".join([
|
||||
str(PYTHON_DIR / "Apple/iOS/Resources/bin"),
|
||||
str(subdir(host) / "prefix"),
|
||||
"/usr/bin",
|
||||
|
|
@ -149,8 +147,7 @@ def apple_env(host: str) -> EnvironmentT:
|
|||
"/usr/sbin",
|
||||
"/sbin",
|
||||
"/Library/Apple/usr/bin",
|
||||
]
|
||||
),
|
||||
]),
|
||||
}
|
||||
|
||||
return env
|
||||
|
|
@ -196,14 +193,10 @@ def clean(context: argparse.Namespace, target: str = "all") -> None:
|
|||
paths.append(target)
|
||||
|
||||
if target in {"all", "hosts", "test"}:
|
||||
paths.extend(
|
||||
[
|
||||
paths.extend([
|
||||
path.name
|
||||
for path in CROSS_BUILD_DIR.glob(
|
||||
f"{context.platform}-testbed.*"
|
||||
)
|
||||
]
|
||||
)
|
||||
for path in CROSS_BUILD_DIR.glob(f"{context.platform}-testbed.*")
|
||||
])
|
||||
|
||||
for path in paths:
|
||||
delete_path(path)
|
||||
|
|
@ -352,8 +345,7 @@ def download(url: str, target_dir: Path) -> Path:
|
|||
|
||||
out_path = target_path / basename(url)
|
||||
if not Path(out_path).is_file():
|
||||
run(
|
||||
[
|
||||
run([
|
||||
"curl",
|
||||
"-Lf",
|
||||
"--retry",
|
||||
|
|
@ -362,8 +354,7 @@ def download(url: str, target_dir: Path) -> Path:
|
|||
"-o",
|
||||
out_path,
|
||||
url,
|
||||
]
|
||||
)
|
||||
])
|
||||
else:
|
||||
print(f"Using cached version of {basename(url)}")
|
||||
return out_path
|
||||
|
|
@ -468,8 +459,7 @@ def package_version(prefix_path: Path) -> str:
|
|||
|
||||
|
||||
def lib_platform_files(dirname, names):
|
||||
"""A file filter that ignores platform-specific files in the lib directory.
|
||||
"""
|
||||
"""A file filter that ignores platform-specific files in lib."""
|
||||
path = Path(dirname)
|
||||
if (
|
||||
path.parts[-3] == "lib"
|
||||
|
|
@ -478,7 +468,7 @@ def lib_platform_files(dirname, names):
|
|||
):
|
||||
return names
|
||||
elif path.parts[-2] == "lib" and path.parts[-1].startswith("python"):
|
||||
ignored_names = set(
|
||||
ignored_names = {
|
||||
name
|
||||
for name in names
|
||||
if (
|
||||
|
|
@ -486,7 +476,7 @@ def lib_platform_files(dirname, names):
|
|||
or name.startswith("_sysconfig_vars_")
|
||||
or name == "build-details.json"
|
||||
)
|
||||
)
|
||||
}
|
||||
else:
|
||||
ignored_names = set()
|
||||
|
||||
|
|
@ -499,7 +489,9 @@ def lib_non_platform_files(dirname, names):
|
|||
"""
|
||||
path = Path(dirname)
|
||||
if path.parts[-2] == "lib" and path.parts[-1].startswith("python"):
|
||||
return set(names) - lib_platform_files(dirname, names) - {"lib-dynload"}
|
||||
return (
|
||||
set(names) - lib_platform_files(dirname, names) - {"lib-dynload"}
|
||||
)
|
||||
else:
|
||||
return set()
|
||||
|
||||
|
|
@ -514,7 +506,8 @@ def create_xcframework(platform: str) -> str:
|
|||
package_path.mkdir()
|
||||
except FileExistsError:
|
||||
raise RuntimeError(
|
||||
f"{platform} XCframework already exists; do you need to run with --clean?"
|
||||
f"{platform} XCframework already exists; do you need to run "
|
||||
"with --clean?"
|
||||
) from None
|
||||
|
||||
frameworks = []
|
||||
|
|
@ -607,7 +600,7 @@ def create_xcframework(platform: str) -> str:
|
|||
print(f" - {slice_name} binaries")
|
||||
shutil.copytree(first_path / "bin", slice_path / "bin")
|
||||
|
||||
# Copy the include path (this will be a symlink to the framework headers)
|
||||
# Copy the include path (a symlink to the framework headers)
|
||||
print(f" - {slice_name} include files")
|
||||
shutil.copytree(
|
||||
first_path / "include",
|
||||
|
|
@ -659,7 +652,8 @@ def create_xcframework(platform: str) -> str:
|
|||
# statically link those libraries into a Framework, you become
|
||||
# responsible for providing a privacy manifest for that framework.
|
||||
xcprivacy_file = {
|
||||
"OpenSSL": subdir(host_triple) / "prefix/share/OpenSSL.xcprivacy"
|
||||
"OpenSSL": subdir(host_triple)
|
||||
/ "prefix/share/OpenSSL.xcprivacy"
|
||||
}
|
||||
print(f" - {multiarch} xcprivacy files")
|
||||
for module, lib in [
|
||||
|
|
@ -669,7 +663,8 @@ def create_xcframework(platform: str) -> str:
|
|||
shutil.copy(
|
||||
xcprivacy_file[lib],
|
||||
slice_path
|
||||
/ f"lib-{arch}/python{version_tag}/lib-dynload/{module}.xcprivacy",
|
||||
/ f"lib-{arch}/python{version_tag}"
|
||||
/ f"lib-dynload/{module}.xcprivacy",
|
||||
)
|
||||
|
||||
print(" - build tools")
|
||||
|
|
@ -692,8 +687,7 @@ def package(context: argparse.Namespace) -> None:
|
|||
|
||||
# Clone testbed
|
||||
print()
|
||||
run(
|
||||
[
|
||||
run([
|
||||
sys.executable,
|
||||
"Apple/testbed",
|
||||
"clone",
|
||||
|
|
@ -702,8 +696,7 @@ def package(context: argparse.Namespace) -> None:
|
|||
"--framework",
|
||||
CROSS_BUILD_DIR / context.platform / "Python.xcframework",
|
||||
CROSS_BUILD_DIR / context.platform / "testbed",
|
||||
]
|
||||
)
|
||||
])
|
||||
|
||||
# Build the final archive
|
||||
archive_name = (
|
||||
|
|
@ -757,7 +750,7 @@ def build(context: argparse.Namespace, host: str | None = None) -> None:
|
|||
package(context)
|
||||
|
||||
|
||||
def test(context: argparse.Namespace, host: str | None = None) -> None:
|
||||
def test(context: argparse.Namespace, host: str | None = None) -> None: # noqa: PT028
|
||||
"""The implementation of the "test" command."""
|
||||
if host is None:
|
||||
host = context.host
|
||||
|
|
@ -795,8 +788,7 @@ def test(context: argparse.Namespace, host: str | None = None) -> None:
|
|||
/ f"Frameworks/{apple_multiarch(host)}"
|
||||
)
|
||||
|
||||
run(
|
||||
[
|
||||
run([
|
||||
sys.executable,
|
||||
"Apple/testbed",
|
||||
"clone",
|
||||
|
|
@ -805,8 +797,7 @@ def test(context: argparse.Namespace, host: str | None = None) -> None:
|
|||
"--framework",
|
||||
framework_path,
|
||||
testbed_dir,
|
||||
]
|
||||
)
|
||||
])
|
||||
|
||||
run(
|
||||
[
|
||||
|
|
@ -840,7 +831,7 @@ def apple_sim_host(platform_name: str) -> str:
|
|||
"""Determine the native simulator target for this platform."""
|
||||
for _, slice_parts in HOSTS[platform_name].items():
|
||||
for host_triple in slice_parts:
|
||||
parts = host_triple.split('-')
|
||||
parts = host_triple.split("-")
|
||||
if parts[0] == platform.machine() and parts[-1] == "simulator":
|
||||
return host_triple
|
||||
|
||||
|
|
@ -968,20 +959,29 @@ def parse_args() -> argparse.Namespace:
|
|||
cmd.add_argument(
|
||||
"--simulator",
|
||||
help=(
|
||||
"The name of the simulator to use (eg: 'iPhone 16e'). Defaults to "
|
||||
"the most recently released 'entry level' iPhone device. Device "
|
||||
"architecture and OS version can also be specified; e.g., "
|
||||
"`--simulator 'iPhone 16 Pro,arch=arm64,OS=26.0'` would run on "
|
||||
"an ARM64 iPhone 16 Pro simulator running iOS 26.0."
|
||||
"The name of the simulator to use (eg: 'iPhone 16e'). "
|
||||
"Defaults to the most recently released 'entry level' "
|
||||
"iPhone device. Device architecture and OS version can also "
|
||||
"be specified; e.g., "
|
||||
"`--simulator 'iPhone 16 Pro,arch=arm64,OS=26.0'` would "
|
||||
"run on an ARM64 iPhone 16 Pro simulator running iOS 26.0."
|
||||
),
|
||||
)
|
||||
group = cmd.add_mutually_exclusive_group()
|
||||
group.add_argument(
|
||||
"--fast-ci", action="store_const", dest="ci_mode", const="fast",
|
||||
help="Add test arguments for GitHub Actions")
|
||||
"--fast-ci",
|
||||
action="store_const",
|
||||
dest="ci_mode",
|
||||
const="fast",
|
||||
help="Add test arguments for GitHub Actions",
|
||||
)
|
||||
group.add_argument(
|
||||
"--slow-ci", action="store_const", dest="ci_mode", const="slow",
|
||||
help="Add test arguments for buildbots")
|
||||
"--slow-ci",
|
||||
action="store_const",
|
||||
dest="ci_mode",
|
||||
const="slow",
|
||||
help="Add test arguments for buildbots",
|
||||
)
|
||||
|
||||
for subcommand in [configure_build, configure_host, build, ci]:
|
||||
subcommand.add_argument(
|
||||
|
|
|
|||
|
|
@ -32,15 +32,15 @@ def select_simulator_device(platform):
|
|||
json_data = json.loads(raw_json)
|
||||
|
||||
if platform == "iOS":
|
||||
# Any iOS device will do; we'll look for "SE" devices - but the name isn't
|
||||
# consistent over time. Older Xcode versions will use "iPhone SE (Nth
|
||||
# generation)"; As of 2025, they've started using "iPhone 16e".
|
||||
# Any iOS device will do; we'll look for "SE" devices - but the name
|
||||
# isn't consistent over time. Older Xcode versions will use "iPhone SE
|
||||
# (Nth generation)"; As of 2025, they've started using "iPhone 16e".
|
||||
#
|
||||
# When Xcode is updated after a new release, new devices will be available
|
||||
# and old ones will be dropped from the set available on the latest iOS
|
||||
# version. Select the one with the highest minimum runtime version - this
|
||||
# is an indicator of the "newest" released device, which should always be
|
||||
# supported on the "most recent" iOS version.
|
||||
# When Xcode is updated after a new release, new devices will be
|
||||
# available and old ones will be dropped from the set available on the
|
||||
# latest iOS version. Select the one with the highest minimum runtime
|
||||
# version - this is an indicator of the "newest" released device, which
|
||||
# should always be supported on the "most recent" iOS version.
|
||||
se_simulators = sorted(
|
||||
(devicetype["minRuntimeVersion"], devicetype["name"])
|
||||
for devicetype in json_data["devicetypes"]
|
||||
|
|
@ -295,7 +295,8 @@ def main():
|
|||
|
||||
parser = argparse.ArgumentParser(
|
||||
description=(
|
||||
"Manages the process of testing an Apple Python project through Xcode."
|
||||
"Manages the process of testing an Apple Python project "
|
||||
"through Xcode."
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -336,7 +337,10 @@ def main():
|
|||
|
||||
run = subcommands.add_parser(
|
||||
"run",
|
||||
usage="%(prog)s [-h] [--simulator SIMULATOR] -- <test arg> [<test arg> ...]",
|
||||
usage=(
|
||||
"%(prog)s [-h] [--simulator SIMULATOR] -- "
|
||||
"<test arg> [<test arg> ...]"
|
||||
),
|
||||
description=(
|
||||
"Run a testbed project. The arguments provided after `--` will be "
|
||||
"passed to the running iOS process as if they were arguments to "
|
||||
|
|
@ -397,9 +401,9 @@ def main():
|
|||
/ "bin"
|
||||
).is_dir():
|
||||
print(
|
||||
f"Testbed does not contain a compiled Python framework. Use "
|
||||
f"`python {sys.argv[0]} clone ...` to create a runnable "
|
||||
f"clone of this testbed."
|
||||
"Testbed does not contain a compiled Python framework. "
|
||||
f"Use `python {sys.argv[0]} clone ...` to create a "
|
||||
"runnable clone of this testbed."
|
||||
)
|
||||
sys.exit(20)
|
||||
|
||||
|
|
@ -411,7 +415,8 @@ def main():
|
|||
)
|
||||
else:
|
||||
print(
|
||||
f"Must specify test arguments (e.g., {sys.argv[0]} run -- test)"
|
||||
"Must specify test arguments "
|
||||
f"(e.g., {sys.argv[0]} run -- test)"
|
||||
)
|
||||
print()
|
||||
parser.print_help(sys.stderr)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue