Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run pyupgrade to 3.11 #21903

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
  •  
  •  
  •  
5 changes: 3 additions & 2 deletions build-support/bin/generate_builtin_lockfiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
import os
import shutil
import subprocess
from collections.abc import Sequence
from dataclasses import dataclass
from textwrap import dedent
from typing import Generic, Sequence, Type, TypeVar, cast
from typing import Generic, TypeVar, cast

from pants.backend.cc.lint.clangformat.subsystem import ClangFormat
from pants.backend.codegen.avro.java.subsystem import AvroSubsystem
Expand Down Expand Up @@ -72,7 +73,7 @@

@dataclass
class Tool(Generic[ToolBaseT]):
cls: Type[ToolBaseT]
cls: type[ToolBaseT]
backend: str

@property
Expand Down
2 changes: 1 addition & 1 deletion build-support/bin/generate_completions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import json
import subprocess
from typing import Iterable
from collections.abc import Iterable

BASH_COMPLETION_TEMPLATE = """# DO NOT EDIT.
# This script is autogenerated by build-support/bin/generate_completions.py
Expand Down
5 changes: 3 additions & 2 deletions build-support/bin/generate_json_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
import itertools
import json
import re
from typing import Any, Dict, Iterable
from collections.abc import Iterable
from typing import Any

from packaging.version import Version

Expand Down Expand Up @@ -133,7 +134,7 @@ def main() -> None:
scope=scope,
)

schema: Dict[str, Any] = dict()
schema: dict[str, Any] = dict()
schema["$schema"] = "http://json-schema.org/draft-04/schema#"
schema["description"] = "Pants configuration file schema: https://www.pantsbuild.org/"
schema["properties"] = ruleset
Expand Down
19 changes: 10 additions & 9 deletions build-support/bin/terraform_tool_versions.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@
import logging
import re
import tempfile
from collections.abc import Generator
from dataclasses import dataclass
from io import StringIO
from pathlib import Path
from typing import Dict, Generator, List, Optional, Tuple, TypeVar
from typing import TypeVar
from urllib.parse import urljoin, urlparse

import gnupg
Expand Down Expand Up @@ -69,7 +70,7 @@ class Link:
link: str


Links = List[Link]
Links = list[Link]


def get_tf_page(url) -> BeautifulSoup:
Expand Down Expand Up @@ -118,15 +119,15 @@ class VersionHash:

@dataclass(frozen=True)
class VersionHashes:
sha256sums: List[VersionHash]
sha256sums: list[VersionHash]
signature: bytes

def by_file(self) -> Dict[str, str]:
def by_file(self) -> dict[str, str]:
"""Get sha256sum by filename."""
return {x.filename: x.sha256sum for x in self.sha256sums}


def parse_sha256sums_file(file_text: str) -> List[VersionHash]:
def parse_sha256sums_file(file_text: str) -> list[VersionHash]:
"""Parse Terraform's sha256sums file."""
return [
VersionHash(**x)
Expand Down Expand Up @@ -164,7 +165,7 @@ def get_file_size(url) -> int:
return int(r.headers["content-length"])


def parse_download_url(url: str) -> Tuple[str, str]:
def parse_download_url(url: str) -> tuple[str, str]:
"""Get the version and platform from the url.

The url is of the form "https://releases.hashicorp.com/terraform/{expected_platform}/terraform_{expected_version}_{expected_platform}.zip"
Expand All @@ -183,10 +184,10 @@ def is_prerelease(version_slug: str) -> bool:

def fetch_platforms_for_version(
verifier: GPGVerifier,
inverse_platform_mapping: Dict[str, str],
inverse_platform_mapping: dict[str, str],
version_slug: str,
version_links: TFVersionLinks,
) -> Optional[List[ExternalToolVersion]]:
) -> list[ExternalToolVersion] | None:
"""Fetch platform binary information for a particular Terraform version."""
logging.info(
f"processing version {version_slug} with {len(version_links.binary_links)} binaries"
Expand Down Expand Up @@ -230,7 +231,7 @@ def fetch_platforms_for_version(

def fetch_versions(
url: str, verifier: GPGVerifier
) -> Generator[List[ExternalToolVersion], None, None]:
) -> Generator[list[ExternalToolVersion], None, None]:
"""Crawl the Terraform version site and identify all supported Terraform binaries."""
version_page = get_tf_page(url)
version_links = get_tf_links(version_page)
Expand Down
2 changes: 1 addition & 1 deletion build-support/flake8/await_in_loop.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
from __future__ import annotations

import ast
from collections.abc import Iterator, Sequence
from contextlib import contextmanager
from pathlib import PurePath
from typing import Iterator, Sequence


def check_for_await_in_loop(tree: ast.AST, filename: str) -> Iterator[tuple[int, int, str, None]]:
Expand Down
2 changes: 1 addition & 1 deletion build-support/flake8/dedent_use_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
from __future__ import annotations

import ast
from collections.abc import Iterator
from pathlib import PurePath
from typing import Iterator


def check_for_dedent_imports(tree: ast.AST, filename: str) -> Iterator[tuple[int, int, str, None]]:
Expand Down
11 changes: 5 additions & 6 deletions build-support/migration-support/convert_source_to_sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,18 @@
from io import BytesIO
from pathlib import Path
from token import NAME, OP
from typing import Dict, List, Optional, Set


def main() -> None:
args = create_parser().parse_args()
build_files: Set[Path] = {
build_files: set[Path] = {
fp
for folder in args.folders
for fp in [*folder.rglob("BUILD"), *folder.rglob("BUILD.*")]
# Check that it really is a BUILD file
if fp.is_file() and fp.stem == "BUILD"
}
updates: Dict[Path, List[str]] = {}
updates: dict[Path, list[str]] = {}
for build in build_files:
possibly_new_build = maybe_rewrite_build(build)
if possibly_new_build is not None:
Expand Down Expand Up @@ -48,7 +47,7 @@ def create_parser() -> argparse.ArgumentParser:
return parser


def maybe_rewrite_line(line: str) -> Optional[str]:
def maybe_rewrite_line(line: str) -> str | None:
try:
tokens = list(tokenize.tokenize(BytesIO(line.encode()).readline))
except tokenize.TokenError:
Expand All @@ -75,7 +74,7 @@ def maybe_rewrite_line(line: str) -> Optional[str]:
return f"{prefix}sources{interfix}[{source_value.string}]{suffix}"


def maybe_rewrite_build(build_file: Path) -> Optional[List[str]]:
def maybe_rewrite_build(build_file: Path) -> list[str] | None:
original_text = build_file.read_text()
original_text_lines = original_text.splitlines()
updated_text_lines = original_text_lines.copy()
Expand All @@ -88,7 +87,7 @@ def maybe_rewrite_build(build_file: Path) -> Optional[List[str]]:
return updated_text_lines if updated_text_lines != original_text_lines else None


def generate_diff(build_file: Path, new_content: List[str]) -> str:
def generate_diff(build_file: Path, new_content: list[str]) -> str:
def green(s: str) -> str:
return f"\x1b[32m{s}\x1b[0m"

Expand Down
36 changes: 18 additions & 18 deletions build-support/migration-support/fix_deprecated_globs_usage.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,19 @@
from enum import Enum
from functools import partial
from pathlib import Path
from typing import Dict, List, NamedTuple, Optional, Set, Union
from typing import NamedTuple, Optional


def main() -> None:
args = create_parser().parse_args()
build_files: Set[Path] = {
build_files: set[Path] = {
fp
for folder in args.folders
for fp in [*folder.rglob("BUILD"), *folder.rglob("BUILD.*")]
# Check that it really is a BUILD file
if fp.is_file() and fp.stem == "BUILD"
}
updates: Dict[Path, List[str]] = {}
updates: dict[Path, list[str]] = {}
for build in build_files:
try:
possibly_new_build = generate_possibly_new_build(build)
Expand Down Expand Up @@ -70,8 +70,8 @@ class GlobType(Enum):

class GlobFunction(NamedTuple):
glob_type: GlobType
includes: List[str]
excludes: Optional[List[str]]
includes: list[str]
excludes: list[str] | None

@staticmethod
def normalize_rglob(rglob: str) -> str:
Expand All @@ -84,7 +84,7 @@ def normalize_rglob(rglob: str) -> str:
for the original implementation.
"""
components = rglob.split(os.path.sep)
out: List[str] = []
out: list[str] = []
for component in components:
if component == "**":
if out and out[-1].startswith("**"):
Expand Down Expand Up @@ -118,25 +118,25 @@ def parse(cls, glob_func: ast.Call, *, build_file: Path) -> Optional["GlobFuncti
f"using variables instead of raw strings. Please manually update."
)
return None
include_globs: List[str] = [arg.s for arg in glob_func.args] # type: ignore[attr-defined]
include_globs: list[str] = [arg.s for arg in glob_func.args] # type: ignore[attr-defined]

# Excludes are tricky...The optional `exclude` keyword is guaranteed to have a list as its
# value, but that list can have any of these elements:
# * `str`
# * `glob`, `rglob`, or `zglob`
# * list of either of the above options
exclude_globs: Optional[List[str]] = None
exclude_arg: Optional[ast.keyword] = next(iter(glob_func.keywords), None)
exclude_globs: list[str] | None = None
exclude_arg: ast.keyword | None = next(iter(glob_func.keywords), None)
if exclude_arg is not None and isinstance(exclude_arg.value, ast.List):
exclude_elements: List[Union[ast.Call, ast.Str, ast.List]] = exclude_arg.value.elts # type: ignore[assignment]
nested_exclude_elements: List[Union[ast.Call, ast.Str]] = list(
exclude_elements: list[ast.Call | ast.Str | ast.List] = exclude_arg.value.elts # type: ignore[assignment]
nested_exclude_elements: list[ast.Call | ast.Str] = list(
itertools.chain.from_iterable(
nested_list.elts # type: ignore[misc]
for nested_list in exclude_elements
if isinstance(nested_list, ast.List)
)
)
combined_exclude_elements: List[Union[ast.Call, ast.Str]] = [
combined_exclude_elements: list[ast.Call | ast.Str] = [
element
for element in (*exclude_elements, *nested_exclude_elements)
# Lists are already flattened, so we want to remove them from this collection.
Expand Down Expand Up @@ -202,19 +202,19 @@ def warning_msg(
}


def generate_possibly_new_build(build_file: Path) -> Optional[List[str]]:
def generate_possibly_new_build(build_file: Path) -> list[str] | None:
"""If any targets use `globs`, `rglobs`, or `zglobs`, this will return a replaced BUILD file."""
original_text = build_file.read_text()
original_text_lines = original_text.splitlines()
updated_text_lines = original_text_lines.copy()

targets: List[ast.Call] = [
targets: list[ast.Call] = [
target.value
for target in ast.parse(original_text).body
if isinstance(target, ast.Expr) and isinstance(target.value, ast.Call)
]
for target in targets:
bundles_arg: Optional[ast.keyword] = next(
bundles_arg: ast.keyword | None = next(
(
kwarg
for kwarg in target.keywords
Expand All @@ -223,7 +223,7 @@ def generate_possibly_new_build(build_file: Path) -> Optional[List[str]]:
None,
)
if bundles_arg is not None:
bundle_funcs: List[ast.Call] = [
bundle_funcs: list[ast.Call] = [
element
for element in bundles_arg.value.elts # type: ignore[attr-defined]
if isinstance(element, ast.Call) and element.func.id == "bundle" # type: ignore[attr-defined]
Expand Down Expand Up @@ -254,7 +254,7 @@ def generate_possibly_new_build(build_file: Path) -> Optional[List[str]]:
script_restriction=SCRIPT_RESTRICTIONS["no_bundles"],
)
)
sources_arg: Optional[ast.keyword] = next(
sources_arg: ast.keyword | None = next(
(kwarg for kwarg in target.keywords if kwarg.arg == "sources"), None
)
if not sources_arg or not isinstance(sources_arg.value, ast.Call):
Expand Down Expand Up @@ -305,7 +305,7 @@ def generate_possibly_new_build(build_file: Path) -> Optional[List[str]]:
return updated_text_lines if updated_text_lines != original_text_lines else None


def generate_diff(build_file: Path, new_content: List[str]) -> str:
def generate_diff(build_file: Path, new_content: list[str]) -> str:
def green(s: str) -> str:
return f"\x1b[32m{s}\x1b[0m"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@
from functools import partial
from pathlib import Path
from textwrap import dedent
from typing import List, Optional, Tuple
from typing import Optional

from fix_deprecated_globs_usage import SCRIPT_RESTRICTIONS, generate_possibly_new_build, warning_msg

from pants.util.contextutil import temporary_dir

Result = Optional[List[str]]
Result = Optional[list[str]]


def run_on_build_file(content: str) -> Tuple[Result, Path]:
def run_on_build_file(content: str) -> tuple[Result, Path]:
with temporary_dir() as tmpdir:
build = Path(tmpdir, "BUILD")
build.write_text(content)
Expand Down Expand Up @@ -351,7 +351,7 @@ def check_multiple_bad_bundle_entries(
build_file_content: str,
warning_slice: slice,
*,
replacements_and_line_numbers: List[Tuple[str, int]],
replacements_and_line_numbers: list[tuple[str, int]],
) -> None:
result, build = run_on_build_file(build_file_content)
assert result is None
Expand Down
5 changes: 2 additions & 3 deletions build-support/migration-support/migrate_to_toml_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@
import logging
import re
from pathlib import Path
from typing import Dict, List


def main() -> None:
args = create_parser().parse_args()
updates: Dict[Path, List[str]] = {}
updates: dict[Path, list[str]] = {}
for config in args.files:
if config.suffix not in [".ini", ".cfg"]:
logging.warning(f"This script may only be run on INI files. Skipping {config}.")
Expand Down Expand Up @@ -72,7 +71,7 @@ def update_primitive_value(original: str) -> str:
return f'"{original}"'


def generate_new_config(config: Path) -> List[str]:
def generate_new_config(config: Path) -> list[str]:
original_text = config.read_text()
original_text_lines = original_text.splitlines()
updated_text_lines = original_text_lines.copy()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
from __future__ import annotations

import textwrap
from collections.abc import Iterable
from dataclasses import dataclass
from pathlib import Path
from typing import Iterable

from _pytest.fixtures import FixtureRequest

Expand Down
Loading
Loading