From 27fad4fcf1b3ad7455d9c0556a5b4475dddddf76 Mon Sep 17 00:00:00 2001 From: sj Date: Mon, 3 Feb 2025 08:41:04 -0500 Subject: [PATCH 01/10] Upgrading pants plugins --- .../lockfile_fixture.py | 2 +- .../server/graphql/query/rules.py | 17 +++++++------- .../server/graphql/query/targets.py | 22 +++++++++---------- .../pants_explorer/server/graphql/setup.py | 2 +- .../pants_explorer/server/uvicorn.py | 3 ++- pants.toml | 2 +- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/pants-plugins/internal_plugins/test_lockfile_fixtures/lockfile_fixture.py b/pants-plugins/internal_plugins/test_lockfile_fixtures/lockfile_fixture.py index 705c3e5afc7..a3dba3ec0f8 100644 --- a/pants-plugins/internal_plugins/test_lockfile_fixtures/lockfile_fixture.py +++ b/pants-plugins/internal_plugins/test_lockfile_fixtures/lockfile_fixture.py @@ -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 diff --git a/pants-plugins/pants_explorer/server/graphql/query/rules.py b/pants-plugins/pants_explorer/server/graphql/query/rules.py index 594b467a3df..c7f06af2d8c 100644 --- a/pants-plugins/pants_explorer/server/graphql/query/rules.py +++ b/pants-plugins/pants_explorer/server/graphql/query/rules.py @@ -4,8 +4,9 @@ from __future__ import annotations import re +from collections.abc import Iterable, Iterator from dataclasses import asdict -from typing import Iterable, Iterator, List, Optional, cast +from typing import cast import strawberry from pants_explorer.server.graphql.context import GraphQLContext @@ -17,12 +18,12 @@ @strawberry.type(description=cast(str, help_info_extracter.RuleInfo.__doc__)) class RuleInfo: name: str - description: Optional[str] - documentation: Optional[str] + description: str | None + documentation: str | None provider: str output_type: str - input_types: List[str] - awaitables: List[str] + input_types: list[str] + awaitables: list[str] @classmethod def from_help(cls, info: help_info_extracter.RuleInfo) -> RuleInfo: @@ -34,10 +35,10 @@ def from_help(cls, info: help_info_extracter.RuleInfo) -> RuleInfo: description="Filter rules based on name and/or limit the number of entries to return." ) class RulesQuery: - name_re: Optional[str] = strawberry.field( + name_re: str | None = strawberry.field( default=None, description="Select rules matching a regexp." ) - limit: Optional[int] = strawberry.field( + limit: int | None = strawberry.field( default=None, description="Limit the number of entries returned." ) @@ -66,7 +67,7 @@ class QueryRulesMixin: """Get rules related info.""" @strawberry.field - def rules(self, info: Info, query: Optional[RulesQuery] = None) -> List[RuleInfo]: + def rules(self, info: Info, query: RulesQuery | None = None) -> list[RuleInfo]: request_state = GraphQLContext.request_state_from_info(info) return list( RulesQuery.filter( diff --git a/pants-plugins/pants_explorer/server/graphql/query/targets.py b/pants-plugins/pants_explorer/server/graphql/query/targets.py index 8492ee00e2e..e932d831b91 100644 --- a/pants-plugins/pants_explorer/server/graphql/query/targets.py +++ b/pants-plugins/pants_explorer/server/graphql/query/targets.py @@ -4,8 +4,8 @@ from __future__ import annotations import re +from collections.abc import Iterable, Iterator from dataclasses import asdict -from typing import Iterable, Iterator, List, Optional import strawberry from pants_explorer.server.graphql.context import GraphQLContext @@ -37,7 +37,7 @@ class TargetTypeField: description: str = strawberry.field(description="Field documentation.") type_hint: str = strawberry.field(description="Field type hint.") required: bool = strawberry.field(description="Field required flag.") - default: Optional[str] = strawberry.field(description="Field default value.") + default: str | None = strawberry.field(description="Field default value.") @strawberry.type(description="Describes a target type.") @@ -48,7 +48,7 @@ class TargetType: provider: str = strawberry.field(description="Backend that registered the target type.") summary: str = strawberry.field(description="Target type documentation summary.") description: str = strawberry.field(description="Target type documentation.") - fields: List[TargetTypeField] = strawberry.field(description="All valid fields for the target.") + fields: list[TargetTypeField] = strawberry.field(description="All valid fields for the target.") @classmethod def from_help(cls, info: TargetTypeHelpInfo) -> TargetType: @@ -85,10 +85,10 @@ def from_data(cls, data: TargetData) -> Target: description="Filter target types based on type (alias) and/or limit the number of entries to return." ) class TargetTypesQuery: - alias_re: Optional[str] = strawberry.field( + alias_re: str | None = strawberry.field( default=None, description="Select targets types matching a regexp." ) - limit: Optional[int] = strawberry.field( + limit: int | None = strawberry.field( default=None, description="Limit the number of entries returned." ) @@ -116,16 +116,16 @@ def filter( @strawberry.input(description="Filter targets based on the supplied query.") class TargetsQuery: - specs: Optional[List[str]] = strawberry.field( + specs: list[str] | None = strawberry.field( default=None, description=( "Select targets matching the address specs. (Same syntax as supported on the command line.)" ), ) - target_type: Optional[str] = strawberry.field( + target_type: str | None = strawberry.field( default=None, description="Select targets of a certain type only." ) - limit: Optional[int] = strawberry.field( + limit: int | None = strawberry.field( default=None, description="Limit the number of entries returned." ) @@ -154,9 +154,7 @@ class QueryTargetsMixin: @strawberry.field( description="Get all registered target types that may be used in BUILD files." ) - def target_types( - self, info: Info, query: Optional[TargetTypesQuery] = None - ) -> List[TargetType]: + def target_types(self, info: Info, query: TargetTypesQuery | None = None) -> list[TargetType]: request_state = GraphQLContext.request_state_from_info(info) return list( TargetTypesQuery.filter( @@ -169,7 +167,7 @@ def target_types( ) @strawberry.field(description="Get all targets defined in BUILD files.") - async def targets(self, info: Info, query: Optional[TargetsQuery] = None) -> List[Target]: + async def targets(self, info: Info, query: TargetsQuery | None = None) -> list[Target]: req = GraphQLContext.request_state_from_info(info).product_request specs = ( _get_specs_parser().parse_specs( diff --git a/pants-plugins/pants_explorer/server/graphql/setup.py b/pants-plugins/pants_explorer/server/graphql/setup.py index be2b4e7dd5f..02778ec2b47 100644 --- a/pants-plugins/pants_explorer/server/graphql/setup.py +++ b/pants-plugins/pants_explorer/server/graphql/setup.py @@ -4,7 +4,7 @@ from __future__ import annotations import json -from typing import Callable +from collections.abc import Callable import strawberry from pants_explorer.server.browser import Browser diff --git a/pants-plugins/pants_explorer/server/uvicorn.py b/pants-plugins/pants_explorer/server/uvicorn.py index 31ce046dac9..8fdbcfdd607 100644 --- a/pants-plugins/pants_explorer/server/uvicorn.py +++ b/pants-plugins/pants_explorer/server/uvicorn.py @@ -4,8 +4,9 @@ from __future__ import annotations import logging +from collections.abc import Callable from dataclasses import dataclass, field -from typing import Any, Callable +from typing import Any from fastapi import FastAPI from pants_explorer.server.browser import BrowserRequest diff --git a/pants.toml b/pants.toml index a82955a3ec1..0c46abd9f2c 100644 --- a/pants.toml +++ b/pants.toml @@ -216,7 +216,7 @@ template_by_globs = "@build-support/preambles/config.yaml" diff = true [pyupgrade] -args = ["--keep-runtime-typing", "--py38-plus"] +args = ["--keep-runtime-typing", "--py311-plus"] [jvm] From fcd36c198183ae380f222239563ae7df1735a0c3 Mon Sep 17 00:00:00 2001 From: sj Date: Mon, 3 Feb 2025 08:41:44 -0500 Subject: [PATCH 02/10] Upgraded tests folder --- tests/python/pants_test/init/test_plugin_resolver.py | 4 ++-- tests/python/pants_test/init/test_util.py | 3 ++- tests/python/pants_test/integration/graph_integration_test.py | 2 +- .../python/pants_test/pantsd/pantsd_integration_test_base.py | 3 ++- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/python/pants_test/init/test_plugin_resolver.py b/tests/python/pants_test/init/test_plugin_resolver.py index 21e2162296a..05560385cf5 100644 --- a/tests/python/pants_test/init/test_plugin_resolver.py +++ b/tests/python/pants_test/init/test_plugin_resolver.py @@ -6,11 +6,11 @@ import os import shutil import sys +from collections.abc import Iterable, Sequence from contextlib import contextmanager from dataclasses import dataclass from pathlib import Path, PurePath from textwrap import dedent -from typing import Dict, Iterable, Sequence import pytest from pkg_resources import Distribution, Requirement, WorkingSet @@ -148,7 +148,7 @@ def provide_chroot(existing): ) with provide_chroot(chroot) as (root_dir, create_artifacts): - env: Dict[str, str] = {} + env: dict[str, str] = {} repo_dir = os.path.join(root_dir, "repo") def _create_artifact(name, version, install_requires): diff --git a/tests/python/pants_test/init/test_util.py b/tests/python/pants_test/init/test_util.py index 934a6ae4d94..97ae4b130af 100644 --- a/tests/python/pants_test/init/test_util.py +++ b/tests/python/pants_test/init/test_util.py @@ -2,8 +2,9 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). import os +from collections.abc import Iterator from contextlib import contextmanager -from typing import Iterator, cast +from typing import cast from pants.fs.fs import safe_filename_from_path from pants.init.util import init_workdir diff --git a/tests/python/pants_test/integration/graph_integration_test.py b/tests/python/pants_test/integration/graph_integration_test.py index 88054face1d..350332abae1 100644 --- a/tests/python/pants_test/integration/graph_integration_test.py +++ b/tests/python/pants_test/integration/graph_integration_test.py @@ -2,10 +2,10 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). import os +from collections.abc import Iterator from contextlib import contextmanager from pathlib import Path from textwrap import dedent -from typing import Iterator from pants.option.scope import GLOBAL_SCOPE_CONFIG_SECTION from pants.testutil.pants_integration_test import run_pants diff --git a/tests/python/pants_test/pantsd/pantsd_integration_test_base.py b/tests/python/pants_test/pantsd/pantsd_integration_test_base.py index 3bcd95ce60f..b2fc1b18991 100644 --- a/tests/python/pants_test/pantsd/pantsd_integration_test_base.py +++ b/tests/python/pants_test/pantsd/pantsd_integration_test_base.py @@ -7,9 +7,10 @@ import os import time import unittest +from collections.abc import Callable, Iterator, Mapping from contextlib import contextmanager from dataclasses import dataclass -from typing import Any, Callable, Iterator, Mapping +from typing import Any from colors import bold, cyan, magenta From e0f59a41e701e0f0527e7e3399952c67fa6a7d35 Mon Sep 17 00:00:00 2001 From: sj Date: Mon, 3 Feb 2025 09:00:34 -0500 Subject: [PATCH 03/10] Upgraded backends to 3.11 syntax --- .../pants/backend/adhoc/code_quality_tool.py | 3 +- .../pants/backend/adhoc/run_system_binary.py | 2 +- .../backend/awslambda/python/target_types.py | 9 +++-- .../pants/backend/build_files/fix/base.py | 2 +- .../fix/deprecations/renamed_fields_rules.py | 3 +- .../pants/backend/build_files/fmt/base.py | 2 +- src/python/pants/backend/build_files/utils.py | 2 +- .../backend/cc/dependency_inference/rules.py | 3 +- src/python/pants/backend/cc/goals/tailor.py | 2 +- .../backend/cc/lint/clangformat/rules.py | 2 +- .../backend/cc/lint/clangformat/skip_field.py | 2 +- .../backend/cc/lint/clangformat/subsystem.py | 2 +- .../pants/backend/cc/subsystems/compiler.py | 2 +- src/python/pants/backend/cc/target_types.py | 2 +- .../pants/backend/cc/util_rules/toolchain.py | 2 +- .../pants/backend/codegen/avro/java/rules.py | 2 +- .../avro/java/rules_integration_test.py | 2 +- .../protobuf/go/rules_integration_test.py | 2 +- .../protobuf/java/dependency_inference.py | 5 +-- .../codegen/protobuf/jvm_symbol_mapper.py | 3 +- .../protobuf_dependency_inference_test.py | 3 +- .../protobuf/scala/rules_integration_test.py | 2 +- .../codegen/soap/java/dependency_inference.py | 3 +- .../soap/java/rules_integration_test.py | 2 +- .../codegen/soap/java/symbol_mapper.py | 5 ++- .../codegen/thrift/jvm_symbol_mapper.py | 3 +- .../backend/codegen/thrift/thrift_parser.py | 2 +- .../codegen/thrift/thrift_parser_test.py | 2 +- src/python/pants/backend/cue/goals/fix.py | 2 +- .../pants/backend/cue/goals/fix_test.py | 2 +- src/python/pants/backend/cue/goals/lint.py | 3 +- .../pants/backend/cue/goals/lint_test.py | 3 +- src/python/pants/backend/debian/rules.py | 2 +- .../pants/backend/debian/target_types.py | 2 +- .../pants/backend/debian/target_types_test.py | 4 +- .../backend/docker/goals/package_image.py | 3 +- .../docker/goals/package_image_test.py | 3 +- .../backend/docker/goals/publish_test.py | 3 +- src/python/pants/backend/docker/registries.py | 3 +- .../subsystems/dockerfile_wrapper_script.py | 2 +- .../pants/backend/docker/target_types.py | 7 ++-- .../docker/util_rules/docker_binary.py | 3 +- .../docker/util_rules/docker_build_args.py | 3 +- .../docker/util_rules/docker_build_context.py | 2 +- .../docker/util_rules/docker_build_env.py | 2 +- .../docker/util_rules/dockerfile_test.py | 3 +- src/python/pants/backend/docker/utils.py | 5 +-- .../cc/lint/clangformat/register.py | 2 +- .../javascript/lint/prettier/register.py | 2 +- .../experimental/javascript/register.py | 2 +- .../backend/experimental/openapi/register.py | 2 +- .../python/typecheck/pyright/register.py | 2 +- .../backend/experimental/swift/register.py | 2 +- .../experimental/tools/semgrep/register.py | 2 +- .../experimental/tools/yamllint/register.py | 2 +- .../experimental/typescript/register.py | 4 +- .../backend/go/go_sources/load_go_binary.py | 2 +- src/python/pants/backend/go/goals/generate.py | 2 +- src/python/pants/backend/go/goals/test.py | 3 +- src/python/pants/backend/go/target_types.py | 6 +-- src/python/pants/backend/go/testutil.py | 8 ++-- .../pants/backend/go/util_rules/assembly.py | 2 +- .../pants/backend/go/util_rules/build_opts.py | 2 +- .../backend/go/util_rules/build_opts_test.py | 2 +- .../pants/backend/go/util_rules/build_pkg.py | 2 +- .../backend/go/util_rules/build_pkg_target.py | 4 +- src/python/pants/backend/go/util_rules/cgo.py | 2 +- .../backend/go/util_rules/cgo_security.py | 2 +- .../pants/backend/go/util_rules/cgo_test.py | 2 +- .../backend/go/util_rules/coverage_html.py | 2 +- .../pants/backend/go/util_rules/embedcfg.py | 3 +- .../backend/go/util_rules/go_bootstrap.py | 2 +- .../backend/go/util_rules/pkg_pattern.py | 2 +- .../backend/go/util_rules/pkg_pattern_test.py | 2 +- src/python/pants/backend/go/util_rules/sdk.py | 2 +- .../pants/backend/go/util_rules/testutil.py | 2 +- .../pants/backend/go/util_rules/vendor.py | 2 +- .../python/target_types.py | 9 +++-- .../helm/check/kubeconform/deployment_test.py | 2 +- .../helm/check/kubeconform/extra_fields.py | 5 +-- .../helm/dependency_inference/chart.py | 2 +- .../helm/dependency_inference/unittest.py | 2 +- .../pants/backend/helm/goals/deploy_test.py | 2 +- .../pants/backend/helm/goals/lint_test.py | 2 +- .../pants/backend/helm/resolve/artifacts.py | 3 +- .../pants/backend/helm/resolve/remotes.py | 3 +- .../pants/backend/helm/subsystems/helm.py | 3 +- .../backend/helm/subsystems/post_renderer.py | 3 +- .../pants/backend/helm/util_rules/chart.py | 3 +- .../pants/backend/helm/util_rules/renderer.py | 3 +- .../pants/backend/helm/util_rules/tool.py | 8 ++-- src/python/pants/backend/helm/utils/yaml.py | 7 ++-- .../dependency_inference/symbol_mapper.py | 2 +- .../java/dependency_inference/types.py | 3 +- src/python/pants/backend/java/goals/tailor.py | 2 +- .../javascript/dependency_inference/rules.py | 2 +- .../backend/javascript/goals/lockfile.py | 2 +- .../pants/backend/javascript/goals/tailor.py | 2 +- .../pants/backend/javascript/goals/test.py | 2 +- .../javascript/install_node_package.py | 2 +- .../backend/javascript/lint/prettier/rules.py | 2 +- .../javascript/lint/prettier/skip_field.py | 2 +- .../javascript/lint/prettier/subsystem.py | 2 +- .../backend/javascript/nodejs_project.py | 2 +- .../backend/javascript/nodejs_project_test.py | 2 +- .../pants/backend/javascript/package/rules.py | 3 +- .../pants/backend/javascript/package_json.py | 7 ++-- .../backend/javascript/package_json_test.py | 2 +- .../pants/backend/javascript/resolve.py | 2 +- .../pants/backend/javascript/run/rules.py | 2 +- .../backend/javascript/subsystems/nodejs.py | 3 +- .../javascript/subsystems/nodejs_tool.py | 3 +- src/python/pants/backend/jsx/goals/tailor.py | 2 +- .../backend/kotlin/compile/kotlinc_plugins.py | 2 +- .../dependency_inference/kotlin_parser.py | 3 +- .../dependency_inference/symbol_mapper.py | 2 +- .../pants/backend/kotlin/goals/tailor.py | 2 +- .../pants/backend/makeself/goals/package.py | 8 ++-- .../pants/backend/makeself/goals/run.py | 4 +- .../pants/backend/makeself/subsystem.py | 6 +-- .../pants/backend/makeself/system_binaries.py | 4 +- .../pants/backend/nfpm/fields/contents.py | 15 +++---- src/python/pants/backend/nfpm/fields/deb.py | 7 ++-- src/python/pants/backend/nfpm/fields/rpm.py | 4 +- .../pants/backend/nfpm/fields/scripts.py | 6 +-- .../backend/nfpm/util_rules/inject_config.py | 2 +- .../codegen/java/rules_integration_test.py | 2 +- .../openapi/codegen/java/symbol_mapper.py | 5 ++- .../openapi/codegen/python/generate.py | 3 +- .../python/generate_integration_test.py | 2 +- .../backend/openapi/dependency_inference.py | 3 +- .../pants/backend/openapi/goals/tailor.py | 2 +- .../openapi/util_rules/generator_process.py | 2 +- .../backend/project_info/dependencies_test.py | 8 ++-- .../pants/backend/project_info/dependents.py | 4 +- .../backend/project_info/dependents_test.py | 7 ++-- .../pants/backend/project_info/filedeps.py | 2 +- .../backend/project_info/filter_targets.py | 2 +- .../backend/project_info/list_roots_test.py | 7 ++-- .../backend/project_info/list_targets.py | 4 +- .../pants/backend/project_info/paths.py | 2 +- .../pants/backend/project_info/paths_test.py | 4 +- src/python/pants/backend/project_info/peek.py | 3 +- .../pants/backend/project_info/peek_test.py | 3 +- .../pants/backend/project_info/regex_lint.py | 3 +- .../default_module_mapping.py | 11 ++--- .../default_unowned_dependencies.py | 3 +- .../dependency_inference/module_mapper.py | 13 +++--- .../module_mapper_test.py | 6 +-- .../parse_python_dependencies.py | 2 +- .../python/dependency_inference/rules.py | 6 +-- .../python/dependency_inference/rules_test.py | 2 +- .../stevedore/python_target_dependencies.py | 2 +- .../pants/backend/python/goals/coverage_py.py | 3 +- .../pants/backend/python/goals/debug_goals.py | 6 +-- .../python/goals/export_integration_test.py | 2 +- .../python/goals/package_pex_binary.py | 3 +- .../backend/python/goals/publish_test.py | 2 +- .../backend/python/goals/pytest_runner.py | 9 ++--- .../goals/pytest_runner_integration_test.py | 2 +- src/python/pants/backend/python/goals/repl.py | 2 +- .../pants/backend/python/goals/run_helper.py | 6 +-- .../goals/run_pex_binary_integration_test.py | 10 ++--- .../python/goals/run_python_requirement.py | 5 +-- .../backend/python/goals/run_python_source.py | 3 +- .../run_python_source_integration_test.py | 3 +- .../pants/backend/python/goals/tailor.py | 2 +- .../pants/backend/python/lint/bandit/rules.py | 4 +- .../lint/bandit/rules_integration_test.py | 2 +- .../backend/python/lint/black/subsystem.py | 2 +- .../pants/backend/python/lint/flake8/rules.py | 3 +- .../pants/backend/python/lint/isort/rules.py | 3 +- .../backend/python/lint/isort/subsystem.py | 2 +- .../backend/python/lint/pydocstyle/rules.py | 4 +- .../lint/pydocstyle/rules_integration_test.py | 2 +- .../pants/backend/python/lint/pylint/rules.py | 3 +- .../backend/python/lint/pylint/subsystem.py | 2 +- .../pants/backend/python/lint/ruff/common.py | 6 +-- .../backend/python/lint/ruff/subsystem.py | 2 +- .../backend/python/lint/yapf/subsystem.py | 2 +- .../backend/python/macros/common_fields.py | 11 ++--- .../python/macros/common_requirements_rule.py | 3 +- .../python/macros/poetry_requirements.py | 3 +- .../backend/python/macros/python_artifact.py | 12 +++--- .../python/macros/python_requirements.py | 3 +- .../backend/python/macros/uv_requirements.py | 2 +- .../python_build_standalone/constraints.py | 3 +- .../python_build_standalone/rules.py | 3 +- .../rules_integration_test.py | 2 +- .../pants/backend/python/subsystems/pytest.py | 2 +- .../python/subsystems/python_native_code.py | 2 +- .../python/subsystems/python_tool_base.py | 5 ++- .../pants/backend/python/subsystems/setup.py | 9 +++-- .../pants/backend/python/target_types.py | 40 +++++++------------ .../backend/python/target_types_rules.py | 15 +++---- .../pants/backend/python/target_types_test.py | 2 +- .../backend/python/typecheck/mypy/rules.py | 8 ++-- .../python/typecheck/mypy/subsystem.py | 2 +- .../backend/python/typecheck/pyright/rules.py | 2 +- .../pyright/rules_integration_test.py | 2 +- .../python/typecheck/pyright/skip_field.py | 2 +- .../backend/python/typecheck/pytype/rules.py | 2 +- .../pytype/rules_integration_test.py | 2 +- .../python/typecheck/pytype/skip_field.py | 2 +- .../pants/backend/python/util_rules/dists.py | 3 +- .../backend/python/util_rules/entry_points.py | 2 +- .../python/util_rules/entry_points_test.py | 2 +- .../pants/backend/python/util_rules/faas.py | 4 +- .../backend/python/util_rules/faas_test.py | 3 +- .../util_rules/interpreter_constraints.py | 5 ++- .../interpreter_constraints_test.py | 2 +- .../backend/python/util_rules/local_dists.py | 2 +- .../python/util_rules/lockfile_diff.py | 3 +- .../python/util_rules/lockfile_metadata.py | 11 ++--- .../util_rules/lockfile_metadata_test.py | 2 +- .../python/util_rules/package_dists.py | 15 +++---- .../python/util_rules/package_dists_test.py | 2 +- .../backend/python/util_rules/partition.py | 3 +- .../pants/backend/python/util_rules/pex.py | 3 +- .../backend/python/util_rules/pex_cli.py | 20 +++++----- .../python/util_rules/pex_environment.py | 2 +- .../python/util_rules/pex_from_targets.py | 2 +- .../util_rules/pex_from_targets_test.py | 5 ++- .../python/util_rules/pex_requirements.py | 3 +- .../python/util_rules/pex_test_utils.py | 3 +- .../python/util_rules/python_sources.py | 2 +- .../python/util_rules/python_sources_test.py | 2 +- .../backend/rust/util_rules/toolchains.py | 2 +- src/python/pants/backend/scala/bsp/rules.py | 2 +- .../backend/scala/compile/scalac_plugins.py | 2 +- .../dependency_inference/scala_parser.py | 3 +- .../dependency_inference/symbol_mapper.py | 2 +- .../pants/backend/scala/goals/tailor.py | 2 +- .../backend/scala/lint/scalafix/rules.py | 3 +- .../lint/scalafix/rules_integration_test.py | 3 +- .../backend/scala/test/scalatest_test.py | 4 +- .../pants/backend/shell/goals/tailor.py | 2 +- .../shell/lint/shellcheck/subsystem.py | 2 +- .../backend/shell/lint/shfmt/subsystem.py | 2 +- .../pants/backend/sql/lint/sqlfluff/rules.py | 7 ++-- .../backend/sql/lint/sqlfluff/skip_field.py | 2 +- .../backend/sql/lint/sqlfluff/subsystem.py | 2 +- .../pants/backend/swift/goals/tailor.py | 2 +- .../pants/backend/terraform/dependencies.py | 3 +- .../backend/terraform/dependencies_test.py | 5 +-- .../backend/terraform/dependency_inference.py | 4 +- .../pants/backend/terraform/goals/check.py | 3 +- .../backend/terraform/goals/check_test.py | 4 +- .../pants/backend/terraform/goals/tailor.py | 3 +- .../pants/backend/terraform/hcl2_parser.py | 3 +- .../lint/tffmt/tffmt_integration_test.py | 10 ++--- .../pants/backend/terraform/partition.py | 2 +- src/python/pants/backend/terraform/tool.py | 4 +- .../pants/backend/tools/preamble/subsystem.py | 2 +- .../pants/backend/tools/semgrep/rules.py | 2 +- .../tools/semgrep/rules_integration_test.py | 2 +- .../pants/backend/tools/semgrep/subsystem.py | 2 +- .../pants/backend/tools/trufflehog/rules.py | 2 +- .../backend/tools/workunit_logger/rules.py | 8 ++-- .../pants/backend/tools/yamllint/subsystem.py | 2 +- src/python/pants/backend/tsx/goals/tailor.py | 2 +- .../typescript/dependency_inference/rules.py | 2 +- .../pants/backend/typescript/goals/tailor.py | 4 +- .../pants/backend/typescript/tsconfig.py | 3 +- src/python/pants/backend/visibility/glob.py | 3 +- .../pants/backend/visibility/glob_test.py | 3 +- .../pants/backend/visibility/rule_types.py | 3 +- 267 files changed, 488 insertions(+), 465 deletions(-) diff --git a/src/python/pants/backend/adhoc/code_quality_tool.py b/src/python/pants/backend/adhoc/code_quality_tool.py index 3248457734f..e34fddac410 100644 --- a/src/python/pants/backend/adhoc/code_quality_tool.py +++ b/src/python/pants/backend/adhoc/code_quality_tool.py @@ -1,7 +1,8 @@ # Copyright 2023 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). +from collections.abc import Iterable from dataclasses import dataclass -from typing import ClassVar, Iterable +from typing import ClassVar from pants.core.goals.fix import Fix, FixFilesRequest, FixResult from pants.core.goals.fmt import Fmt, FmtFilesRequest, FmtResult diff --git a/src/python/pants/backend/adhoc/run_system_binary.py b/src/python/pants/backend/adhoc/run_system_binary.py index 1a8c24d7efa..c5745dc2f0f 100644 --- a/src/python/pants/backend/adhoc/run_system_binary.py +++ b/src/python/pants/backend/adhoc/run_system_binary.py @@ -5,9 +5,9 @@ import logging import re +from collections.abc import Mapping from dataclasses import dataclass from io import StringIO -from typing import Mapping from pants.backend.adhoc.target_types import ( SystemBinaryExtraSearchPathsField, diff --git a/src/python/pants/backend/awslambda/python/target_types.py b/src/python/pants/backend/awslambda/python/target_types.py index 13fcb44a7c0..80881bedeef 100644 --- a/src/python/pants/backend/awslambda/python/target_types.py +++ b/src/python/pants/backend/awslambda/python/target_types.py @@ -6,7 +6,8 @@ import re from dataclasses import dataclass from enum import Enum -from typing import ClassVar, Match, Optional, Tuple, cast +from re import Match +from typing import ClassVar, cast from pants.backend.python.target_types import PexCompletePlatformsField, PythonResolveField from pants.backend.python.util_rules.faas import ( @@ -104,7 +105,7 @@ class PythonAwsLambdaFunctionRuntimes(Enum): PYTHON_312 = "python3.12" PYTHON_313 = "python3.13" - def to_interpreter_version(self) -> Tuple[int, int]: + def to_interpreter_version(self) -> tuple[int, int]: """Returns the Python version implied by the runtime, as (major, minor).""" mo = cast(Match, re.match(PYTHON_RUNTIME_REGEX, self.value)) return int(mo.group("major")), int(mo.group("minor")) @@ -153,7 +154,7 @@ class PythonAwsLambdaRuntime(PythonFaaSRuntimeField): ) @classmethod - def compute_value(cls, raw_value: Optional[str], address: Address) -> Optional[str]: + def compute_value(cls, raw_value: str | None, address: Address) -> str | None: value = super().compute_value(raw_value, address) if value is None: return None @@ -168,7 +169,7 @@ def compute_value(cls, raw_value: Optional[str], address: Address) -> Optional[s ) return value - def to_interpreter_version(self) -> Optional[Tuple[int, int]]: + def to_interpreter_version(self) -> tuple[int, int] | None: """Returns the Python version implied by the runtime, as (major, minor).""" if self.value is None: return None diff --git a/src/python/pants/backend/build_files/fix/base.py b/src/python/pants/backend/build_files/fix/base.py index 375b90d3136..d1bc6248b73 100644 --- a/src/python/pants/backend/build_files/fix/base.py +++ b/src/python/pants/backend/build_files/fix/base.py @@ -3,7 +3,7 @@ from __future__ import annotations -from typing import Iterable +from collections.abc import Iterable from pants.backend.build_files.utils import _get_build_file_partitioner_rules from pants.core.goals.fix import FixFilesRequest diff --git a/src/python/pants/backend/build_files/fix/deprecations/renamed_fields_rules.py b/src/python/pants/backend/build_files/fix/deprecations/renamed_fields_rules.py index 5ae65ad000e..013261c8122 100644 --- a/src/python/pants/backend/build_files/fix/deprecations/renamed_fields_rules.py +++ b/src/python/pants/backend/build_files/fix/deprecations/renamed_fields_rules.py @@ -5,8 +5,9 @@ import tokenize from collections import defaultdict +from collections.abc import Mapping from dataclasses import dataclass -from typing import DefaultDict, Mapping +from typing import DefaultDict from pants.backend.build_files.fix.base import FixBuildFilesRequest from pants.backend.build_files.fix.deprecations.base import FixBUILDFileRequest, FixedBUILDFile diff --git a/src/python/pants/backend/build_files/fmt/base.py b/src/python/pants/backend/build_files/fmt/base.py index 3fd1ab57010..108ea85e2b0 100644 --- a/src/python/pants/backend/build_files/fmt/base.py +++ b/src/python/pants/backend/build_files/fmt/base.py @@ -2,7 +2,7 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). -from typing import Iterable +from collections.abc import Iterable from pants.backend.build_files.utils import _get_build_file_partitioner_rules from pants.core.goals.fmt import FmtFilesRequest diff --git a/src/python/pants/backend/build_files/utils.py b/src/python/pants/backend/build_files/utils.py index 4c6f5437828..90cde71f206 100644 --- a/src/python/pants/backend/build_files/utils.py +++ b/src/python/pants/backend/build_files/utils.py @@ -4,7 +4,7 @@ from __future__ import annotations import os -from typing import Iterable +from collections.abc import Iterable from pants.core.goals.fix import FixFilesRequest, Partitions from pants.core.goals.multi_tool_goal_helper import SkippableSubsystem diff --git a/src/python/pants/backend/cc/dependency_inference/rules.py b/src/python/pants/backend/cc/dependency_inference/rules.py index 7f0e251be39..b5b3243885a 100644 --- a/src/python/pants/backend/cc/dependency_inference/rules.py +++ b/src/python/pants/backend/cc/dependency_inference/rules.py @@ -4,9 +4,10 @@ import re from collections import defaultdict +from collections.abc import Iterable from dataclasses import dataclass from pathlib import PurePath -from typing import DefaultDict, Iterable +from typing import DefaultDict from pants.backend.cc.subsystems.cc_infer import CCInferSubsystem from pants.backend.cc.target_types import CCDependenciesField, CCSourceField diff --git a/src/python/pants/backend/cc/goals/tailor.py b/src/python/pants/backend/cc/goals/tailor.py index 27ce469274c..83f9b964b9a 100644 --- a/src/python/pants/backend/cc/goals/tailor.py +++ b/src/python/pants/backend/cc/goals/tailor.py @@ -3,8 +3,8 @@ from __future__ import annotations +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.cc.target_types import CC_FILE_EXTENSIONS, CCSourcesGeneratorTarget from pants.core.goals.tailor import ( diff --git a/src/python/pants/backend/cc/lint/clangformat/rules.py b/src/python/pants/backend/cc/lint/clangformat/rules.py index 54e52c3e697..ef4fb68b670 100644 --- a/src/python/pants/backend/cc/lint/clangformat/rules.py +++ b/src/python/pants/backend/cc/lint/clangformat/rules.py @@ -4,8 +4,8 @@ from __future__ import annotations import logging +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.cc.lint.clangformat.subsystem import ClangFormat from pants.backend.cc.target_types import CCSourceField diff --git a/src/python/pants/backend/cc/lint/clangformat/skip_field.py b/src/python/pants/backend/cc/lint/clangformat/skip_field.py index f10657cea81..ed9bb8aede4 100644 --- a/src/python/pants/backend/cc/lint/clangformat/skip_field.py +++ b/src/python/pants/backend/cc/lint/clangformat/skip_field.py @@ -3,7 +3,7 @@ from __future__ import annotations -from typing import Iterable +from collections.abc import Iterable from pants.backend.cc.target_types import CCSourcesGeneratorTarget, CCSourceTarget from pants.engine.rules import Rule diff --git a/src/python/pants/backend/cc/lint/clangformat/subsystem.py b/src/python/pants/backend/cc/lint/clangformat/subsystem.py index a27ee89e260..dbfa3a8d7bb 100644 --- a/src/python/pants/backend/cc/lint/clangformat/subsystem.py +++ b/src/python/pants/backend/cc/lint/clangformat/subsystem.py @@ -4,7 +4,7 @@ from __future__ import annotations import os -from typing import Iterable +from collections.abc import Iterable from pants.backend.python.subsystems.python_tool_base import PythonToolBase from pants.backend.python.target_types import ConsoleScript diff --git a/src/python/pants/backend/cc/subsystems/compiler.py b/src/python/pants/backend/cc/subsystems/compiler.py index fb054495412..681572fe249 100644 --- a/src/python/pants/backend/cc/subsystems/compiler.py +++ b/src/python/pants/backend/cc/subsystems/compiler.py @@ -4,7 +4,7 @@ from __future__ import annotations import logging -from typing import Iterable +from collections.abc import Iterable from pants.core.goals.resolves import ExportableTool from pants.core.util_rules.external_tool import TemplatedExternalTool diff --git a/src/python/pants/backend/cc/target_types.py b/src/python/pants/backend/cc/target_types.py index 2d1ec57db61..77d697e818f 100644 --- a/src/python/pants/backend/cc/target_types.py +++ b/src/python/pants/backend/cc/target_types.py @@ -3,9 +3,9 @@ from __future__ import annotations +from collections.abc import Iterable from dataclasses import dataclass from enum import Enum -from typing import Iterable from pants.engine.rules import Rule, collect_rules from pants.engine.target import ( diff --git a/src/python/pants/backend/cc/util_rules/toolchain.py b/src/python/pants/backend/cc/util_rules/toolchain.py index 04d81381a5b..c87b97ffc3c 100644 --- a/src/python/pants/backend/cc/util_rules/toolchain.py +++ b/src/python/pants/backend/cc/util_rules/toolchain.py @@ -5,8 +5,8 @@ import logging import os +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.cc.subsystems.compiler import CCSubsystem, ExternalCCSubsystem from pants.backend.cc.target_types import CCLanguage diff --git a/src/python/pants/backend/codegen/avro/java/rules.py b/src/python/pants/backend/codegen/avro/java/rules.py index d62a52b7b49..9a7152da351 100644 --- a/src/python/pants/backend/codegen/avro/java/rules.py +++ b/src/python/pants/backend/codegen/avro/java/rules.py @@ -3,9 +3,9 @@ from __future__ import annotations import os +from collections.abc import Iterable from dataclasses import dataclass from pathlib import PurePath -from typing import Iterable from pants.backend.codegen.avro.java.subsystem import AvroSubsystem from pants.backend.codegen.avro.target_types import ( diff --git a/src/python/pants/backend/codegen/avro/java/rules_integration_test.py b/src/python/pants/backend/codegen/avro/java/rules_integration_test.py index 328c10bd05f..ca6fb889351 100644 --- a/src/python/pants/backend/codegen/avro/java/rules_integration_test.py +++ b/src/python/pants/backend/codegen/avro/java/rules_integration_test.py @@ -2,8 +2,8 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). from __future__ import annotations +from collections.abc import Iterable from textwrap import dedent -from typing import Iterable import pytest diff --git a/src/python/pants/backend/codegen/protobuf/go/rules_integration_test.py b/src/python/pants/backend/codegen/protobuf/go/rules_integration_test.py index d41461d875e..39b24800dd0 100644 --- a/src/python/pants/backend/codegen/protobuf/go/rules_integration_test.py +++ b/src/python/pants/backend/codegen/protobuf/go/rules_integration_test.py @@ -2,8 +2,8 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). from __future__ import annotations +from collections.abc import Iterable from textwrap import dedent -from typing import Iterable import pytest diff --git a/src/python/pants/backend/codegen/protobuf/java/dependency_inference.py b/src/python/pants/backend/codegen/protobuf/java/dependency_inference.py index c27562ebb93..a1e9b363cad 100644 --- a/src/python/pants/backend/codegen/protobuf/java/dependency_inference.py +++ b/src/python/pants/backend/codegen/protobuf/java/dependency_inference.py @@ -3,7 +3,6 @@ from __future__ import annotations from dataclasses import dataclass -from typing import FrozenSet from pants.backend.codegen.protobuf.target_types import ( ProtobufDependenciesField, @@ -51,7 +50,7 @@ class ProtobufJavaRuntimeForResolveRequest: @dataclass(frozen=True) class ProtobufJavaRuntimeForResolve: - addresses: FrozenSet[Address] + addresses: frozenset[Address] @rule @@ -83,7 +82,7 @@ class ProtobufJavaGrpcRuntimeForResolveRequest: @dataclass(frozen=True) class ProtobufJavaGrpcRuntimeForResolve: - addresses: FrozenSet[Address] + addresses: frozenset[Address] @rule diff --git a/src/python/pants/backend/codegen/protobuf/jvm_symbol_mapper.py b/src/python/pants/backend/codegen/protobuf/jvm_symbol_mapper.py index ca1b0454d2e..26ef2fa5f74 100644 --- a/src/python/pants/backend/codegen/protobuf/jvm_symbol_mapper.py +++ b/src/python/pants/backend/codegen/protobuf/jvm_symbol_mapper.py @@ -5,8 +5,9 @@ import os import re from collections import defaultdict +from collections.abc import Mapping from dataclasses import dataclass -from typing import DefaultDict, Mapping +from typing import DefaultDict from pants.backend.codegen.protobuf.target_types import AllProtobufTargets, ProtobufSourceField from pants.engine.addresses import Address diff --git a/src/python/pants/backend/codegen/protobuf/protobuf_dependency_inference_test.py b/src/python/pants/backend/codegen/protobuf/protobuf_dependency_inference_test.py index 543eafc6cd1..537f2fbc8ff 100644 --- a/src/python/pants/backend/codegen/protobuf/protobuf_dependency_inference_test.py +++ b/src/python/pants/backend/codegen/protobuf/protobuf_dependency_inference_test.py @@ -2,7 +2,6 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). from textwrap import dedent -from typing import Set import pytest @@ -69,7 +68,7 @@ ), ], ) -def test_parse_proto_imports(file_content: str, expected: Set[str]) -> None: +def test_parse_proto_imports(file_content: str, expected: set[str]) -> None: assert set(parse_proto_imports(file_content)) == expected diff --git a/src/python/pants/backend/codegen/protobuf/scala/rules_integration_test.py b/src/python/pants/backend/codegen/protobuf/scala/rules_integration_test.py index 549eb4f8c5f..defd7cb6a3a 100644 --- a/src/python/pants/backend/codegen/protobuf/scala/rules_integration_test.py +++ b/src/python/pants/backend/codegen/protobuf/scala/rules_integration_test.py @@ -2,8 +2,8 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). from __future__ import annotations +from collections.abc import Iterable from textwrap import dedent -from typing import Iterable import pytest diff --git a/src/python/pants/backend/codegen/soap/java/dependency_inference.py b/src/python/pants/backend/codegen/soap/java/dependency_inference.py index 5e6dc661863..95bcd1dc623 100644 --- a/src/python/pants/backend/codegen/soap/java/dependency_inference.py +++ b/src/python/pants/backend/codegen/soap/java/dependency_inference.py @@ -3,7 +3,6 @@ from __future__ import annotations from dataclasses import dataclass -from typing import FrozenSet from pants.backend.codegen.soap.java.jaxws import JaxWsTools from pants.backend.codegen.soap.target_types import WsdlDependenciesField @@ -41,7 +40,7 @@ class JaxWSJavaRuntimeForResolveRequest: @dataclass(frozen=True) class JaxWSJavaRuntimeForResolve: - addresses: FrozenSet[Address] + addresses: frozenset[Address] @rule diff --git a/src/python/pants/backend/codegen/soap/java/rules_integration_test.py b/src/python/pants/backend/codegen/soap/java/rules_integration_test.py index 16036919876..b034b4ed9b8 100644 --- a/src/python/pants/backend/codegen/soap/java/rules_integration_test.py +++ b/src/python/pants/backend/codegen/soap/java/rules_integration_test.py @@ -4,8 +4,8 @@ from __future__ import annotations import textwrap +from collections.abc import Iterable from textwrap import dedent -from typing import Iterable import pytest diff --git a/src/python/pants/backend/codegen/soap/java/symbol_mapper.py b/src/python/pants/backend/codegen/soap/java/symbol_mapper.py index bdd7afe4612..05510d5e0f9 100644 --- a/src/python/pants/backend/codegen/soap/java/symbol_mapper.py +++ b/src/python/pants/backend/codegen/soap/java/symbol_mapper.py @@ -3,7 +3,8 @@ from __future__ import annotations from collections import defaultdict -from typing import DefaultDict, Mapping, Tuple +from collections.abc import Mapping +from typing import DefaultDict from pants.backend.codegen.soap.java.extra_fields import JavaPackageField from pants.backend.codegen.soap.target_types import AllWsdlTargets @@ -27,7 +28,7 @@ class FirstPartyWsdlJaxWsTargetsMappingRequest(FirstPartyMappingRequest): async def map_first_party_wsdl_jaxws_targets_to_symbols( _: FirstPartyWsdlJaxWsTargetsMappingRequest, wsdl_targets: AllWsdlTargets, jvm: JvmSubsystem ) -> SymbolMap: - package_mapping: DefaultDict[Tuple[_ResolveName, str], OrderedSet[Address]] = defaultdict( + package_mapping: DefaultDict[tuple[_ResolveName, str], OrderedSet[Address]] = defaultdict( OrderedSet ) for target in wsdl_targets: diff --git a/src/python/pants/backend/codegen/thrift/jvm_symbol_mapper.py b/src/python/pants/backend/codegen/thrift/jvm_symbol_mapper.py index 7db24587fdf..2e8a1de994f 100644 --- a/src/python/pants/backend/codegen/thrift/jvm_symbol_mapper.py +++ b/src/python/pants/backend/codegen/thrift/jvm_symbol_mapper.py @@ -3,8 +3,9 @@ from __future__ import annotations from collections import defaultdict +from collections.abc import Mapping from dataclasses import dataclass -from typing import DefaultDict, Mapping +from typing import DefaultDict from pants.backend.codegen.thrift.target_types import AllThriftTargets, ThriftSourceField from pants.backend.codegen.thrift.thrift_parser import ParsedThrift, ParsedThriftRequest diff --git a/src/python/pants/backend/codegen/thrift/thrift_parser.py b/src/python/pants/backend/codegen/thrift/thrift_parser.py index 1216dc417e2..7409b7f0db8 100644 --- a/src/python/pants/backend/codegen/thrift/thrift_parser.py +++ b/src/python/pants/backend/codegen/thrift/thrift_parser.py @@ -4,8 +4,8 @@ from __future__ import annotations import re +from collections.abc import Mapping from dataclasses import dataclass -from typing import Mapping from pants.backend.codegen.thrift.target_types import ThriftSourceField from pants.engine.engine_aware import EngineAwareParameter diff --git a/src/python/pants/backend/codegen/thrift/thrift_parser_test.py b/src/python/pants/backend/codegen/thrift/thrift_parser_test.py index 6ecfe500c70..91a243fbb82 100644 --- a/src/python/pants/backend/codegen/thrift/thrift_parser_test.py +++ b/src/python/pants/backend/codegen/thrift/thrift_parser_test.py @@ -3,8 +3,8 @@ from __future__ import annotations +from collections.abc import Iterable from textwrap import dedent -from typing import Iterable import pytest diff --git a/src/python/pants/backend/cue/goals/fix.py b/src/python/pants/backend/cue/goals/fix.py index 1e1f83fab2e..4b268898c73 100644 --- a/src/python/pants/backend/cue/goals/fix.py +++ b/src/python/pants/backend/cue/goals/fix.py @@ -3,7 +3,7 @@ from __future__ import annotations -from typing import Iterable +from collections.abc import Iterable from pants.backend.cue import subsystem from pants.backend.cue.rules import _run_cue diff --git a/src/python/pants/backend/cue/goals/fix_test.py b/src/python/pants/backend/cue/goals/fix_test.py index badabc8ad9b..2acad9b32b0 100644 --- a/src/python/pants/backend/cue/goals/fix_test.py +++ b/src/python/pants/backend/cue/goals/fix_test.py @@ -3,8 +3,8 @@ from __future__ import annotations from collections import namedtuple +from collections.abc import Iterable from textwrap import dedent -from typing import Iterable import pytest diff --git a/src/python/pants/backend/cue/goals/lint.py b/src/python/pants/backend/cue/goals/lint.py index 8256d5d2830..05e0477a7fb 100644 --- a/src/python/pants/backend/cue/goals/lint.py +++ b/src/python/pants/backend/cue/goals/lint.py @@ -3,7 +3,8 @@ from __future__ import annotations -from typing import Any, Iterable +from collections.abc import Iterable +from typing import Any from pants.backend.cue import subsystem from pants.backend.cue.rules import _run_cue diff --git a/src/python/pants/backend/cue/goals/lint_test.py b/src/python/pants/backend/cue/goals/lint_test.py index fdf3d7598b2..12d93b6e6e9 100644 --- a/src/python/pants/backend/cue/goals/lint_test.py +++ b/src/python/pants/backend/cue/goals/lint_test.py @@ -3,8 +3,9 @@ from __future__ import annotations from collections import namedtuple +from collections.abc import Iterable from textwrap import dedent -from typing import Any, Iterable +from typing import Any import pytest diff --git a/src/python/pants/backend/debian/rules.py b/src/python/pants/backend/debian/rules.py index ca443362bf4..f9d2c258d10 100644 --- a/src/python/pants/backend/debian/rules.py +++ b/src/python/pants/backend/debian/rules.py @@ -3,9 +3,9 @@ from __future__ import annotations +from collections.abc import Iterable from dataclasses import dataclass from pathlib import PurePath -from typing import Iterable from pants.backend.debian.target_types import ( DebianInstallPrefix, diff --git a/src/python/pants/backend/debian/target_types.py b/src/python/pants/backend/debian/target_types.py index f1ee118ae00..a8fcde2d353 100644 --- a/src/python/pants/backend/debian/target_types.py +++ b/src/python/pants/backend/debian/target_types.py @@ -1,7 +1,7 @@ # Copyright 2021 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). +from collections.abc import Sequence from pathlib import PurePath -from typing import Sequence from pants.core.goals.package import OutputPathField from pants.engine.target import ( diff --git a/src/python/pants/backend/debian/target_types_test.py b/src/python/pants/backend/debian/target_types_test.py index a0bdf22929f..08e4c7e8c6c 100644 --- a/src/python/pants/backend/debian/target_types_test.py +++ b/src/python/pants/backend/debian/target_types_test.py @@ -1,6 +1,6 @@ # Copyright 2022 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). -from typing import Iterable, Type +from collections.abc import Iterable import pytest @@ -41,7 +41,7 @@ def test_sources_expected_num_files(sources_rule_runner: RuleRunner) -> None: ) ) - def hydrate(sources_cls: Type[DebianSources], sources: Iterable[str]) -> HydratedSources: + def hydrate(sources_cls: type[DebianSources], sources: Iterable[str]) -> HydratedSources: return sources_rule_runner.request( HydratedSources, [ diff --git a/src/python/pants/backend/docker/goals/package_image.py b/src/python/pants/backend/docker/goals/package_image.py index 2418009f57a..b17530a03a8 100644 --- a/src/python/pants/backend/docker/goals/package_image.py +++ b/src/python/pants/backend/docker/goals/package_image.py @@ -6,10 +6,11 @@ import logging import os import re +from collections.abc import Iterator from dataclasses import asdict, dataclass from functools import partial from itertools import chain -from typing import Iterator, Literal, cast +from typing import Literal, cast # Re-exporting BuiltDockerImage here, as it has its natural home here, but has moved out to resolve # a dependency cycle from docker_build_context. diff --git a/src/python/pants/backend/docker/goals/package_image_test.py b/src/python/pants/backend/docker/goals/package_image_test.py index af609234196..1be3117a03a 100644 --- a/src/python/pants/backend/docker/goals/package_image_test.py +++ b/src/python/pants/backend/docker/goals/package_image_test.py @@ -7,8 +7,9 @@ import logging import os.path from collections import namedtuple +from collections.abc import Callable from textwrap import dedent -from typing import Callable, ContextManager, cast +from typing import ContextManager, cast import pytest diff --git a/src/python/pants/backend/docker/goals/publish_test.py b/src/python/pants/backend/docker/goals/publish_test.py index 3ed8fcccbfb..0f8b69a8f1e 100644 --- a/src/python/pants/backend/docker/goals/publish_test.py +++ b/src/python/pants/backend/docker/goals/publish_test.py @@ -3,7 +3,8 @@ from __future__ import annotations -from typing import Callable, cast +from collections.abc import Callable +from typing import cast import pytest diff --git a/src/python/pants/backend/docker/registries.py b/src/python/pants/backend/docker/registries.py index ad734469b2f..4a5a861fc2d 100644 --- a/src/python/pants/backend/docker/registries.py +++ b/src/python/pants/backend/docker/registries.py @@ -3,8 +3,9 @@ from __future__ import annotations +from collections.abc import Iterator from dataclasses import dataclass -from typing import Any, Iterator +from typing import Any from pants.util.frozendict import FrozenDict from pants.util.strutil import softwrap diff --git a/src/python/pants/backend/docker/subsystems/dockerfile_wrapper_script.py b/src/python/pants/backend/docker/subsystems/dockerfile_wrapper_script.py index 3dbce02acf9..f1020d2ef95 100644 --- a/src/python/pants/backend/docker/subsystems/dockerfile_wrapper_script.py +++ b/src/python/pants/backend/docker/subsystems/dockerfile_wrapper_script.py @@ -6,9 +6,9 @@ import json import re import sys +from collections.abc import Iterator from dataclasses import asdict, dataclass from itertools import chain -from typing import Iterator # # Note: This file is used as a pex entry point in the execution sandbox. diff --git a/src/python/pants/backend/docker/target_types.py b/src/python/pants/backend/docker/target_types.py index 6b9b0cf5910..19c57c2c32f 100644 --- a/src/python/pants/backend/docker/target_types.py +++ b/src/python/pants/backend/docker/target_types.py @@ -6,10 +6,9 @@ import os import re from abc import ABC, abstractmethod +from collections.abc import Callable, Iterator from dataclasses import dataclass -from typing import Callable, ClassVar, Iterator, Optional, cast - -from typing_extensions import final +from typing import ClassVar, cast, final from pants.backend.docker.registries import ALL_DEFAULT_REGISTRIES from pants.backend.docker.subsystems.docker_options import DockerOptions @@ -81,7 +80,7 @@ class DockerImageContextRootField(StringField): ) @classmethod - def compute_value(cls, raw_value: Optional[str], address: Address) -> Optional[str]: + def compute_value(cls, raw_value: str | None, address: Address) -> str | None: value_or_default = super().compute_value(raw_value, address=address) if isinstance(value_or_default, str) and value_or_default.startswith("/"): val = value_or_default.strip("/") diff --git a/src/python/pants/backend/docker/util_rules/docker_binary.py b/src/python/pants/backend/docker/util_rules/docker_binary.py index 2593b154c0d..2291e05e3c3 100644 --- a/src/python/pants/backend/docker/util_rules/docker_binary.py +++ b/src/python/pants/backend/docker/util_rules/docker_binary.py @@ -5,8 +5,9 @@ import logging import os +from collections.abc import Mapping, Sequence from dataclasses import dataclass -from typing import Mapping, Sequence, cast +from typing import cast from pants.backend.docker.subsystems.docker_options import DockerOptions from pants.backend.docker.util_rules.docker_build_args import DockerBuildArgs diff --git a/src/python/pants/backend/docker/util_rules/docker_build_args.py b/src/python/pants/backend/docker/util_rules/docker_build_args.py index 40adbcc26a2..ed4d02e3700 100644 --- a/src/python/pants/backend/docker/util_rules/docker_build_args.py +++ b/src/python/pants/backend/docker/util_rules/docker_build_args.py @@ -4,7 +4,6 @@ from __future__ import annotations from dataclasses import dataclass -from typing import Union from pants.backend.docker.subsystems.docker_options import DockerOptions from pants.backend.docker.target_types import DockerImageBuildArgsField @@ -29,7 +28,7 @@ def with_overrides(self, overrides: DockerBuildArgs) -> DockerBuildArgs: {k: overrides_dict.get(k, v) for k, v in self.to_dict().items()} ) - def extended(self, more: Union[DockerBuildArgs, list[str]]) -> DockerBuildArgs: + def extended(self, more: DockerBuildArgs | list[str]) -> DockerBuildArgs: """Create a new DockerBuildArgs out of this and a list of strs to add.""" if isinstance(more, DockerBuildArgs): return DockerBuildArgs.from_strings(*self, *more) diff --git a/src/python/pants/backend/docker/util_rules/docker_build_context.py b/src/python/pants/backend/docker/util_rules/docker_build_context.py index eb83462ac9b..6774d4bccfc 100644 --- a/src/python/pants/backend/docker/util_rules/docker_build_context.py +++ b/src/python/pants/backend/docker/util_rules/docker_build_context.py @@ -7,8 +7,8 @@ import re import shlex from abc import ABC +from collections.abc import Iterable, Mapping from dataclasses import dataclass -from typing import Iterable, Mapping from pants.backend.docker.package_types import BuiltDockerImage from pants.backend.docker.subsystems.dockerfile_parser import DockerfileInfo, DockerfileInfoRequest diff --git a/src/python/pants/backend/docker/util_rules/docker_build_env.py b/src/python/pants/backend/docker/util_rules/docker_build_env.py index ea3dc3c5b09..c5af8ad14be 100644 --- a/src/python/pants/backend/docker/util_rules/docker_build_env.py +++ b/src/python/pants/backend/docker/util_rules/docker_build_env.py @@ -4,8 +4,8 @@ from __future__ import annotations import logging +from collections.abc import Mapping from dataclasses import dataclass -from typing import Mapping from pants.backend.docker.subsystems.docker_options import DockerOptions from pants.backend.docker.util_rules.docker_build_args import ( diff --git a/src/python/pants/backend/docker/util_rules/dockerfile_test.py b/src/python/pants/backend/docker/util_rules/dockerfile_test.py index 05c3bda15bf..f14b714330a 100644 --- a/src/python/pants/backend/docker/util_rules/dockerfile_test.py +++ b/src/python/pants/backend/docker/util_rules/dockerfile_test.py @@ -3,8 +3,9 @@ # from __future__ import annotations +from collections.abc import Mapping from textwrap import dedent -from typing import Any, Mapping +from typing import Any import pytest diff --git a/src/python/pants/backend/docker/utils.py b/src/python/pants/backend/docker/utils.py index 2603679b662..69b60f17892 100644 --- a/src/python/pants/backend/docker/utils.py +++ b/src/python/pants/backend/docker/utils.py @@ -6,10 +6,9 @@ import difflib import os.path import re +from collections.abc import Callable, Iterable, Iterator, Sequence from fnmatch import fnmatch -from typing import Callable, Iterable, Iterator, Sequence, TypeVar - -from typing_extensions import Self +from typing import Self, TypeVar from pants.help.maybe_color import MaybeColor from pants.util.ordered_set import FrozenOrderedSet diff --git a/src/python/pants/backend/experimental/cc/lint/clangformat/register.py b/src/python/pants/backend/experimental/cc/lint/clangformat/register.py index ae3cf36579a..77985ecd3d2 100644 --- a/src/python/pants/backend/experimental/cc/lint/clangformat/register.py +++ b/src/python/pants/backend/experimental/cc/lint/clangformat/register.py @@ -8,7 +8,7 @@ from __future__ import annotations -from typing import Iterable +from collections.abc import Iterable from pants.backend.cc.lint.clangformat import rules as clangformat_rules from pants.backend.cc.lint.clangformat import skip_field, subsystem diff --git a/src/python/pants/backend/experimental/javascript/lint/prettier/register.py b/src/python/pants/backend/experimental/javascript/lint/prettier/register.py index 273d4c390a6..96fc99cf763 100644 --- a/src/python/pants/backend/experimental/javascript/lint/prettier/register.py +++ b/src/python/pants/backend/experimental/javascript/lint/prettier/register.py @@ -8,7 +8,7 @@ from __future__ import annotations -from typing import Iterable +from collections.abc import Iterable from pants.backend.javascript.lint.prettier import rules as prettier_rules from pants.backend.javascript.lint.prettier import skip_field diff --git a/src/python/pants/backend/experimental/javascript/register.py b/src/python/pants/backend/experimental/javascript/register.py index 87c0abea5aa..467e884a64c 100644 --- a/src/python/pants/backend/experimental/javascript/register.py +++ b/src/python/pants/backend/experimental/javascript/register.py @@ -3,7 +3,7 @@ from __future__ import annotations -from typing import Iterable +from collections.abc import Iterable from pants.backend.javascript import package_json from pants.backend.javascript.goals import export, lockfile, tailor, test diff --git a/src/python/pants/backend/experimental/openapi/register.py b/src/python/pants/backend/experimental/openapi/register.py index 3db00a8d9b5..cda8a6f69a7 100644 --- a/src/python/pants/backend/experimental/openapi/register.py +++ b/src/python/pants/backend/experimental/openapi/register.py @@ -3,7 +3,7 @@ from __future__ import annotations -from typing import Iterable +from collections.abc import Iterable from pants.backend.openapi import dependency_inference from pants.backend.openapi.goals import tailor diff --git a/src/python/pants/backend/experimental/python/typecheck/pyright/register.py b/src/python/pants/backend/experimental/python/typecheck/pyright/register.py index 2f3c7c9a1e7..466bcaefd99 100644 --- a/src/python/pants/backend/experimental/python/typecheck/pyright/register.py +++ b/src/python/pants/backend/experimental/python/typecheck/pyright/register.py @@ -8,7 +8,7 @@ from __future__ import annotations -from typing import Iterable +from collections.abc import Iterable from pants.backend.javascript.subsystems import nodejs from pants.backend.python.typecheck.pyright import rules as pyright_rules diff --git a/src/python/pants/backend/experimental/swift/register.py b/src/python/pants/backend/experimental/swift/register.py index 8c02cd655a4..de4d6e5419a 100644 --- a/src/python/pants/backend/experimental/swift/register.py +++ b/src/python/pants/backend/experimental/swift/register.py @@ -3,7 +3,7 @@ from __future__ import annotations -from typing import Iterable +from collections.abc import Iterable from pants.backend.swift.goals import tailor from pants.backend.swift.target_types import SwiftSourcesGeneratorTarget, SwiftSourceTarget diff --git a/src/python/pants/backend/experimental/tools/semgrep/register.py b/src/python/pants/backend/experimental/tools/semgrep/register.py index 589cf36713b..2936e61d3eb 100644 --- a/src/python/pants/backend/experimental/tools/semgrep/register.py +++ b/src/python/pants/backend/experimental/tools/semgrep/register.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Iterable +from collections.abc import Iterable from pants.backend.python.goals import lockfile as python_lockfile from pants.backend.tools.semgrep import rules as semgrep_rules diff --git a/src/python/pants/backend/experimental/tools/yamllint/register.py b/src/python/pants/backend/experimental/tools/yamllint/register.py index c0cb52cc2ac..4b66a14f6eb 100644 --- a/src/python/pants/backend/experimental/tools/yamllint/register.py +++ b/src/python/pants/backend/experimental/tools/yamllint/register.py @@ -8,7 +8,7 @@ from __future__ import annotations -from typing import Iterable +from collections.abc import Iterable from pants.backend.python.goals import lockfile as python_lockfile from pants.backend.tools.yamllint import rules as yamllint_rules diff --git a/src/python/pants/backend/experimental/typescript/register.py b/src/python/pants/backend/experimental/typescript/register.py index a01befa2ddf..8a7bc5d1725 100644 --- a/src/python/pants/backend/experimental/typescript/register.py +++ b/src/python/pants/backend/experimental/typescript/register.py @@ -1,6 +1,6 @@ # Copyright 2023 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). -from typing import Iterable, Union +from collections.abc import Iterable from pants.backend.tsx.goals import tailor as tsx_tailor from pants.backend.tsx.target_types import ( @@ -35,7 +35,7 @@ def target_types() -> Iterable[type[Target]]: ) -def rules() -> Iterable[Union[Rule, UnionRule]]: +def rules() -> Iterable[Rule | UnionRule]: return ( *dependency_inference_rules.rules(), *tailor.rules(), diff --git a/src/python/pants/backend/go/go_sources/load_go_binary.py b/src/python/pants/backend/go/go_sources/load_go_binary.py index fc4327baa71..0e0ba1f725f 100644 --- a/src/python/pants/backend/go/go_sources/load_go_binary.py +++ b/src/python/pants/backend/go/go_sources/load_go_binary.py @@ -4,8 +4,8 @@ from __future__ import annotations import re +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.go.util_rules.build_opts import GoBuildOptions from pants.backend.go.util_rules.build_pkg import BuildGoPackageRequest, BuiltGoPackage diff --git a/src/python/pants/backend/go/goals/generate.py b/src/python/pants/backend/go/goals/generate.py index 140a61072aa..49aa18b61b7 100644 --- a/src/python/pants/backend/go/goals/generate.py +++ b/src/python/pants/backend/go/goals/generate.py @@ -7,8 +7,8 @@ import re import shlex import string +from collections.abc import Mapping from dataclasses import dataclass -from typing import Mapping from pants.backend.go.target_types import GoPackageSourcesField from pants.backend.go.util_rules import first_party_pkg, goroot, sdk diff --git a/src/python/pants/backend/go/goals/test.py b/src/python/pants/backend/go/goals/test.py index ebe258e042d..310ee9e5a96 100644 --- a/src/python/pants/backend/go/goals/test.py +++ b/src/python/pants/backend/go/goals/test.py @@ -8,8 +8,9 @@ import logging import os from collections import deque +from collections.abc import Iterable, Sequence from dataclasses import dataclass -from typing import Any, Iterable, Sequence +from typing import Any from pants.backend.go.dependency_inference import GoModuleImportPathsMapping from pants.backend.go.subsystems.gotest import GoTestSubsystem diff --git a/src/python/pants/backend/go/target_types.py b/src/python/pants/backend/go/target_types.py index 7b28c62b3be..12a64fec30a 100644 --- a/src/python/pants/backend/go/target_types.py +++ b/src/python/pants/backend/go/target_types.py @@ -4,7 +4,7 @@ from __future__ import annotations import os -from typing import Iterable, Optional, Sequence, Tuple +from collections.abc import Iterable, Sequence from pants.core.goals.package import OutputPathField from pants.core.goals.run import RestartableField @@ -359,8 +359,8 @@ class GoPackageSourcesField(MultipleSourcesField): @classmethod def compute_value( - cls, raw_value: Optional[Iterable[str]], address: Address - ) -> Optional[Tuple[str, ...]]: + cls, raw_value: Iterable[str] | None, address: Address + ) -> tuple[str, ...] | None: value_or_default = super().compute_value(raw_value, address) if not value_or_default: raise InvalidFieldException( diff --git a/src/python/pants/backend/go/testutil.py b/src/python/pants/backend/go/testutil.py index 73fd2782b41..1c58d4d3d59 100644 --- a/src/python/pants/backend/go/testutil.py +++ b/src/python/pants/backend/go/testutil.py @@ -8,12 +8,12 @@ import io import json import zipfile +from collections.abc import Iterable from textwrap import dedent # noqa: PNT20 -from typing import Dict, Iterable, Tuple # Implements hashing algorithm from https://cs.opensource.google/go/x/mod/+/refs/tags/v0.5.0:sumdb/dirhash/hash.go. -def compute_module_hash(files: Iterable[Tuple[str, str]]) -> str: +def compute_module_hash(files: Iterable[tuple[str, str]]) -> str: """Compute a module hash that can be used in go.sum for an emulated remote package.""" sorted_files = sorted(files, key=lambda x: x[0]) summary = "" @@ -27,8 +27,8 @@ def compute_module_hash(files: Iterable[Tuple[str, str]]) -> str: def gen_module_gomodproxy( - version: str, import_path: str, files: Iterable[Tuple[str, str]] -) -> Dict[str, str | bytes]: + version: str, import_path: str, files: Iterable[tuple[str, str]] +) -> dict[str, str | bytes]: go_mod_content = dedent( f"""\ module {import_path} diff --git a/src/python/pants/backend/go/util_rules/assembly.py b/src/python/pants/backend/go/util_rules/assembly.py index 137accd583e..e81b1b91a89 100644 --- a/src/python/pants/backend/go/util_rules/assembly.py +++ b/src/python/pants/backend/go/util_rules/assembly.py @@ -4,9 +4,9 @@ from __future__ import annotations import os.path +from collections.abc import Iterable from dataclasses import dataclass from pathlib import PurePath -from typing import Iterable from pants.backend.go.util_rules.goroot import GoRoot from pants.backend.go.util_rules.sdk import GoSdkProcess, GoSdkToolIDRequest, GoSdkToolIDResult diff --git a/src/python/pants/backend/go/util_rules/build_opts.py b/src/python/pants/backend/go/util_rules/build_opts.py index 7c9ce2b827a..1583c60d0f6 100644 --- a/src/python/pants/backend/go/util_rules/build_opts.py +++ b/src/python/pants/backend/go/util_rules/build_opts.py @@ -3,8 +3,8 @@ from __future__ import annotations import logging +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.go.subsystems.golang import GolangSubsystem from pants.backend.go.subsystems.gotest import GoTestSubsystem diff --git a/src/python/pants/backend/go/util_rules/build_opts_test.py b/src/python/pants/backend/go/util_rules/build_opts_test.py index 9a1450cb365..6ee080154e4 100644 --- a/src/python/pants/backend/go/util_rules/build_opts_test.py +++ b/src/python/pants/backend/go/util_rules/build_opts_test.py @@ -5,8 +5,8 @@ import os import pprint import subprocess +from collections.abc import Callable, Iterable from textwrap import dedent -from typing import Callable, Iterable import pytest diff --git a/src/python/pants/backend/go/util_rules/build_pkg.py b/src/python/pants/backend/go/util_rules/build_pkg.py index 91ff26fbef3..ccd207960ca 100644 --- a/src/python/pants/backend/go/util_rules/build_pkg.py +++ b/src/python/pants/backend/go/util_rules/build_pkg.py @@ -6,9 +6,9 @@ import hashlib import os.path from collections import deque +from collections.abc import Iterable, Mapping from dataclasses import dataclass from pathlib import PurePath -from typing import Iterable, Mapping from pants.backend.go.util_rules import cgo, coverage from pants.backend.go.util_rules.assembly import ( diff --git a/src/python/pants/backend/go/util_rules/build_pkg_target.py b/src/python/pants/backend/go/util_rules/build_pkg_target.py index 62964ac5d63..3d345ebf6e3 100644 --- a/src/python/pants/backend/go/util_rules/build_pkg_target.py +++ b/src/python/pants/backend/go/util_rules/build_pkg_target.py @@ -6,7 +6,7 @@ import dataclasses import json from dataclasses import dataclass -from typing import ClassVar, Type, cast +from typing import ClassVar, cast from pants.backend.go.dependency_inference import GoModuleImportPathsMapping from pants.backend.go.go_sources.load_go_binary import LoadedGoBinary, LoadedGoBinaryRequest @@ -140,7 +140,7 @@ def maybe_get_codegen_request_type( if not tgt.has_field(SourcesField): return None generate_request_types = cast( - FrozenOrderedSet[Type[GoCodegenBuildRequest]], union_membership.get(GoCodegenBuildRequest) + FrozenOrderedSet[type[GoCodegenBuildRequest]], union_membership.get(GoCodegenBuildRequest) ) sources_field = tgt[SourcesField] relevant_requests = [ diff --git a/src/python/pants/backend/go/util_rules/cgo.py b/src/python/pants/backend/go/util_rules/cgo.py index c5db9d0ed64..e016bd08417 100644 --- a/src/python/pants/backend/go/util_rules/cgo.py +++ b/src/python/pants/backend/go/util_rules/cgo.py @@ -7,9 +7,9 @@ import os import shlex import textwrap +from collections.abc import Iterable from dataclasses import dataclass from pathlib import PurePath -from typing import Iterable from pants.backend.go.subsystems.golang import GolangSubsystem from pants.backend.go.util_rules import cgo_binaries, cgo_pkgconfig diff --git a/src/python/pants/backend/go/util_rules/cgo_security.py b/src/python/pants/backend/go/util_rules/cgo_security.py index 62f6a9f7255..816555ca739 100644 --- a/src/python/pants/backend/go/util_rules/cgo_security.py +++ b/src/python/pants/backend/go/util_rules/cgo_security.py @@ -4,7 +4,7 @@ import re import string -from typing import Iterable, Sequence +from collections.abc import Iterable, Sequence from pants.util.memo import memoized diff --git a/src/python/pants/backend/go/util_rules/cgo_test.py b/src/python/pants/backend/go/util_rules/cgo_test.py index 5840be2ae0f..244d461de4a 100644 --- a/src/python/pants/backend/go/util_rules/cgo_test.py +++ b/src/python/pants/backend/go/util_rules/cgo_test.py @@ -4,9 +4,9 @@ import os import subprocess +from collections.abc import Iterable from pathlib import Path from textwrap import dedent -from typing import Iterable import pytest diff --git a/src/python/pants/backend/go/util_rules/coverage_html.py b/src/python/pants/backend/go/util_rules/coverage_html.py index 2ad2a7a7246..86147cd7675 100644 --- a/src/python/pants/backend/go/util_rules/coverage_html.py +++ b/src/python/pants/backend/go/util_rules/coverage_html.py @@ -4,9 +4,9 @@ import io import math +from collections.abc import Sequence from dataclasses import dataclass from pathlib import PurePath -from typing import Sequence import chevron diff --git a/src/python/pants/backend/go/util_rules/embedcfg.py b/src/python/pants/backend/go/util_rules/embedcfg.py index d2ed6cc9388..9441cacac28 100644 --- a/src/python/pants/backend/go/util_rules/embedcfg.py +++ b/src/python/pants/backend/go/util_rules/embedcfg.py @@ -4,8 +4,9 @@ from __future__ import annotations import json +from collections.abc import Iterable, Mapping from dataclasses import dataclass -from typing import Any, Iterable, Mapping +from typing import Any from pants.util.frozendict import FrozenDict from pants.util.strutil import strip_prefix diff --git a/src/python/pants/backend/go/util_rules/go_bootstrap.py b/src/python/pants/backend/go/util_rules/go_bootstrap.py index c7c415b093d..862f524421f 100644 --- a/src/python/pants/backend/go/util_rules/go_bootstrap.py +++ b/src/python/pants/backend/go/util_rules/go_bootstrap.py @@ -3,8 +3,8 @@ from __future__ import annotations import logging +from collections.abc import Collection from dataclasses import dataclass -from typing import Collection from pants.backend.go.subsystems.golang import GolangSubsystem from pants.core.util_rules import asdf, search_paths diff --git a/src/python/pants/backend/go/util_rules/pkg_pattern.py b/src/python/pants/backend/go/util_rules/pkg_pattern.py index 980ccef5bef..5e518ac40ae 100644 --- a/src/python/pants/backend/go/util_rules/pkg_pattern.py +++ b/src/python/pants/backend/go/util_rules/pkg_pattern.py @@ -3,7 +3,7 @@ from __future__ import annotations import re -from typing import Callable +from collections.abc import Callable # Adapted from Go toolchain: # https://github.com/golang/go/blob/6a70292d1cb3464e5b2c2c03341e5148730a1889/src/cmd/internal/pkgpattern/pkgpattern.go diff --git a/src/python/pants/backend/go/util_rules/pkg_pattern_test.py b/src/python/pants/backend/go/util_rules/pkg_pattern_test.py index 4058209fb4f..d096a8d7bec 100644 --- a/src/python/pants/backend/go/util_rules/pkg_pattern_test.py +++ b/src/python/pants/backend/go/util_rules/pkg_pattern_test.py @@ -2,7 +2,7 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). from __future__ import annotations -from typing import Callable +from collections.abc import Callable from pants.backend.go.util_rules.pkg_pattern import match_pattern, match_simple_pattern diff --git a/src/python/pants/backend/go/util_rules/sdk.py b/src/python/pants/backend/go/util_rules/sdk.py index 45a566654af..bf46eebe3e8 100644 --- a/src/python/pants/backend/go/util_rules/sdk.py +++ b/src/python/pants/backend/go/util_rules/sdk.py @@ -4,8 +4,8 @@ from __future__ import annotations import textwrap +from collections.abc import Iterable, Mapping from dataclasses import dataclass -from typing import Iterable, Mapping from pants.backend.go.subsystems.golang import GolangSubsystem from pants.backend.go.util_rules import goroot diff --git a/src/python/pants/backend/go/util_rules/testutil.py b/src/python/pants/backend/go/util_rules/testutil.py index de796d19b9a..d1a5af121eb 100644 --- a/src/python/pants/backend/go/util_rules/testutil.py +++ b/src/python/pants/backend/go/util_rules/testutil.py @@ -1,8 +1,8 @@ # Copyright 2023 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). import json +from collections.abc import Mapping from textwrap import dedent # noqa: PNT20 -from typing import Mapping EXPECTED_VERSION = "1.17" EXPECTED_VERSION_NEXT_RELEASE = "1.18" diff --git a/src/python/pants/backend/go/util_rules/vendor.py b/src/python/pants/backend/go/util_rules/vendor.py index c22a84c9662..c174440b80c 100644 --- a/src/python/pants/backend/go/util_rules/vendor.py +++ b/src/python/pants/backend/go/util_rules/vendor.py @@ -4,8 +4,8 @@ import json import logging +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.go.go_sources import load_go_binary from pants.backend.go.go_sources.load_go_binary import LoadedGoBinary, LoadedGoBinaryRequest diff --git a/src/python/pants/backend/google_cloud_function/python/target_types.py b/src/python/pants/backend/google_cloud_function/python/target_types.py index d41268a3db0..c2261ee1ebf 100644 --- a/src/python/pants/backend/google_cloud_function/python/target_types.py +++ b/src/python/pants/backend/google_cloud_function/python/target_types.py @@ -3,7 +3,8 @@ import re from enum import Enum -from typing import Match, Optional, Tuple, cast +from re import Match +from typing import cast from pants.backend.python.target_types import PexCompletePlatformsField, PythonResolveField from pants.backend.python.util_rules.faas import ( @@ -56,7 +57,7 @@ class PythonGoogleCloudFunctionRuntimes(Enum): PYTHON_311 = "python311" PYTHON_312 = "python312" - def to_interpreter_version(self) -> Tuple[int, int]: + def to_interpreter_version(self) -> tuple[int, int]: """Returns the Python version implied by the runtime, as (major, minor).""" mo = cast(Match, re.match(PYTHON_RUNTIME_REGEX, self.value)) return int(mo.group("major")), int(mo.group("minor")) @@ -115,7 +116,7 @@ class PythonGoogleCloudFunctionRuntime(PythonFaaSRuntimeField): ) @classmethod - def compute_value(cls, raw_value: Optional[str], address: Address) -> Optional[str]: + def compute_value(cls, raw_value: str | None, address: Address) -> str | None: value = super().compute_value(raw_value, address) if value is None: return None @@ -126,7 +127,7 @@ def compute_value(cls, raw_value: Optional[str], address: Address) -> Optional[s ) return value - def to_interpreter_version(self) -> Optional[Tuple[int, int]]: + def to_interpreter_version(self) -> tuple[int, int] | None: """Returns the Python version implied by the runtime, as (major, minor).""" if self.value is None: return None diff --git a/src/python/pants/backend/helm/check/kubeconform/deployment_test.py b/src/python/pants/backend/helm/check/kubeconform/deployment_test.py index 94cac0c32d9..9c9f5e7faac 100644 --- a/src/python/pants/backend/helm/check/kubeconform/deployment_test.py +++ b/src/python/pants/backend/helm/check/kubeconform/deployment_test.py @@ -3,8 +3,8 @@ from __future__ import annotations +from collections.abc import Iterable from textwrap import dedent -from typing import Iterable import pytest diff --git a/src/python/pants/backend/helm/check/kubeconform/extra_fields.py b/src/python/pants/backend/helm/check/kubeconform/extra_fields.py index b5d93acb065..c09198d1a3e 100644 --- a/src/python/pants/backend/helm/check/kubeconform/extra_fields.py +++ b/src/python/pants/backend/helm/check/kubeconform/extra_fields.py @@ -5,7 +5,6 @@ from abc import ABCMeta from dataclasses import dataclass -from typing import Type from pants.backend.helm.target_types import HelmChartTarget, HelmDeploymentTarget from pants.engine.target import ( @@ -77,8 +76,8 @@ def opt_out(cls, target: Target) -> bool: return target[KubeconformSkipField].value -_HELM_TARGET_TYPES: list[Type[Target]] = [HelmChartTarget, HelmDeploymentTarget] -_KUBECONFORM_COMMON_FIELD_TYPES: list[Type[Field]] = [ +_HELM_TARGET_TYPES: list[type[Target]] = [HelmChartTarget, HelmDeploymentTarget] +_KUBECONFORM_COMMON_FIELD_TYPES: list[type[Field]] = [ KubeconformSkipField, KubeconformIgnoreSourcesField, KubeconformIgnoreMissingSchemasField, diff --git a/src/python/pants/backend/helm/dependency_inference/chart.py b/src/python/pants/backend/helm/dependency_inference/chart.py index 716f6249a30..ea920dbd7d6 100644 --- a/src/python/pants/backend/helm/dependency_inference/chart.py +++ b/src/python/pants/backend/helm/dependency_inference/chart.py @@ -5,8 +5,8 @@ import logging import os +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.helm.resolve import artifacts from pants.backend.helm.resolve.artifacts import ThirdPartyHelmArtifactMapping diff --git a/src/python/pants/backend/helm/dependency_inference/unittest.py b/src/python/pants/backend/helm/dependency_inference/unittest.py index f1f653f4b2e..f4b9182fa62 100644 --- a/src/python/pants/backend/helm/dependency_inference/unittest.py +++ b/src/python/pants/backend/helm/dependency_inference/unittest.py @@ -3,9 +3,9 @@ import logging import os +from collections.abc import Sequence from dataclasses import dataclass from pathlib import PurePath -from typing import Sequence from pants.backend.helm.goals.tailor import _SNAPSHOT_FOLDER_NAME, _TESTS_FOLDER_NAME from pants.backend.helm.target_types import AllHelmChartTargets, HelmUnitTestDependenciesField diff --git a/src/python/pants/backend/helm/goals/deploy_test.py b/src/python/pants/backend/helm/goals/deploy_test.py index db409bf5cb7..b6f6ef1be20 100644 --- a/src/python/pants/backend/helm/goals/deploy_test.py +++ b/src/python/pants/backend/helm/goals/deploy_test.py @@ -3,8 +3,8 @@ from __future__ import annotations +from collections.abc import Iterable, Mapping from textwrap import dedent -from typing import Iterable, Mapping import pytest diff --git a/src/python/pants/backend/helm/goals/lint_test.py b/src/python/pants/backend/helm/goals/lint_test.py index eff30cee650..84697fbd2ed 100644 --- a/src/python/pants/backend/helm/goals/lint_test.py +++ b/src/python/pants/backend/helm/goals/lint_test.py @@ -3,7 +3,7 @@ from __future__ import annotations -from typing import Iterable +from collections.abc import Iterable import pytest diff --git a/src/python/pants/backend/helm/resolve/artifacts.py b/src/python/pants/backend/helm/resolve/artifacts.py index 586ee4ef754..4f3884018c4 100644 --- a/src/python/pants/backend/helm/resolve/artifacts.py +++ b/src/python/pants/backend/helm/resolve/artifacts.py @@ -4,8 +4,9 @@ from __future__ import annotations from abc import ABC, abstractmethod +from collections.abc import Iterable from dataclasses import dataclass -from typing import Any, Iterable, cast +from typing import Any, cast from pants.backend.helm.subsystems.helm import HelmSubsystem from pants.backend.helm.target_types import ( diff --git a/src/python/pants/backend/helm/resolve/remotes.py b/src/python/pants/backend/helm/resolve/remotes.py index 93682967c21..f274c7a23fd 100644 --- a/src/python/pants/backend/helm/resolve/remotes.py +++ b/src/python/pants/backend/helm/resolve/remotes.py @@ -3,8 +3,9 @@ from __future__ import annotations +from collections.abc import Iterator from dataclasses import dataclass -from typing import Any, Iterator, cast +from typing import Any, cast from pants.util.frozendict import FrozenDict from pants.util.memo import memoized_method diff --git a/src/python/pants/backend/helm/subsystems/helm.py b/src/python/pants/backend/helm/subsystems/helm.py index 68530b00e1b..767d4c4b03b 100644 --- a/src/python/pants/backend/helm/subsystems/helm.py +++ b/src/python/pants/backend/helm/subsystems/helm.py @@ -4,7 +4,8 @@ from __future__ import annotations import os -from typing import Any, Iterable +from collections.abc import Iterable +from typing import Any from pants.backend.helm.resolve.remotes import HelmRemotes from pants.backend.helm.target_types import HelmChartTarget, HelmRegistriesField diff --git a/src/python/pants/backend/helm/subsystems/post_renderer.py b/src/python/pants/backend/helm/subsystems/post_renderer.py index 39138146b8c..fcfffe4d4bd 100644 --- a/src/python/pants/backend/helm/subsystems/post_renderer.py +++ b/src/python/pants/backend/helm/subsystems/post_renderer.py @@ -7,10 +7,11 @@ import os import pkgutil import shlex +from collections.abc import Iterable, Mapping from dataclasses import dataclass from pathlib import PurePath from textwrap import dedent # noqa: PNT20 -from typing import Any, Iterable, Mapping +from typing import Any import yaml diff --git a/src/python/pants/backend/helm/util_rules/chart.py b/src/python/pants/backend/helm/util_rules/chart.py index 2040de49794..4c7b94bb3c4 100644 --- a/src/python/pants/backend/helm/util_rules/chart.py +++ b/src/python/pants/backend/helm/util_rules/chart.py @@ -5,8 +5,9 @@ import dataclasses import logging +from collections.abc import Iterable from dataclasses import dataclass -from typing import Any, Iterable +from typing import Any from pants.backend.helm.dependency_inference import chart as chart_inference from pants.backend.helm.resolve import fetch diff --git a/src/python/pants/backend/helm/util_rules/renderer.py b/src/python/pants/backend/helm/util_rules/renderer.py index de6a1e8fcd2..2ed3624f2e7 100644 --- a/src/python/pants/backend/helm/util_rules/renderer.py +++ b/src/python/pants/backend/helm/util_rules/renderer.py @@ -8,10 +8,11 @@ import os import re from collections import defaultdict +from collections.abc import Iterable from dataclasses import dataclass from enum import Enum from itertools import chain -from typing import Any, Iterable +from typing import Any from pants.backend.helm.subsystems import post_renderer from pants.backend.helm.subsystems.post_renderer import HelmPostRenderer diff --git a/src/python/pants/backend/helm/util_rules/tool.py b/src/python/pants/backend/helm/util_rules/tool.py index 84a0551debe..f9ba36ac808 100644 --- a/src/python/pants/backend/helm/util_rules/tool.py +++ b/src/python/pants/backend/helm/util_rules/tool.py @@ -7,11 +7,11 @@ import logging import os from abc import ABCMeta +from collections.abc import Iterable, Mapping from dataclasses import dataclass -from typing import Any, ClassVar, Generic, Iterable, Mapping, Type, TypeVar +from typing import Any, ClassVar, Generic, TypeVar, final import yaml -from typing_extensions import final from pants.backend.helm.subsystems.helm import HelmSubsystem from pants.backend.helm.utils.yaml import snake_case_attr_dict @@ -168,13 +168,13 @@ def from_bytes(cls, content: bytes) -> HelmPluginInfo: class ExternalHelmPluginBinding(Generic[_ExternalHelmPlugin], metaclass=ABCMeta): """Union type allowing Pants to discover global external Helm plugins.""" - plugin_subsystem_cls: ClassVar[Type[ExternalHelmPlugin]] + plugin_subsystem_cls: ClassVar[type[ExternalHelmPlugin]] name: str @final @classmethod - def create(cls: Type[_EHPB]) -> _EHPB: + def create(cls: type[_EHPB]) -> _EHPB: return cls(name=cls.plugin_subsystem_cls.plugin_name) diff --git a/src/python/pants/backend/helm/utils/yaml.py b/src/python/pants/backend/helm/utils/yaml.py index be772cec48c..4f1316d9783 100644 --- a/src/python/pants/backend/helm/utils/yaml.py +++ b/src/python/pants/backend/helm/utils/yaml.py @@ -5,9 +5,10 @@ from abc import ABCMeta from collections import defaultdict +from collections.abc import Callable, Iterable, Iterator, Mapping from dataclasses import dataclass from pathlib import PurePath -from typing import Any, Callable, Generic, Iterable, Iterator, Mapping, Optional, Type, TypeVar +from typing import Any, Generic, TypeVar from pants.engine.collection import Collection from pants.util.frozendict import FrozenDict @@ -169,7 +170,7 @@ class _YamlDocumentIndexNode(Generic[T]): paths: FrozenDict[YamlPath, T] @classmethod - def empty(cls: Type[_YamlDocumentIndexNode[T]]) -> _YamlDocumentIndexNode[T]: + def empty(cls: type[_YamlDocumentIndexNode[T]]) -> _YamlDocumentIndexNode[T]: return cls(paths=FrozenDict()) def to_json_dict(self) -> dict[str, dict[str, str]]: @@ -209,7 +210,7 @@ def create(cls, other: MutableYamlIndex[T]) -> FrozenYamlIndex[T]: def empty(cls: type[FrozenYamlIndex[T]]) -> FrozenYamlIndex[T]: return FrozenYamlIndex[T](_data=FrozenDict()) - def transform_values(self, func: Callable[[T], Optional[R]]) -> FrozenYamlIndex[R]: + def transform_values(self, func: Callable[[T], R | None]) -> FrozenYamlIndex[R]: """Transforms the values of the given indexed collection into those that are returned from the received function. diff --git a/src/python/pants/backend/java/dependency_inference/symbol_mapper.py b/src/python/pants/backend/java/dependency_inference/symbol_mapper.py index dd2d7ee1583..e9c385e9f14 100644 --- a/src/python/pants/backend/java/dependency_inference/symbol_mapper.py +++ b/src/python/pants/backend/java/dependency_inference/symbol_mapper.py @@ -5,7 +5,7 @@ import logging from collections import defaultdict -from typing import Mapping +from collections.abc import Mapping from pants.backend.java.dependency_inference.types import JavaSourceDependencyAnalysis from pants.backend.java.target_types import JavaSourceField diff --git a/src/python/pants/backend/java/dependency_inference/types.py b/src/python/pants/backend/java/dependency_inference/types.py index 906651cfc81..666cf5acd4e 100644 --- a/src/python/pants/backend/java/dependency_inference/types.py +++ b/src/python/pants/backend/java/dependency_inference/types.py @@ -3,8 +3,9 @@ from __future__ import annotations +from collections.abc import Sequence from dataclasses import dataclass -from typing import Any, Sequence +from typing import Any @dataclass(frozen=True) diff --git a/src/python/pants/backend/java/goals/tailor.py b/src/python/pants/backend/java/goals/tailor.py index 1d1662acb2c..1c6f647c554 100644 --- a/src/python/pants/backend/java/goals/tailor.py +++ b/src/python/pants/backend/java/goals/tailor.py @@ -4,8 +4,8 @@ from __future__ import annotations import os +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.java.subsystems.javac import JavacSubsystem from pants.backend.java.target_types import ( diff --git a/src/python/pants/backend/javascript/dependency_inference/rules.py b/src/python/pants/backend/javascript/dependency_inference/rules.py index 5039354716d..667fa9429d1 100644 --- a/src/python/pants/backend/javascript/dependency_inference/rules.py +++ b/src/python/pants/backend/javascript/dependency_inference/rules.py @@ -5,9 +5,9 @@ import itertools import logging import os.path +from collections.abc import Iterable from dataclasses import dataclass from pathlib import PurePath -from typing import Iterable from pants.backend.javascript import package_json from pants.backend.javascript.package_json import ( diff --git a/src/python/pants/backend/javascript/goals/lockfile.py b/src/python/pants/backend/javascript/goals/lockfile.py index ff1af65a05b..a0e97b80be0 100644 --- a/src/python/pants/backend/javascript/goals/lockfile.py +++ b/src/python/pants/backend/javascript/goals/lockfile.py @@ -3,8 +3,8 @@ from __future__ import annotations import os.path +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.javascript import nodejs_project_environment from pants.backend.javascript.nodejs_project import AllNodeJSProjects, NodeJSProject diff --git a/src/python/pants/backend/javascript/goals/tailor.py b/src/python/pants/backend/javascript/goals/tailor.py index c1175632039..12a0440c0cf 100644 --- a/src/python/pants/backend/javascript/goals/tailor.py +++ b/src/python/pants/backend/javascript/goals/tailor.py @@ -5,8 +5,8 @@ import dataclasses import os +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.javascript.package_json import PackageJsonTarget from pants.backend.javascript.target_types import ( diff --git a/src/python/pants/backend/javascript/goals/test.py b/src/python/pants/backend/javascript/goals/test.py index 035cb46949a..dce73ee8bd1 100644 --- a/src/python/pants/backend/javascript/goals/test.py +++ b/src/python/pants/backend/javascript/goals/test.py @@ -4,9 +4,9 @@ import dataclasses from collections import defaultdict +from collections.abc import Iterable from dataclasses import dataclass from pathlib import PurePath -from typing import Iterable from pants.backend.javascript import install_node_package, nodejs_project_environment from pants.backend.javascript.install_node_package import ( diff --git a/src/python/pants/backend/javascript/install_node_package.py b/src/python/pants/backend/javascript/install_node_package.py index 27a67d594f9..0cfae85f539 100644 --- a/src/python/pants/backend/javascript/install_node_package.py +++ b/src/python/pants/backend/javascript/install_node_package.py @@ -3,8 +3,8 @@ from __future__ import annotations import os.path +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.javascript import nodejs_project_environment from pants.backend.javascript.dependency_inference.rules import rules as dependency_inference_rules diff --git a/src/python/pants/backend/javascript/lint/prettier/rules.py b/src/python/pants/backend/javascript/lint/prettier/rules.py index 0a71fa8e52e..4e43dac56e0 100644 --- a/src/python/pants/backend/javascript/lint/prettier/rules.py +++ b/src/python/pants/backend/javascript/lint/prettier/rules.py @@ -5,8 +5,8 @@ import logging import os +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.javascript.lint.prettier.subsystem import Prettier from pants.backend.javascript.subsystems import nodejs_tool diff --git a/src/python/pants/backend/javascript/lint/prettier/skip_field.py b/src/python/pants/backend/javascript/lint/prettier/skip_field.py index 4846be4920d..0f97cc4331b 100644 --- a/src/python/pants/backend/javascript/lint/prettier/skip_field.py +++ b/src/python/pants/backend/javascript/lint/prettier/skip_field.py @@ -3,7 +3,7 @@ from __future__ import annotations -from typing import Iterable +from collections.abc import Iterable from pants.backend.javascript.target_types import JSSourcesGeneratorTarget, JSSourceTarget from pants.engine.rules import Rule diff --git a/src/python/pants/backend/javascript/lint/prettier/subsystem.py b/src/python/pants/backend/javascript/lint/prettier/subsystem.py index 3fa4c6d10db..06310379393 100644 --- a/src/python/pants/backend/javascript/lint/prettier/subsystem.py +++ b/src/python/pants/backend/javascript/lint/prettier/subsystem.py @@ -4,7 +4,7 @@ from __future__ import annotations import os -from typing import Iterable +from collections.abc import Iterable from pants.backend.javascript.subsystems.nodejs_tool import NodeJSToolBase from pants.core.util_rules.config_files import ConfigFilesRequest diff --git a/src/python/pants/backend/javascript/nodejs_project.py b/src/python/pants/backend/javascript/nodejs_project.py index eccc6354843..9babf820732 100644 --- a/src/python/pants/backend/javascript/nodejs_project.py +++ b/src/python/pants/backend/javascript/nodejs_project.py @@ -4,9 +4,9 @@ import itertools import os.path +from collections.abc import Iterable from dataclasses import dataclass, replace from pathlib import PurePath -from typing import Iterable from pants.backend.javascript import package_json from pants.backend.javascript.package_json import ( diff --git a/src/python/pants/backend/javascript/nodejs_project_test.py b/src/python/pants/backend/javascript/nodejs_project_test.py index 4ed18a25c40..6ac7cbbb243 100644 --- a/src/python/pants/backend/javascript/nodejs_project_test.py +++ b/src/python/pants/backend/javascript/nodejs_project_test.py @@ -3,7 +3,7 @@ from __future__ import annotations import json -from typing import Iterable +from collections.abc import Iterable import pytest diff --git a/src/python/pants/backend/javascript/package/rules.py b/src/python/pants/backend/javascript/package/rules.py index a7f94cdc6cb..91cbbde9ca1 100644 --- a/src/python/pants/backend/javascript/package/rules.py +++ b/src/python/pants/backend/javascript/package/rules.py @@ -3,8 +3,9 @@ from __future__ import annotations import re +from collections.abc import Iterable from dataclasses import dataclass -from typing import ClassVar, Iterable +from typing import ClassVar from pants.backend.javascript import install_node_package from pants.backend.javascript.install_node_package import ( diff --git a/src/python/pants/backend/javascript/package_json.py b/src/python/pants/backend/javascript/package_json.py index 8f561f377bd..b1214a6157e 100644 --- a/src/python/pants/backend/javascript/package_json.py +++ b/src/python/pants/backend/javascript/package_json.py @@ -7,8 +7,9 @@ import logging import os.path from abc import ABC +from collections.abc import Iterable, Mapping from dataclasses import dataclass, field -from typing import Any, ClassVar, Iterable, Literal, Mapping, Optional, Tuple +from typing import Any, ClassVar, Literal import yaml @@ -209,8 +210,8 @@ class NodePackageScriptsField(SequenceField[NodeScript]): @classmethod def compute_value( - cls, raw_value: Optional[Iterable[Any]], address: Address - ) -> Optional[Tuple[NodeScript, ...]]: + cls, raw_value: Iterable[Any] | None, address: Address + ) -> tuple[NodeScript, ...] | None: values = super().compute_value(raw_value, address) test_scripts = [value for value in values or () if isinstance(value, NodeTestScript)] if len(test_scripts) > 1: diff --git a/src/python/pants/backend/javascript/package_json_test.py b/src/python/pants/backend/javascript/package_json_test.py index 2c285225cd6..795ddb83e70 100644 --- a/src/python/pants/backend/javascript/package_json_test.py +++ b/src/python/pants/backend/javascript/package_json_test.py @@ -3,8 +3,8 @@ from __future__ import annotations import json +from collections.abc import Iterable from textwrap import dedent -from typing import Iterable import pytest diff --git a/src/python/pants/backend/javascript/resolve.py b/src/python/pants/backend/javascript/resolve.py index 21b9a63b69c..756ce5d087b 100644 --- a/src/python/pants/backend/javascript/resolve.py +++ b/src/python/pants/backend/javascript/resolve.py @@ -3,8 +3,8 @@ from __future__ import annotations import os +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.javascript import nodejs_project from pants.backend.javascript.nodejs_project import AllNodeJSProjects, NodeJSProject diff --git a/src/python/pants/backend/javascript/run/rules.py b/src/python/pants/backend/javascript/run/rules.py index 9cae836f045..496f4df3f9d 100644 --- a/src/python/pants/backend/javascript/run/rules.py +++ b/src/python/pants/backend/javascript/run/rules.py @@ -2,8 +2,8 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). from __future__ import annotations +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.javascript import install_node_package from pants.backend.javascript.install_node_package import ( diff --git a/src/python/pants/backend/javascript/subsystems/nodejs.py b/src/python/pants/backend/javascript/subsystems/nodejs.py index b6e35aeec6a..0fba1369353 100644 --- a/src/python/pants/backend/javascript/subsystems/nodejs.py +++ b/src/python/pants/backend/javascript/subsystems/nodejs.py @@ -6,9 +6,10 @@ import itertools import logging import os.path +from collections.abc import Collection, Iterable, Mapping, Sequence from dataclasses import dataclass, field from itertools import groupby -from typing import ClassVar, Collection, Iterable, Mapping, Sequence +from typing import ClassVar from nodesemver import min_satisfying diff --git a/src/python/pants/backend/javascript/subsystems/nodejs_tool.py b/src/python/pants/backend/javascript/subsystems/nodejs_tool.py index b984f721bb2..e09e5e5b7fd 100644 --- a/src/python/pants/backend/javascript/subsystems/nodejs_tool.py +++ b/src/python/pants/backend/javascript/subsystems/nodejs_tool.py @@ -3,8 +3,9 @@ from __future__ import annotations +from collections.abc import Iterable, Mapping from dataclasses import dataclass, field -from typing import ClassVar, Iterable, Mapping +from typing import ClassVar from pants.backend.javascript import install_node_package, nodejs_project_environment from pants.backend.javascript.install_node_package import ( diff --git a/src/python/pants/backend/jsx/goals/tailor.py b/src/python/pants/backend/jsx/goals/tailor.py index de29a591f5e..dd8a18afaf1 100644 --- a/src/python/pants/backend/jsx/goals/tailor.py +++ b/src/python/pants/backend/jsx/goals/tailor.py @@ -4,8 +4,8 @@ from __future__ import annotations import dataclasses +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.jsx.target_types import ( JSX_FILE_EXTENSIONS, diff --git a/src/python/pants/backend/kotlin/compile/kotlinc_plugins.py b/src/python/pants/backend/kotlin/compile/kotlinc_plugins.py index 4366201fe4a..19ad669d712 100644 --- a/src/python/pants/backend/kotlin/compile/kotlinc_plugins.py +++ b/src/python/pants/backend/kotlin/compile/kotlinc_plugins.py @@ -3,8 +3,8 @@ from __future__ import annotations +from collections.abc import Iterable, Iterator from dataclasses import dataclass -from typing import Iterable, Iterator from pants.backend.kotlin.subsystems.kotlinc import KotlincSubsystem from pants.backend.kotlin.target_types import ( diff --git a/src/python/pants/backend/kotlin/dependency_inference/kotlin_parser.py b/src/python/pants/backend/kotlin/dependency_inference/kotlin_parser.py index 33f60a19689..890ccb88ec4 100644 --- a/src/python/pants/backend/kotlin/dependency_inference/kotlin_parser.py +++ b/src/python/pants/backend/kotlin/dependency_inference/kotlin_parser.py @@ -4,8 +4,9 @@ import json import os +from collections.abc import Iterator from dataclasses import dataclass -from typing import Any, Iterator +from typing import Any from pants.core.goals.resolves import ExportableTool from pants.core.util_rules.source_files import SourceFiles diff --git a/src/python/pants/backend/kotlin/dependency_inference/symbol_mapper.py b/src/python/pants/backend/kotlin/dependency_inference/symbol_mapper.py index cd0a901751b..b02314397e5 100644 --- a/src/python/pants/backend/kotlin/dependency_inference/symbol_mapper.py +++ b/src/python/pants/backend/kotlin/dependency_inference/symbol_mapper.py @@ -2,7 +2,7 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). from collections import defaultdict -from typing import Mapping +from collections.abc import Mapping from pants.backend.kotlin.dependency_inference.kotlin_parser import KotlinSourceDependencyAnalysis from pants.backend.kotlin.target_types import KotlinSourceField diff --git a/src/python/pants/backend/kotlin/goals/tailor.py b/src/python/pants/backend/kotlin/goals/tailor.py index f7378bb99a1..57521f2ad53 100644 --- a/src/python/pants/backend/kotlin/goals/tailor.py +++ b/src/python/pants/backend/kotlin/goals/tailor.py @@ -4,8 +4,8 @@ from __future__ import annotations import os +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.kotlin.subsystems.kotlin import KotlinSubsystem from pants.backend.kotlin.target_types import ( diff --git a/src/python/pants/backend/makeself/goals/package.py b/src/python/pants/backend/makeself/goals/package.py index b9c1088418e..a34b5894f60 100644 --- a/src/python/pants/backend/makeself/goals/package.py +++ b/src/python/pants/backend/makeself/goals/package.py @@ -6,9 +6,9 @@ import dataclasses import logging import os +from collections.abc import Iterable from dataclasses import dataclass from pathlib import PurePath -from typing import Iterable, Optional, Tuple from pants.backend.makeself.subsystem import MakeselfTool from pants.backend.makeself.system_binaries import MakeselfBinaryShimsRequest @@ -77,10 +77,10 @@ class CreateMakeselfArchive: input_digest: Digest description: str = dataclasses.field(compare=False) output_filename: str - extra_tools: Optional[Tuple[str, ...]] = None + extra_tools: tuple[str, ...] | None = None level: LogLevel = LogLevel.INFO - cache_scope: Optional[ProcessCacheScope] = None - timeout_seconds: Optional[int] = None + cache_scope: ProcessCacheScope | None = None + timeout_seconds: int | None = None @rule diff --git a/src/python/pants/backend/makeself/goals/run.py b/src/python/pants/backend/makeself/goals/run.py index ae739d672a2..47cbab699bc 100644 --- a/src/python/pants/backend/makeself/goals/run.py +++ b/src/python/pants/backend/makeself/goals/run.py @@ -4,7 +4,7 @@ from __future__ import annotations import os -from typing import Iterable, Tuple +from collections.abc import Iterable from pants.backend.makeself.goals.package import MakeselfArchiveFieldSet, package_makeself_binary from pants.backend.makeself.subsystem import RunMakeselfArchive @@ -27,7 +27,7 @@ async def run_makeself_archive(request: RunMakeselfArchive) -> Process: ) ) output_directories = [] - argv: Tuple[str, ...] = (request.exe,) + argv: tuple[str, ...] = (request.exe,) if output_directory := request.output_directory: output_directories = [output_directory] diff --git a/src/python/pants/backend/makeself/subsystem.py b/src/python/pants/backend/makeself/subsystem.py index 23afaddffaa..208bbbd6c77 100644 --- a/src/python/pants/backend/makeself/subsystem.py +++ b/src/python/pants/backend/makeself/subsystem.py @@ -3,8 +3,8 @@ from __future__ import annotations import logging +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable, Optional from pants.core.goals.resolves import ExportableTool from pants.core.util_rules import external_tool @@ -75,8 +75,8 @@ class RunMakeselfArchive: input_digest: Digest description: str level: LogLevel = LogLevel.INFO - output_directory: Optional[str] = None - extra_args: Optional[tuple[str, ...]] = None + output_directory: str | None = None + extra_args: tuple[str, ...] | None = None extra_tools: tuple[str, ...] = () diff --git a/src/python/pants/backend/makeself/system_binaries.py b/src/python/pants/backend/makeself/system_binaries.py index e796ed5ac4b..1032c569918 100644 --- a/src/python/pants/backend/makeself/system_binaries.py +++ b/src/python/pants/backend/makeself/system_binaries.py @@ -1,7 +1,7 @@ # Copyright 2024 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable, Tuple from pants.backend.shell.subsystems.shell_setup import ShellSetup from pants.backend.shell.util_rules.builtin import BASH_BUILTIN_COMMANDS @@ -51,7 +51,7 @@ class MakeselfBinaryShimsRequest: simplicity. """ - extra_tools: Tuple[str, ...] + extra_tools: tuple[str, ...] rationale: str diff --git a/src/python/pants/backend/nfpm/fields/contents.py b/src/python/pants/backend/nfpm/fields/contents.py index ef37a91e450..3a3d3f2db49 100644 --- a/src/python/pants/backend/nfpm/fields/contents.py +++ b/src/python/pants/backend/nfpm/fields/contents.py @@ -6,8 +6,9 @@ import os import stat from abc import ABCMeta +from collections.abc import Iterable from enum import Enum -from typing import Any, ClassVar, Iterable, Optional, Union, cast +from typing import Any, ClassVar, cast from pants.backend.nfpm.fields.all import NfpmDependencies from pants.backend.nfpm.subsystem import MTIME_DEFAULT @@ -156,7 +157,7 @@ class NfpmContentFileModeField(IntField): valid_numbers = ValidNumbers.positive_and_zero @classmethod - def compute_value(cls, raw_value: Optional[Union[int, str]], address: Address) -> Optional[int]: + def compute_value(cls, raw_value: int | str | None, address: Address) -> int | None: if isinstance(raw_value, str): try: octal_value = int(raw_value, 8) @@ -235,7 +236,7 @@ class _SrcDstSequenceField(TupleSequenceField): @classmethod def compute_value( - cls, raw_value: Optional[Iterable[Iterable[str]]], address: Address + cls, raw_value: Iterable[Iterable[str]] | None, address: Address ) -> tuple[tuple[str, str], ...]: src_dst_map = super().compute_value(raw_value, address) if not src_dst_map: @@ -272,9 +273,9 @@ class _NfpmContentOverridesField(OverridesField): @classmethod def compute_value( cls, - raw_value: Optional[dict[Union[str, tuple[str, ...]], dict[str, Any]]], + raw_value: dict[str | tuple[str, ...], dict[str, Any]] | None, address: Address, - ) -> Optional[FrozenDict[tuple[str, ...], FrozenDict[str, ImmutableValue]]]: + ) -> FrozenDict[tuple[str, ...], FrozenDict[str, ImmutableValue]] | None: value = super().compute_value(raw_value, address) if not value: return None @@ -316,7 +317,7 @@ class NfpmContentFileSourceField(OptionalSingleSourceField): ) @classmethod - def compute_value(cls, raw_value: Optional[str], address: Address) -> Optional[str]: + def compute_value(cls, raw_value: str | None, address: Address) -> str | None: value_or_default = super().compute_value(raw_value, address) # This field should either have a path to a file or it should be None. # If it is a path to a file, we rely on standard glob_match_error_behavior @@ -585,7 +586,7 @@ class NfpmContentDirsField(StringSequenceField): ) @classmethod - def compute_value(cls, raw_value: Optional[Iterable[str]], address: Address) -> tuple[str, ...]: + def compute_value(cls, raw_value: Iterable[str] | None, address: Address) -> tuple[str, ...]: dst_dirs = super().compute_value(raw_value, address) assert dst_dirs is not None # it is required # nFPM normalizes paths to be absolute, so "" is effectively the same as "/". diff --git a/src/python/pants/backend/nfpm/fields/deb.py b/src/python/pants/backend/nfpm/fields/deb.py index 8f4d38f5039..40e54e51215 100644 --- a/src/python/pants/backend/nfpm/fields/deb.py +++ b/src/python/pants/backend/nfpm/fields/deb.py @@ -3,8 +3,9 @@ from __future__ import annotations +from collections.abc import Iterable from enum import Enum -from typing import ClassVar, Iterable, Optional +from typing import ClassVar from pants.backend.nfpm.fields._relationships import NfpmPackageRelationshipsField from pants.backend.nfpm.fields.all import NfpmDependencies @@ -154,8 +155,8 @@ class NfpmDebTriggersField(DictStringToStringSequenceField): @classmethod def compute_value( - cls, raw_value: Optional[dict[str, Iterable[str]]], address: Address - ) -> Optional[FrozenDict[str, tuple[str, ...]]]: + cls, raw_value: dict[str, Iterable[str]] | None, address: Address + ) -> FrozenDict[str, tuple[str, ...]] | None: value_or_default = super().compute_value(raw_value, address) # only certain keys are allowed in this dictionary. if value_or_default and not cls.valid_keys.issuperset(value_or_default.keys()): diff --git a/src/python/pants/backend/nfpm/fields/rpm.py b/src/python/pants/backend/nfpm/fields/rpm.py index af28c417902..5c4ee380e36 100644 --- a/src/python/pants/backend/nfpm/fields/rpm.py +++ b/src/python/pants/backend/nfpm/fields/rpm.py @@ -4,7 +4,7 @@ from __future__ import annotations from enum import Enum -from typing import ClassVar, Optional +from typing import ClassVar from pants.backend.nfpm.config import NfpmContent from pants.backend.nfpm.fields._relationships import NfpmPackageRelationshipsField @@ -312,7 +312,7 @@ class NfpmRpmCompressionField(StringField): ) @classmethod - def compute_value(cls, raw_value: Optional[str], address: Address) -> Optional[str]: + def compute_value(cls, raw_value: str | None, address: Address) -> str | None: if raw_value is None: # valid_choices has only algorithms, not compression level. # So, return default value, skipping check for default in valid_choices. diff --git a/src/python/pants/backend/nfpm/fields/scripts.py b/src/python/pants/backend/nfpm/fields/scripts.py index ad09a1b6ce5..b04d58a13d0 100644 --- a/src/python/pants/backend/nfpm/fields/scripts.py +++ b/src/python/pants/backend/nfpm/fields/scripts.py @@ -4,7 +4,7 @@ from __future__ import annotations import os -from typing import ClassVar, Optional +from typing import ClassVar from pants.engine.internals.native_engine import Address from pants.engine.target import AsyncFieldMixin, DictStringToStringField, InvalidFieldException @@ -27,8 +27,8 @@ class NfpmPackageScriptsField(AsyncFieldMixin, DictStringToStringField): @classmethod def compute_value( - cls, raw_value: Optional[dict[str, str]], address: Address - ) -> Optional[FrozenDict[str, str]]: + cls, raw_value: dict[str, str] | None, address: Address + ) -> FrozenDict[str, str] | None: value_or_default = super().compute_value(raw_value, address) if value_or_default: invalid_keys = value_or_default.keys() - cls.nfpm_aliases.keys() diff --git a/src/python/pants/backend/nfpm/util_rules/inject_config.py b/src/python/pants/backend/nfpm/util_rules/inject_config.py index 73c6ba42121..a1b1f98c83e 100644 --- a/src/python/pants/backend/nfpm/util_rules/inject_config.py +++ b/src/python/pants/backend/nfpm/util_rules/inject_config.py @@ -4,8 +4,8 @@ from __future__ import annotations from abc import ABC, abstractmethod +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.nfpm.fields.scripts import NfpmPackageScriptsField from pants.engine.environment import EnvironmentName diff --git a/src/python/pants/backend/openapi/codegen/java/rules_integration_test.py b/src/python/pants/backend/openapi/codegen/java/rules_integration_test.py index 5a058555a74..13dcf36d0a1 100644 --- a/src/python/pants/backend/openapi/codegen/java/rules_integration_test.py +++ b/src/python/pants/backend/openapi/codegen/java/rules_integration_test.py @@ -3,8 +3,8 @@ from __future__ import annotations +from collections.abc import Iterable from textwrap import dedent -from typing import Iterable import pytest diff --git a/src/python/pants/backend/openapi/codegen/java/symbol_mapper.py b/src/python/pants/backend/openapi/codegen/java/symbol_mapper.py index d67d98ee55a..496f6cc43ef 100644 --- a/src/python/pants/backend/openapi/codegen/java/symbol_mapper.py +++ b/src/python/pants/backend/openapi/codegen/java/symbol_mapper.py @@ -3,7 +3,8 @@ from __future__ import annotations from collections import defaultdict -from typing import DefaultDict, Mapping, Tuple +from collections.abc import Mapping +from typing import DefaultDict from pants.backend.openapi.codegen.java.extra_fields import ( OpenApiJavaApiPackageField, @@ -36,7 +37,7 @@ async def map_first_party_openapi_java_targets_to_symbols( all_openapi_document_targets: AllOpenApiDocumentTargets, jvm: JvmSubsystem, ) -> SymbolMap: - package_mapping: DefaultDict[Tuple[_ResolveName, str], OrderedSet[Address]] = defaultdict( + package_mapping: DefaultDict[tuple[_ResolveName, str], OrderedSet[Address]] = defaultdict( OrderedSet ) for target in all_openapi_document_targets: diff --git a/src/python/pants/backend/openapi/codegen/python/generate.py b/src/python/pants/backend/openapi/codegen/python/generate.py index 8f511870ad4..d298b73a2b2 100644 --- a/src/python/pants/backend/openapi/codegen/python/generate.py +++ b/src/python/pants/backend/openapi/codegen/python/generate.py @@ -8,7 +8,6 @@ from collections import defaultdict from collections.abc import Iterable from dataclasses import dataclass -from typing import Tuple from packaging.utils import canonicalize_name as canonicalize_project_name @@ -147,7 +146,7 @@ async def compile_openapi_into_python( Get(Digest, DigestSubset(normalized_digest, PathGlobs(["**/*.py"]))), ) requirements_contents = await Get(DigestContents, Digest, requirements_digest) - runtime_dependencies: Tuple[PipRequirement, ...] = () + runtime_dependencies: tuple[PipRequirement, ...] = () if len(requirements_contents) > 0: file = requirements_contents[0] runtime_dependencies = tuple( diff --git a/src/python/pants/backend/openapi/codegen/python/generate_integration_test.py b/src/python/pants/backend/openapi/codegen/python/generate_integration_test.py index 4f951b699b7..ede9e62b357 100644 --- a/src/python/pants/backend/openapi/codegen/python/generate_integration_test.py +++ b/src/python/pants/backend/openapi/codegen/python/generate_integration_test.py @@ -3,9 +3,9 @@ from __future__ import annotations +from collections.abc import Iterable from importlib import resources from textwrap import dedent -from typing import Iterable import pytest diff --git a/src/python/pants/backend/openapi/dependency_inference.py b/src/python/pants/backend/openapi/dependency_inference.py index 94eeabd7447..605eb3f736c 100644 --- a/src/python/pants/backend/openapi/dependency_inference.py +++ b/src/python/pants/backend/openapi/dependency_inference.py @@ -5,8 +5,9 @@ import contextlib import json import os.path +from collections.abc import Mapping from dataclasses import dataclass -from typing import Any, Mapping +from typing import Any import yaml diff --git a/src/python/pants/backend/openapi/goals/tailor.py b/src/python/pants/backend/openapi/goals/tailor.py index 99bc02d71a3..29ab7ed0a93 100644 --- a/src/python/pants/backend/openapi/goals/tailor.py +++ b/src/python/pants/backend/openapi/goals/tailor.py @@ -4,8 +4,8 @@ from __future__ import annotations import itertools +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.openapi.dependency_inference import OpenApiDependencies, ParseOpenApiSources from pants.backend.openapi.subsystems.openapi import OpenApiSubsystem diff --git a/src/python/pants/backend/openapi/util_rules/generator_process.py b/src/python/pants/backend/openapi/util_rules/generator_process.py index c71542f2a96..923191fa479 100644 --- a/src/python/pants/backend/openapi/util_rules/generator_process.py +++ b/src/python/pants/backend/openapi/util_rules/generator_process.py @@ -5,8 +5,8 @@ import dataclasses import re +from collections.abc import Iterable, Iterator, Mapping from dataclasses import dataclass -from typing import Iterable, Iterator, Mapping from pants.backend.openapi.subsystems import openapi_generator from pants.backend.openapi.subsystems.openapi_generator import OpenAPIGenerator diff --git a/src/python/pants/backend/project_info/dependencies_test.py b/src/python/pants/backend/project_info/dependencies_test.py index 0892568346f..cfc7046f691 100644 --- a/src/python/pants/backend/project_info/dependencies_test.py +++ b/src/python/pants/backend/project_info/dependencies_test.py @@ -5,7 +5,7 @@ import json from functools import partial from textwrap import dedent -from typing import Any, List, Optional, Union +from typing import Any import pytest @@ -39,7 +39,7 @@ def rule_runner() -> PythonRuleRunner: def create_python_sources( - rule_runner: PythonRuleRunner, directory: str, *, dependencies: Optional[List[str]] = None + rule_runner: PythonRuleRunner, directory: str, *, dependencies: list[str] | None = None ) -> None: rule_runner.write_files( { @@ -85,9 +85,9 @@ def assert_dependencies( rule_runner: PythonRuleRunner, *, specs: list[str], - expected: Union[list[str], dict[str, Any]], + expected: list[str] | dict[str, Any], transitive: bool = False, - output_file: Optional[str] = None, + output_file: str | None = None, closed: bool = False, output_format: DependenciesOutputFormat = DependenciesOutputFormat.text, ) -> None: diff --git a/src/python/pants/backend/project_info/dependents.py b/src/python/pants/backend/project_info/dependents.py index 064fa4df574..accf9397d4b 100644 --- a/src/python/pants/backend/project_info/dependents.py +++ b/src/python/pants/backend/project_info/dependents.py @@ -2,9 +2,9 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). import json from collections import defaultdict +from collections.abc import Iterable from dataclasses import dataclass from enum import Enum -from typing import Iterable, Set from pants.engine.addresses import Address, Addresses from pants.engine.collection import DeduplicatedCollection @@ -88,7 +88,7 @@ def find_dependents( request: DependentsRequest, address_to_dependents: AddressToDependents ) -> Dependents: check = set(request.addresses) - known_dependents: Set[Address] = set() + known_dependents: set[Address] = set() while True: dependents = set(known_dependents) for target in check: diff --git a/src/python/pants/backend/project_info/dependents_test.py b/src/python/pants/backend/project_info/dependents_test.py index 51b4cad464c..440a687b55b 100644 --- a/src/python/pants/backend/project_info/dependents_test.py +++ b/src/python/pants/backend/project_info/dependents_test.py @@ -2,7 +2,6 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). import json from functools import partial -from typing import Dict, List, Optional, Union import pytest @@ -41,10 +40,10 @@ def rule_runner() -> RuleRunner: def assert_dependents( rule_runner: RuleRunner, *, - targets: List[str], - expected: Union[List[str], Dict[str, List[str]]], + targets: list[str], + expected: list[str] | dict[str, list[str]], transitive: bool = False, - output_file: Optional[str] = None, + output_file: str | None = None, closed: bool = False, output_format: DependentsOutputFormat = DependentsOutputFormat.text, ) -> None: diff --git a/src/python/pants/backend/project_info/filedeps.py b/src/python/pants/backend/project_info/filedeps.py index 8e4b106b4d6..de443a8906e 100644 --- a/src/python/pants/backend/project_info/filedeps.py +++ b/src/python/pants/backend/project_info/filedeps.py @@ -2,8 +2,8 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). import itertools +from collections.abc import Iterable from pathlib import PurePath -from typing import Iterable from pants.base.build_root import BuildRoot from pants.build_graph.address import BuildFileAddressRequest diff --git a/src/python/pants/backend/project_info/filter_targets.py b/src/python/pants/backend/project_info/filter_targets.py index a41e9e1fa59..d2e706f64d6 100644 --- a/src/python/pants/backend/project_info/filter_targets.py +++ b/src/python/pants/backend/project_info/filter_targets.py @@ -5,7 +5,7 @@ import re from enum import Enum -from typing import Pattern +from re import Pattern from pants.base.deprecated import warn_or_error from pants.engine.addresses import Addresses diff --git a/src/python/pants/backend/project_info/list_roots_test.py b/src/python/pants/backend/project_info/list_roots_test.py index 4429c0cb4c3..cc2932ea426 100644 --- a/src/python/pants/backend/project_info/list_roots_test.py +++ b/src/python/pants/backend/project_info/list_roots_test.py @@ -1,7 +1,6 @@ # Copyright 2019 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). -from typing import List, Optional import pytest @@ -17,10 +16,10 @@ def rule_runner() -> RuleRunner: def assert_roots( rule_runner: RuleRunner, - configured: List[str], + configured: list[str], *, - marker_files: Optional[List[str]] = None, - expected: Optional[List[str]] = None, + marker_files: list[str] | None = None, + expected: list[str] | None = None, ) -> None: result = rule_runner.run_goal_rule( Roots, diff --git a/src/python/pants/backend/project_info/list_targets.py b/src/python/pants/backend/project_info/list_targets.py index 14d0d8f33e7..ee6517e0663 100644 --- a/src/python/pants/backend/project_info/list_targets.py +++ b/src/python/pants/backend/project_info/list_targets.py @@ -2,7 +2,7 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). import logging -from typing import Dict, cast +from typing import cast from pants.engine.addresses import Address, Addresses from pants.engine.console import Console @@ -41,7 +41,7 @@ async def list_targets( # We must preserve target generators, not replace with their generated targets. targets = await Get(UnexpandedTargets, Addresses, addresses) addresses_with_descriptions = cast( - Dict[Address, str], + dict[Address, str], { tgt.address: tgt[DescriptionField].value for tgt in targets diff --git a/src/python/pants/backend/project_info/paths.py b/src/python/pants/backend/project_info/paths.py index 624d960b049..6e3638745c0 100644 --- a/src/python/pants/backend/project_info/paths.py +++ b/src/python/pants/backend/project_info/paths.py @@ -5,8 +5,8 @@ import json from collections import deque +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.base.specs import Specs from pants.base.specs_parser import SpecsParser diff --git a/src/python/pants/backend/project_info/paths_test.py b/src/python/pants/backend/project_info/paths_test.py index 61dbd0658fa..668d4b16129 100644 --- a/src/python/pants/backend/project_info/paths_test.py +++ b/src/python/pants/backend/project_info/paths_test.py @@ -5,7 +5,7 @@ import json from textwrap import dedent -from typing import ClassVar, List +from typing import ClassVar import pytest @@ -86,7 +86,7 @@ def assert_paths( *, path_from: str, path_to: str, - expected: List[List[str]] | None = None, + expected: list[list[str]] | None = None, ) -> None: args = [] if path_from: diff --git a/src/python/pants/backend/project_info/peek.py b/src/python/pants/backend/project_info/peek.py index c5e4719df99..98044011061 100644 --- a/src/python/pants/backend/project_info/peek.py +++ b/src/python/pants/backend/project_info/peek.py @@ -8,8 +8,9 @@ import json import logging from abc import ABCMeta +from collections.abc import Iterable, Mapping from dataclasses import dataclass, fields, is_dataclass, replace -from typing import Any, Iterable, Mapping, Protocol, runtime_checkable +from typing import Any, Protocol, runtime_checkable from pants.core.goals.deploy import Deploy, DeployFieldSet from pants.core.goals.package import Package, PackageFieldSet diff --git a/src/python/pants/backend/project_info/peek_test.py b/src/python/pants/backend/project_info/peek_test.py index cf2ce98eb99..9244adfa55e 100644 --- a/src/python/pants/backend/project_info/peek_test.py +++ b/src/python/pants/backend/project_info/peek_test.py @@ -4,8 +4,9 @@ from __future__ import annotations import dataclasses +from collections.abc import Sequence from textwrap import dedent -from typing import Sequence, cast +from typing import cast import pytest diff --git a/src/python/pants/backend/project_info/regex_lint.py b/src/python/pants/backend/project_info/regex_lint.py index f4174248588..03d9a1ba35f 100644 --- a/src/python/pants/backend/project_info/regex_lint.py +++ b/src/python/pants/backend/project_info/regex_lint.py @@ -5,9 +5,10 @@ import logging import re +from collections.abc import Iterable from dataclasses import dataclass from enum import Enum -from typing import Any, Iterable +from typing import Any from pants.base.exiter import PANTS_FAILED_EXIT_CODE, PANTS_SUCCEEDED_EXIT_CODE from pants.core.goals.lint import LintFilesRequest, LintResult, Partitions diff --git a/src/python/pants/backend/python/dependency_inference/default_module_mapping.py b/src/python/pants/backend/python/dependency_inference/default_module_mapping.py index 7613a22fdd6..28d56d82a69 100644 --- a/src/python/pants/backend/python/dependency_inference/default_module_mapping.py +++ b/src/python/pants/backend/python/dependency_inference/default_module_mapping.py @@ -5,9 +5,10 @@ # https://www.python.org/dev/peps/pep-0503/#normalized-names. import re +from collections.abc import Callable from enum import Enum from functools import partial -from typing import Callable, Dict, List, Match, Tuple +from re import Match class PackageSeparator(Enum): @@ -83,7 +84,7 @@ def two_groups_hyphens_two_replacements_with_suffix( then if an import in the python code is google.cloud.foo, then the package of google-cloud-foo will be used. """ -DEFAULT_MODULE_PATTERN_MAPPING: Dict[re.Pattern, List[Callable[[Match[str]], str]]] = { +DEFAULT_MODULE_PATTERN_MAPPING: dict[re.Pattern, list[Callable[[Match[str]], str]]] = { re.compile(r"""^azure-.+"""): [all_hyphen_to_dot], re.compile(r"""^django-((.+(-.+)?))"""): [first_group_hyphen_to_underscore], # See https://github.com/googleapis/google-cloud-python#libraries for all Google cloud @@ -103,7 +104,7 @@ def two_groups_hyphens_two_replacements_with_suffix( re.compile(r"""^apache-(airflow-providers-.+)"""): [first_group_hyphen_to_dot], } -DEFAULT_MODULE_MAPPING: Dict[str, Tuple[str, ...]] = { +DEFAULT_MODULE_MAPPING: dict[str, tuple[str, ...]] = { "absl-py": ("absl",), "acryl-datahub": ("datahub",), "ansicolors": ("colors",), @@ -249,14 +250,14 @@ def two_groups_hyphens_two_replacements_with_suffix( "websocket-client": ("websocket",), } -DEFAULT_TYPE_STUB_MODULE_PATTERN_MAPPING: Dict[re.Pattern, List[Callable[[Match[str]], str]]] = { +DEFAULT_TYPE_STUB_MODULE_PATTERN_MAPPING: dict[re.Pattern, list[Callable[[Match[str]], str]]] = { re.compile(r"""^stubs[_-](.+)"""): [first_group_hyphen_to_underscore], re.compile(r"""^types[_-](.+)"""): [first_group_hyphen_to_underscore], re.compile(r"""^(.+)[_-]stubs"""): [first_group_hyphen_to_underscore], re.compile(r"""^(.+)[_-]types"""): [first_group_hyphen_to_underscore], } -DEFAULT_TYPE_STUB_MODULE_MAPPING: Dict[str, Tuple[str, ...]] = { +DEFAULT_TYPE_STUB_MODULE_MAPPING: dict[str, tuple[str, ...]] = { "djangorestframework-types": ("rest_framework",), "lark-stubs": ("lark",), "types-beautifulsoup4": ("bs4",), diff --git a/src/python/pants/backend/python/dependency_inference/default_unowned_dependencies.py b/src/python/pants/backend/python/dependency_inference/default_unowned_dependencies.py index 5b52d45ec70..dd1c6d65d7e 100644 --- a/src/python/pants/backend/python/dependency_inference/default_unowned_dependencies.py +++ b/src/python/pants/backend/python/dependency_inference/default_unowned_dependencies.py @@ -1,7 +1,6 @@ # Copyright 2021 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). -from typing import List _STDLIB_MODULES = [ # See https://docs.python.org/3/library/sys.html#sys.stdlib_module_names @@ -313,7 +312,7 @@ "zoneinfo", ] -_KNOWN_SYSTEM_MODULES: List[str] = [ +_KNOWN_SYSTEM_MODULES: list[str] = [ # Add the first one, if ye dare! ] diff --git a/src/python/pants/backend/python/dependency_inference/module_mapper.py b/src/python/pants/backend/python/dependency_inference/module_mapper.py index 1369285f88f..de5e4ffdc32 100644 --- a/src/python/pants/backend/python/dependency_inference/module_mapper.py +++ b/src/python/pants/backend/python/dependency_inference/module_mapper.py @@ -9,10 +9,11 @@ import logging import os from collections import defaultdict +from collections.abc import Iterable, Mapping from dataclasses import dataclass from functools import total_ordering from pathlib import PurePath -from typing import DefaultDict, Iterable, Mapping, Tuple +from typing import DefaultDict from packaging.utils import canonicalize_name as canonicalize_project_name @@ -103,7 +104,7 @@ def find_all_python_projects(all_targets: AllTargets) -> AllPythonTargets: class FirstPartyPythonMappingImpl( - FrozenDict[ResolveName, FrozenDict[str, Tuple[ModuleProvider, ...]]] + FrozenDict[ResolveName, FrozenDict[str, tuple[ModuleProvider, ...]]] ): """A mapping of each resolve name to the first-party module names contained and their owning addresses. @@ -143,7 +144,7 @@ class FirstPartyPythonMappingImplMarker: @dataclass(frozen=True) class FirstPartyPythonModuleMapping: resolves_to_modules_to_providers: FrozenDict[ - ResolveName, FrozenDict[str, Tuple[ModuleProvider, ...]] + ResolveName, FrozenDict[str, tuple[ModuleProvider, ...]] ] """A merged mapping of each resolve name to the first-party module names contained and their @@ -277,7 +278,7 @@ class ThirdPartyPythonModuleMapping: modules.""" resolves_to_modules_to_providers: FrozenDict[ - ResolveName, FrozenDict[str, Tuple[ModuleProvider, ...]] + ResolveName, FrozenDict[str, tuple[ModuleProvider, ...]] ] def _providers_for_resolve( @@ -317,7 +318,7 @@ def providers_for_module( @functools.cache -def generate_mappings_from_pattern(proj_name: str, is_type_stub: bool) -> Tuple[str, ...]: +def generate_mappings_from_pattern(proj_name: str, is_type_stub: bool) -> tuple[str, ...]: """Generate a tuple of possible module mappings from a project name using a regex pattern. e.g. google-cloud-foo -> [google.cloud.foo, google.cloud.foo_v1, google.cloud.foo_v2] @@ -377,7 +378,7 @@ def add_modules(modules: Iterable[str], *, is_type_stub: bool) -> None: proj_name = canonicalize_project_name(req.project_name) fallback_value = req.project_name.strip().lower().replace("-", "_") - modules_to_add: Tuple[str, ...] + modules_to_add: tuple[str, ...] is_type_stub: bool if proj_name in DEFAULT_MODULE_MAPPING: modules_to_add = DEFAULT_MODULE_MAPPING[proj_name] diff --git a/src/python/pants/backend/python/dependency_inference/module_mapper_test.py b/src/python/pants/backend/python/dependency_inference/module_mapper_test.py index dfaf8151152..88fcb7e7d9b 100644 --- a/src/python/pants/backend/python/dependency_inference/module_mapper_test.py +++ b/src/python/pants/backend/python/dependency_inference/module_mapper_test.py @@ -4,10 +4,10 @@ from __future__ import annotations import re +from collections.abc import Iterable from pathlib import PurePath from textwrap import dedent from types import FunctionType -from typing import Iterable, Tuple import pytest from packaging.utils import canonicalize_name as canonicalize_project_name @@ -994,7 +994,7 @@ def test_issue_15111(rule_runner: RuleRunner) -> None: ], ) def test_generate_mappings_from_pattern_matches_para( - proj_name: str, expected_modules: Tuple[str] + proj_name: str, expected_modules: tuple[str] ) -> None: assert generate_mappings_from_pattern(proj_name, is_type_stub=False) == expected_modules @@ -1030,7 +1030,7 @@ def test_generate_mappings_from_pattern_matches_para( ], ) def test_generate_type_stub_mappings_from_pattern_matches_para( - proj_name: str, expected_modules: Tuple[str] + proj_name: str, expected_modules: tuple[str] ) -> None: assert generate_mappings_from_pattern(proj_name, is_type_stub=True) == expected_modules diff --git a/src/python/pants/backend/python/dependency_inference/parse_python_dependencies.py b/src/python/pants/backend/python/dependency_inference/parse_python_dependencies.py index 8b3fea0b196..b2d4b92fe3a 100644 --- a/src/python/pants/backend/python/dependency_inference/parse_python_dependencies.py +++ b/src/python/pants/backend/python/dependency_inference/parse_python_dependencies.py @@ -4,8 +4,8 @@ import logging import os +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.python.dependency_inference.subsystem import PythonInferSubsystem from pants.backend.python.target_types import PythonSourceField diff --git a/src/python/pants/backend/python/dependency_inference/rules.py b/src/python/pants/backend/python/dependency_inference/rules.py index 7b891c9293d..b2489cd41a0 100644 --- a/src/python/pants/backend/python/dependency_inference/rules.py +++ b/src/python/pants/backend/python/dependency_inference/rules.py @@ -5,10 +5,10 @@ import itertools import logging +from collections.abc import Iterable from dataclasses import dataclass from enum import Enum from pathlib import PurePath -from typing import Dict, Iterable, Optional from pants.backend.python.dependency_inference import module_mapper, parse_python_dependencies from pants.backend.python.dependency_inference.default_unowned_dependencies import ( @@ -248,7 +248,7 @@ class UnownedImportPossibleOwnerRequest: @dataclass(frozen=True) class UnownedImportsPossibleOwners: - value: Dict[str, list[tuple[Address, ResolveName]]] + value: dict[str, list[tuple[Address, ResolveName]]] @dataclass(frozen=True) @@ -375,7 +375,7 @@ async def _exec_parse_deps( class ResolvedParsedPythonDependenciesRequest: field_set: PythonImportDependenciesInferenceFieldSet parsed_dependencies: ParsedPythonDependencies - resolve: Optional[str] + resolve: str | None @dataclass(frozen=True) diff --git a/src/python/pants/backend/python/dependency_inference/rules_test.py b/src/python/pants/backend/python/dependency_inference/rules_test.py index 1e3b2820422..32bd2ca7c16 100644 --- a/src/python/pants/backend/python/dependency_inference/rules_test.py +++ b/src/python/pants/backend/python/dependency_inference/rules_test.py @@ -3,8 +3,8 @@ from __future__ import annotations +from collections.abc import Iterable from textwrap import dedent -from typing import Iterable import pytest diff --git a/src/python/pants/backend/python/framework/stevedore/python_target_dependencies.py b/src/python/pants/backend/python/framework/stevedore/python_target_dependencies.py index cb3a8cfea8d..5acff90a92f 100644 --- a/src/python/pants/backend/python/framework/stevedore/python_target_dependencies.py +++ b/src/python/pants/backend/python/framework/stevedore/python_target_dependencies.py @@ -4,8 +4,8 @@ from __future__ import annotations from collections import defaultdict +from collections.abc import Mapping from dataclasses import dataclass -from typing import Mapping from pants.backend.python.framework.stevedore.target_types import ( AllStevedoreExtensionTargets, diff --git a/src/python/pants/backend/python/goals/coverage_py.py b/src/python/pants/backend/python/goals/coverage_py.py index 493ad51d06d..be48bac543a 100644 --- a/src/python/pants/backend/python/goals/coverage_py.py +++ b/src/python/pants/backend/python/goals/coverage_py.py @@ -4,11 +4,12 @@ from __future__ import annotations import configparser +from collections.abc import MutableMapping from dataclasses import dataclass from enum import Enum from io import StringIO from pathlib import PurePath -from typing import Any, MutableMapping, cast +from typing import Any, cast import toml diff --git a/src/python/pants/backend/python/goals/debug_goals.py b/src/python/pants/backend/python/goals/debug_goals.py index 838f7b81172..ce53e07a3c0 100644 --- a/src/python/pants/backend/python/goals/debug_goals.py +++ b/src/python/pants/backend/python/goals/debug_goals.py @@ -6,7 +6,7 @@ import json from dataclasses import dataclass from enum import Enum -from typing import Any, Optional, Union +from typing import Any from pants.backend.project_info.peek import _PeekJsonEncoder from pants.backend.python.dependency_inference.module_mapper import ResolveName @@ -110,9 +110,9 @@ class ImportAnalysis: """Information on the inferred imports for a Python file.""" name: str - reference: Union[ParsedPythonImportInfo, str] + reference: ParsedPythonImportInfo | str resolved: ImportResolveResult - possible_resolve: Optional[list[tuple[Address, ResolveName]]] + possible_resolve: list[tuple[Address, ResolveName]] | None @dataclass(frozen=True) diff --git a/src/python/pants/backend/python/goals/export_integration_test.py b/src/python/pants/backend/python/goals/export_integration_test.py index 8cdf288aa80..ed80bfb2427 100644 --- a/src/python/pants/backend/python/goals/export_integration_test.py +++ b/src/python/pants/backend/python/goals/export_integration_test.py @@ -7,8 +7,8 @@ import platform import re import shutil +from collections.abc import Mapping, MutableMapping from textwrap import dedent -from typing import Mapping, MutableMapping import pytest diff --git a/src/python/pants/backend/python/goals/package_pex_binary.py b/src/python/pants/backend/python/goals/package_pex_binary.py index a75754278dc..28417e01afb 100644 --- a/src/python/pants/backend/python/goals/package_pex_binary.py +++ b/src/python/pants/backend/python/goals/package_pex_binary.py @@ -3,7 +3,6 @@ import logging from dataclasses import dataclass -from typing import Tuple from pants.backend.python.target_types import ( PexArgsField, @@ -86,7 +85,7 @@ class PexBinaryFieldSet(PackageFieldSet, RunFieldSet): def _execution_mode(self) -> PexExecutionMode: return PexExecutionMode(self.execution_mode.value) - def generate_additional_args(self, pex_binary_defaults: PexBinaryDefaults) -> Tuple[str, ...]: + def generate_additional_args(self, pex_binary_defaults: PexBinaryDefaults) -> tuple[str, ...]: args = [] if self.emit_warnings.value_or_global_default(pex_binary_defaults) is False: args.append("--no-emit-warnings") diff --git a/src/python/pants/backend/python/goals/publish_test.py b/src/python/pants/backend/python/goals/publish_test.py index 62eaaf5a686..836c4362900 100644 --- a/src/python/pants/backend/python/goals/publish_test.py +++ b/src/python/pants/backend/python/goals/publish_test.py @@ -3,8 +3,8 @@ from __future__ import annotations +from collections.abc import Callable from textwrap import dedent -from typing import Callable import pytest diff --git a/src/python/pants/backend/python/goals/pytest_runner.py b/src/python/pants/backend/python/goals/pytest_runner.py index 2bfd6ca6cce..5933e3c43a5 100644 --- a/src/python/pants/backend/python/goals/pytest_runner.py +++ b/src/python/pants/backend/python/goals/pytest_runner.py @@ -8,7 +8,6 @@ from abc import ABC, abstractmethod from collections import defaultdict from dataclasses import dataclass -from typing import Optional, Tuple from packaging.utils import canonicalize_name as canonicalize_project_name @@ -200,18 +199,18 @@ def description(self) -> str | None: @dataclass(frozen=True) class TestSetupRequest: - field_sets: Tuple[PythonTestFieldSet, ...] + field_sets: tuple[PythonTestFieldSet, ...] metadata: TestMetadata is_debug: bool extra_env: FrozenDict[str, str] = FrozenDict() - prepend_argv: Tuple[str, ...] = () - additional_pexes: Tuple[Pex, ...] = () + prepend_argv: tuple[str, ...] = () + additional_pexes: tuple[Pex, ...] = () @dataclass(frozen=True) class TestSetup: process: Process - results_file_name: Optional[str] + results_file_name: str | None # Prevent this class from being detected by pytest as a test class. __test__ = False diff --git a/src/python/pants/backend/python/goals/pytest_runner_integration_test.py b/src/python/pants/backend/python/goals/pytest_runner_integration_test.py index f26892055b2..c7929f8ebda 100644 --- a/src/python/pants/backend/python/goals/pytest_runner_integration_test.py +++ b/src/python/pants/backend/python/goals/pytest_runner_integration_test.py @@ -6,8 +6,8 @@ import os import re import unittest.mock +from collections.abc import Iterable from textwrap import dedent -from typing import Iterable import pytest diff --git a/src/python/pants/backend/python/goals/repl.py b/src/python/pants/backend/python/goals/repl.py index 19b2788e676..62d848fa20a 100644 --- a/src/python/pants/backend/python/goals/repl.py +++ b/src/python/pants/backend/python/goals/repl.py @@ -4,7 +4,7 @@ from __future__ import annotations import os -from typing import Iterable +from collections.abc import Iterable from pants.backend.python.subsystems import ipython from pants.backend.python.subsystems.ipython import IPython diff --git a/src/python/pants/backend/python/goals/run_helper.py b/src/python/pants/backend/python/goals/run_helper.py index c5a42056956..7e143638677 100644 --- a/src/python/pants/backend/python/goals/run_helper.py +++ b/src/python/pants/backend/python/goals/run_helper.py @@ -5,7 +5,7 @@ import dataclasses import os import textwrap -from typing import Iterable, Optional +from collections.abc import Iterable from pants.backend.python.subsystems.debugpy import DebugPy from pants.backend.python.target_types import ( @@ -43,8 +43,8 @@ async def _create_python_source_run_request( pex_env: PexEnvironment, run_in_sandbox: bool, pex_path: Iterable[Pex] = (), - console_script: Optional[ConsoleScript] = None, - executable: Optional[Executable] = None, + console_script: ConsoleScript | None = None, + executable: Executable | None = None, ) -> RunRequest: addresses = [address] entry_point, transitive_targets = await MultiGet( diff --git a/src/python/pants/backend/python/goals/run_pex_binary_integration_test.py b/src/python/pants/backend/python/goals/run_pex_binary_integration_test.py index 686f0a507ef..5a30f116460 100644 --- a/src/python/pants/backend/python/goals/run_pex_binary_integration_test.py +++ b/src/python/pants/backend/python/goals/run_pex_binary_integration_test.py @@ -3,8 +3,8 @@ from __future__ import annotations import json +from collections.abc import Callable from textwrap import dedent -from typing import Callable, Optional import pytest @@ -15,9 +15,9 @@ def run_generic_test( *, entry_point: str = "app.py", - execution_mode: Optional[PexExecutionMode] = None, + execution_mode: PexExecutionMode | None = None, include_tools: bool = False, - layout: Optional[PexLayout] = None, + layout: PexLayout | None = None, venv_site_packages_copies: bool = False, ) -> Callable[..., PantsResult]: sources = { @@ -105,7 +105,7 @@ def test_entry_point( @pytest.mark.parametrize("execution_mode", [None, PexExecutionMode.VENV]) @pytest.mark.parametrize("include_tools", [True, False]) def test_execution_mode_and_include_tools( - execution_mode: Optional[PexExecutionMode], + execution_mode: PexExecutionMode | None, include_tools: bool, ): run = run_generic_test( @@ -126,7 +126,7 @@ def test_execution_mode_and_include_tools( @pytest.mark.parametrize("layout", PexLayout) def test_layout( - layout: Optional[PexLayout], + layout: PexLayout | None, ): run_generic_test(layout=layout) diff --git a/src/python/pants/backend/python/goals/run_python_requirement.py b/src/python/pants/backend/python/goals/run_python_requirement.py index 1a06996b3fb..f0667f153b0 100644 --- a/src/python/pants/backend/python/goals/run_python_requirement.py +++ b/src/python/pants/backend/python/goals/run_python_requirement.py @@ -7,10 +7,9 @@ import os from collections import defaultdict from dataclasses import dataclass -from typing import Tuple +from typing import TypeAlias from packaging.utils import canonicalize_name as canonicalize_project_name -from typing_extensions import TypeAlias from pants.backend.python.dependency_inference.module_mapper import ( ResolveName, @@ -41,7 +40,7 @@ logger = logging.getLogger(__name__) -InvertedModuleMapping: TypeAlias = FrozenDict[Address, Tuple[str, ...]] +InvertedModuleMapping: TypeAlias = FrozenDict[Address, tuple[str, ...]] def _in_chroot(relpath: str) -> str: diff --git a/src/python/pants/backend/python/goals/run_python_source.py b/src/python/pants/backend/python/goals/run_python_source.py index 2820cdd70e3..792af782980 100644 --- a/src/python/pants/backend/python/goals/run_python_source.py +++ b/src/python/pants/backend/python/goals/run_python_source.py @@ -3,7 +3,6 @@ from dataclasses import dataclass from pathlib import PurePath -from typing import Optional from pants.backend.python.goals.run_helper import ( _create_python_source_run_dap_request, @@ -51,7 +50,7 @@ def should_use_sandbox(self, python_setup: PythonSetup) -> bool: return python_setup.default_run_goal_use_sandbox return self._run_goal_use_sandbox.value - def _executable_main(self) -> Optional[Executable]: + def _executable_main(self) -> Executable | None: source = PurePath(self.source.value) source_name = source.stem if source.suffix == ".py" else source.name if not all(part.isidentifier() for part in source_name.split(".")): diff --git a/src/python/pants/backend/python/goals/run_python_source_integration_test.py b/src/python/pants/backend/python/goals/run_python_source_integration_test.py index 82aeb49bef6..052e3740a86 100644 --- a/src/python/pants/backend/python/goals/run_python_source_integration_test.py +++ b/src/python/pants/backend/python/goals/run_python_source_integration_test.py @@ -6,7 +6,6 @@ import json import os from textwrap import dedent -from typing import Tuple import pytest @@ -75,7 +74,7 @@ def run_run_request( rule_runner: PythonRuleRunner, target: Target, test_debug_adapter: bool = True, -) -> Tuple[int, str, str]: +) -> tuple[int, str, str]: run_request = rule_runner.request(RunRequest, [PythonSourceFieldSet.create(target)]) run_process = InteractiveProcess( argv=run_request.args, diff --git a/src/python/pants/backend/python/goals/tailor.py b/src/python/pants/backend/python/goals/tailor.py index cc116db9f49..0bbea7924dd 100644 --- a/src/python/pants/backend/python/goals/tailor.py +++ b/src/python/pants/backend/python/goals/tailor.py @@ -6,9 +6,9 @@ import logging import os import re +from collections.abc import Iterable from dataclasses import dataclass from pathlib import PurePath -from typing import Iterable from pants.backend.python.dependency_inference.module_mapper import module_from_stripped_path from pants.backend.python.macros.pipenv_requirements import parse_pipenv_requirements diff --git a/src/python/pants/backend/python/lint/bandit/rules.py b/src/python/pants/backend/python/lint/bandit/rules.py index d3c82fe6e67..44b1645e4bc 100644 --- a/src/python/pants/backend/python/lint/bandit/rules.py +++ b/src/python/pants/backend/python/lint/bandit/rules.py @@ -3,8 +3,6 @@ from __future__ import annotations -from typing import Tuple - from pants.backend.python.lint.bandit.subsystem import Bandit, BanditFieldSet from pants.backend.python.subsystems.setup import PythonSetup from pants.backend.python.util_rules import pex @@ -26,7 +24,7 @@ class BanditRequest(LintTargetsRequest): tool_subsystem = Bandit -def generate_argv(source_files: SourceFiles, bandit: Bandit) -> Tuple[str, ...]: +def generate_argv(source_files: SourceFiles, bandit: Bandit) -> tuple[str, ...]: args = [] if bandit.config is not None: args.append(f"--config={bandit.config}") diff --git a/src/python/pants/backend/python/lint/bandit/rules_integration_test.py b/src/python/pants/backend/python/lint/bandit/rules_integration_test.py index f2b36dd60d2..1bcba64a953 100644 --- a/src/python/pants/backend/python/lint/bandit/rules_integration_test.py +++ b/src/python/pants/backend/python/lint/bandit/rules_integration_test.py @@ -3,8 +3,8 @@ from __future__ import annotations +from collections.abc import Sequence from textwrap import dedent -from typing import Sequence import pytest diff --git a/src/python/pants/backend/python/lint/black/subsystem.py b/src/python/pants/backend/python/lint/black/subsystem.py index d32317b3ca3..a475a848185 100644 --- a/src/python/pants/backend/python/lint/black/subsystem.py +++ b/src/python/pants/backend/python/lint/black/subsystem.py @@ -4,8 +4,8 @@ from __future__ import annotations import os.path +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.python.lint.black.skip_field import SkipBlackField from pants.backend.python.subsystems.python_tool_base import PythonToolBase diff --git a/src/python/pants/backend/python/lint/flake8/rules.py b/src/python/pants/backend/python/lint/flake8/rules.py index 22ba0cb251c..8dc87dc5cb6 100644 --- a/src/python/pants/backend/python/lint/flake8/rules.py +++ b/src/python/pants/backend/python/lint/flake8/rules.py @@ -4,7 +4,6 @@ from __future__ import annotations from collections import defaultdict -from typing import Tuple from pants.backend.python.lint.flake8.subsystem import ( Flake8, @@ -32,7 +31,7 @@ class Flake8Request(LintTargetsRequest): tool_subsystem = Flake8 -def generate_argv(source_files: SourceFiles, flake8: Flake8) -> Tuple[str, ...]: +def generate_argv(source_files: SourceFiles, flake8: Flake8) -> tuple[str, ...]: args = [] if flake8.config: args.append(f"--config={flake8.config}") diff --git a/src/python/pants/backend/python/lint/isort/rules.py b/src/python/pants/backend/python/lint/isort/rules.py index ea4acd342b6..d18d80a92c5 100644 --- a/src/python/pants/backend/python/lint/isort/rules.py +++ b/src/python/pants/backend/python/lint/isort/rules.py @@ -3,7 +3,6 @@ from __future__ import annotations from dataclasses import dataclass -from typing import Tuple from pants.backend.python.lint.isort.skip_field import SkipIsortField from pants.backend.python.lint.isort.subsystem import Isort @@ -41,7 +40,7 @@ class IsortRequest(FmtTargetsRequest): def generate_argv( source_files: tuple[str, ...], isort: Isort, *, is_isort5: bool -) -> Tuple[str, ...]: +) -> tuple[str, ...]: args = [*isort.args] if is_isort5 and len(isort.config) == 1: explicitly_configured_config_args = [ diff --git a/src/python/pants/backend/python/lint/isort/subsystem.py b/src/python/pants/backend/python/lint/isort/subsystem.py index 412e410a43e..f8b2f364484 100644 --- a/src/python/pants/backend/python/lint/isort/subsystem.py +++ b/src/python/pants/backend/python/lint/isort/subsystem.py @@ -4,7 +4,7 @@ from __future__ import annotations import os.path -from typing import Iterable +from collections.abc import Iterable from pants.backend.python.subsystems.python_tool_base import PythonToolBase from pants.backend.python.target_types import ConsoleScript diff --git a/src/python/pants/backend/python/lint/pydocstyle/rules.py b/src/python/pants/backend/python/lint/pydocstyle/rules.py index f66bbf180e6..82df611c055 100644 --- a/src/python/pants/backend/python/lint/pydocstyle/rules.py +++ b/src/python/pants/backend/python/lint/pydocstyle/rules.py @@ -3,8 +3,6 @@ from __future__ import annotations -from typing import Tuple - from pants.backend.python.lint.pydocstyle.subsystem import Pydocstyle, PydocstyleFieldSet from pants.backend.python.util_rules import pex from pants.backend.python.util_rules.pex import PexRequest, VenvPex, VenvPexProcess @@ -25,7 +23,7 @@ class PydocstyleRequest(LintTargetsRequest): partitioner_type = PartitionerType.DEFAULT_SINGLE_PARTITION -def generate_argv(source_files: SourceFiles, pydocstyle: Pydocstyle) -> Tuple[str, ...]: +def generate_argv(source_files: SourceFiles, pydocstyle: Pydocstyle) -> tuple[str, ...]: args = [] if pydocstyle.config is not None: args.append(f"--config={pydocstyle.config}") diff --git a/src/python/pants/backend/python/lint/pydocstyle/rules_integration_test.py b/src/python/pants/backend/python/lint/pydocstyle/rules_integration_test.py index 419e11759ea..076458842ae 100644 --- a/src/python/pants/backend/python/lint/pydocstyle/rules_integration_test.py +++ b/src/python/pants/backend/python/lint/pydocstyle/rules_integration_test.py @@ -3,7 +3,7 @@ from __future__ import annotations -from typing import Sequence +from collections.abc import Sequence import pytest diff --git a/src/python/pants/backend/python/lint/pylint/rules.py b/src/python/pants/backend/python/lint/pylint/rules.py index af2c45da013..0b1fa727d50 100644 --- a/src/python/pants/backend/python/lint/pylint/rules.py +++ b/src/python/pants/backend/python/lint/pylint/rules.py @@ -4,7 +4,6 @@ from __future__ import annotations from dataclasses import dataclass -from typing import Tuple import packaging @@ -62,7 +61,7 @@ class PylintRequest(LintTargetsRequest): tool_subsystem = Pylint -def generate_argv(field_sets: tuple[PylintFieldSet, ...], pylint: Pylint) -> Tuple[str, ...]: +def generate_argv(field_sets: tuple[PylintFieldSet, ...], pylint: Pylint) -> tuple[str, ...]: args = [] if pylint.config is not None: args.append(f"--rcfile={pylint.config}") diff --git a/src/python/pants/backend/python/lint/pylint/subsystem.py b/src/python/pants/backend/python/lint/pylint/subsystem.py index 37add5b21ac..39a029e46ce 100644 --- a/src/python/pants/backend/python/lint/pylint/subsystem.py +++ b/src/python/pants/backend/python/lint/pylint/subsystem.py @@ -4,8 +4,8 @@ from __future__ import annotations import os.path +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.python.lint.pylint.skip_field import SkipPylintField from pants.backend.python.subsystems.python_tool_base import PythonToolBase diff --git a/src/python/pants/backend/python/lint/ruff/common.py b/src/python/pants/backend/python/lint/ruff/common.py index cb80a55ca2a..de4d59f59f8 100644 --- a/src/python/pants/backend/python/lint/ruff/common.py +++ b/src/python/pants/backend/python/lint/ruff/common.py @@ -1,9 +1,7 @@ # Copyright 2024 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). from dataclasses import dataclass -from typing import Tuple - -from typing_extensions import assert_never +from typing import assert_never from pants.backend.python.lint.ruff.subsystem import Ruff, RuffMode from pants.core.goals.lint import REPORT_DIR @@ -56,7 +54,7 @@ async def run_ruff( conf_args = [f"--config={ruff.config}"] if ruff.config else [] - extra_initial_args: Tuple[str, ...] = () + extra_initial_args: tuple[str, ...] = () if request.mode is RuffMode.FORMAT: extra_initial_args = ("format",) elif request.mode is RuffMode.FIX: diff --git a/src/python/pants/backend/python/lint/ruff/subsystem.py b/src/python/pants/backend/python/lint/ruff/subsystem.py index 9449fb75e84..67ad6dfb247 100644 --- a/src/python/pants/backend/python/lint/ruff/subsystem.py +++ b/src/python/pants/backend/python/lint/ruff/subsystem.py @@ -4,8 +4,8 @@ from __future__ import annotations import os.path +from collections.abc import Iterable from enum import Enum -from typing import Iterable from packaging.version import parse diff --git a/src/python/pants/backend/python/lint/yapf/subsystem.py b/src/python/pants/backend/python/lint/yapf/subsystem.py index 949f42b3a89..772368401d7 100644 --- a/src/python/pants/backend/python/lint/yapf/subsystem.py +++ b/src/python/pants/backend/python/lint/yapf/subsystem.py @@ -4,7 +4,7 @@ from __future__ import annotations import os.path -from typing import Iterable +from collections.abc import Iterable from pants.backend.python.subsystems.python_tool_base import PythonToolBase from pants.backend.python.target_types import ConsoleScript diff --git a/src/python/pants/backend/python/macros/common_fields.py b/src/python/pants/backend/python/macros/common_fields.py index f38964192c9..527bde582ef 100644 --- a/src/python/pants/backend/python/macros/common_fields.py +++ b/src/python/pants/backend/python/macros/common_fields.py @@ -3,7 +3,8 @@ from __future__ import annotations -from typing import ClassVar, Dict, Iterable, Tuple +from collections.abc import Iterable +from typing import ClassVar from pants.backend.python.target_types import ( PythonRequirementModulesField, @@ -35,8 +36,8 @@ class ModuleMappingField(DictStringToStringSequenceField): @classmethod def compute_value( # type: ignore[override] - cls, raw_value: Dict[str, Iterable[str]], address: Address - ) -> FrozenDict[str, Tuple[str, ...]]: + cls, raw_value: dict[str, Iterable[str]], address: Address + ) -> FrozenDict[str, tuple[str, ...]]: value_or_default = super().compute_value(raw_value, address) return normalize_module_mapping(value_or_default) @@ -59,8 +60,8 @@ class TypeStubsModuleMappingField(DictStringToStringSequenceField): @classmethod def compute_value( # type: ignore[override] - cls, raw_value: Dict[str, Iterable[str]], address: Address - ) -> FrozenDict[str, Tuple[str, ...]]: + cls, raw_value: dict[str, Iterable[str]], address: Address + ) -> FrozenDict[str, tuple[str, ...]]: value_or_default = super().compute_value(raw_value, address) return normalize_module_mapping(value_or_default) diff --git a/src/python/pants/backend/python/macros/common_requirements_rule.py b/src/python/pants/backend/python/macros/common_requirements_rule.py index a657d7e6831..6bf650841ee 100644 --- a/src/python/pants/backend/python/macros/common_requirements_rule.py +++ b/src/python/pants/backend/python/macros/common_requirements_rule.py @@ -6,7 +6,8 @@ import itertools import logging import os -from typing import Callable, Iterable, cast +from collections.abc import Callable, Iterable +from typing import cast from packaging.utils import canonicalize_name as canonicalize_project_name diff --git a/src/python/pants/backend/python/macros/poetry_requirements.py b/src/python/pants/backend/python/macros/poetry_requirements.py index bb9e0c284af..084b8ab7d48 100644 --- a/src/python/pants/backend/python/macros/poetry_requirements.py +++ b/src/python/pants/backend/python/macros/poetry_requirements.py @@ -6,10 +6,11 @@ import itertools import logging import urllib.parse +from collections.abc import Iterator, Mapping, Sequence from dataclasses import dataclass from functools import partial from pathlib import Path, PurePath -from typing import Any, Iterator, Mapping, Sequence, cast +from typing import Any, cast import toml from packaging.version import InvalidVersion, Version diff --git a/src/python/pants/backend/python/macros/python_artifact.py b/src/python/pants/backend/python/macros/python_artifact.py index 415290bed62..de28ca73e24 100644 --- a/src/python/pants/backend/python/macros/python_artifact.py +++ b/src/python/pants/backend/python/macros/python_artifact.py @@ -4,14 +4,14 @@ import collections.abc import copy import json -from typing import Any, Dict, List, Union +from typing import Any from pants.util.strutil import softwrap def _normalize_entry_points( - all_entry_points: Dict[str, Union[List[str], Dict[str, str]]] -) -> Dict[str, Dict[str, str]]: + all_entry_points: dict[str, list[str] | dict[str, str]] +) -> dict[str, dict[str, str]]: """Ensure any entry points are in the form Dict[str, Dict[str, str]].""" if not isinstance(all_entry_points, collections.abc.Mapping): raise ValueError( @@ -66,7 +66,7 @@ def __init__(self, **kwargs) -> None: # coerce entry points from Dict[str, List[str]] to Dict[str, Dict[str, str]] kwargs["entry_points"] = _normalize_entry_points(kwargs["entry_points"]) - self._kw: Dict[str, Any] = copy.deepcopy(kwargs) + self._kw: dict[str, Any] = copy.deepcopy(kwargs) # The kwargs come from a BUILD file, and can contain somewhat arbitrary nested structures, # so we don't have a principled way to make them into a hashable data structure. # E.g., we can't naively turn all lists into tuples because distutils checks that some @@ -76,10 +76,10 @@ def __init__(self, **kwargs) -> None: self._hash: int = hash(json.dumps(kwargs, sort_keys=True)) @property - def kwargs(self) -> Dict[str, Any]: + def kwargs(self) -> dict[str, Any]: return self._kw - def asdict(self) -> Dict[str, Any]: + def asdict(self) -> dict[str, Any]: return self.kwargs def __eq__(self, other: Any) -> bool: diff --git a/src/python/pants/backend/python/macros/python_requirements.py b/src/python/pants/backend/python/macros/python_requirements.py index 5fec18d99c1..df85edbf82f 100644 --- a/src/python/pants/backend/python/macros/python_requirements.py +++ b/src/python/pants/backend/python/macros/python_requirements.py @@ -4,8 +4,9 @@ from __future__ import annotations import os +from collections.abc import Callable, Iterator from itertools import chain -from typing import Any, Callable, Iterator +from typing import Any import toml diff --git a/src/python/pants/backend/python/macros/uv_requirements.py b/src/python/pants/backend/python/macros/uv_requirements.py index 83e0b77dc7e..8a35f6f45a9 100644 --- a/src/python/pants/backend/python/macros/uv_requirements.py +++ b/src/python/pants/backend/python/macros/uv_requirements.py @@ -2,9 +2,9 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). import logging +from collections.abc import Iterator from functools import partial from pathlib import PurePath -from typing import Iterator from pants.backend.python.macros.common_fields import ( ModuleMappingField, diff --git a/src/python/pants/backend/python/providers/python_build_standalone/constraints.py b/src/python/pants/backend/python/providers/python_build_standalone/constraints.py index 2e250569ac1..0a370867226 100644 --- a/src/python/pants/backend/python/providers/python_build_standalone/constraints.py +++ b/src/python/pants/backend/python/providers/python_build_standalone/constraints.py @@ -3,7 +3,8 @@ from __future__ import annotations import operator -from typing import Callable, Iterable, Protocol, cast +from collections.abc import Callable, Iterable +from typing import Protocol, cast from packaging.version import Version diff --git a/src/python/pants/backend/python/providers/python_build_standalone/rules.py b/src/python/pants/backend/python/providers/python_build_standalone/rules.py index 16fa2acec51..3f1d38b4319 100644 --- a/src/python/pants/backend/python/providers/python_build_standalone/rules.py +++ b/src/python/pants/backend/python/providers/python_build_standalone/rules.py @@ -10,9 +10,10 @@ import textwrap import urllib import uuid +from collections.abc import Iterable, Mapping, Sequence from dataclasses import dataclass from pathlib import PurePath -from typing import Iterable, Mapping, Sequence, TypedDict, TypeVar, cast +from typing import TypedDict, TypeVar, cast from packaging.version import InvalidVersion diff --git a/src/python/pants/backend/python/providers/python_build_standalone/rules_integration_test.py b/src/python/pants/backend/python/providers/python_build_standalone/rules_integration_test.py index b5e9231c517..02d0337a6c7 100644 --- a/src/python/pants/backend/python/providers/python_build_standalone/rules_integration_test.py +++ b/src/python/pants/backend/python/providers/python_build_standalone/rules_integration_test.py @@ -4,8 +4,8 @@ from __future__ import annotations import shutil +from collections.abc import Iterable from textwrap import dedent -from typing import Iterable import pytest diff --git a/src/python/pants/backend/python/subsystems/pytest.py b/src/python/pants/backend/python/subsystems/pytest.py index 60f8ecf8df4..65c57ec5336 100644 --- a/src/python/pants/backend/python/subsystems/pytest.py +++ b/src/python/pants/backend/python/subsystems/pytest.py @@ -4,8 +4,8 @@ from __future__ import annotations import os.path +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.python.subsystems.python_tool_base import PythonToolBase from pants.backend.python.target_types import ( diff --git a/src/python/pants/backend/python/subsystems/python_native_code.py b/src/python/pants/backend/python/subsystems/python_native_code.py index 79a497b9091..3a834e16751 100644 --- a/src/python/pants/backend/python/subsystems/python_native_code.py +++ b/src/python/pants/backend/python/subsystems/python_native_code.py @@ -3,7 +3,7 @@ from __future__ import annotations -from typing import Sequence +from collections.abc import Sequence from pants.option.option_types import StrListOption from pants.option.subsystem import Subsystem diff --git a/src/python/pants/backend/python/subsystems/python_tool_base.py b/src/python/pants/backend/python/subsystems/python_tool_base.py index da2ad6ad5cd..4a5015d0fa7 100644 --- a/src/python/pants/backend/python/subsystems/python_tool_base.py +++ b/src/python/pants/backend/python/subsystems/python_tool_base.py @@ -7,9 +7,10 @@ import json import logging import os +from collections.abc import Callable, Iterable, Sequence from dataclasses import dataclass from functools import cache -from typing import Callable, ClassVar, Iterable, Optional, Sequence +from typing import ClassVar from urllib.parse import urlparse from pants.backend.python.target_types import ConsoleScript, EntryPoint, MainSpecification @@ -212,7 +213,7 @@ def pex_requirements_for_default_lockfile(cls): @classmethod @cache - def _default_package_name_and_version(cls) -> Optional[_PackageNameAndVersion]: + def _default_package_name_and_version(cls) -> _PackageNameAndVersion | None: if cls.default_lockfile_resource is None: return None diff --git a/src/python/pants/backend/python/subsystems/setup.py b/src/python/pants/backend/python/subsystems/setup.py index e217ea3b59b..49c89e33528 100644 --- a/src/python/pants/backend/python/subsystems/setup.py +++ b/src/python/pants/backend/python/subsystems/setup.py @@ -6,7 +6,8 @@ import enum import logging import os -from typing import Iterable, List, Optional, TypeVar, cast +from collections.abc import Iterable +from typing import Optional, TypeVar, cast from packaging.utils import canonicalize_name @@ -267,7 +268,7 @@ def interpreter_constraints(self) -> tuple[str, ...]: ), advanced=True, ) - _resolves_to_interpreter_constraints = DictOption[List[str]]( + _resolves_to_interpreter_constraints = DictOption[list[str]]( help=softwrap( """ Override the interpreter constraints to use when generating a resolve's lockfile @@ -315,7 +316,7 @@ def interpreter_constraints(self) -> tuple[str, ...]: ), advanced=True, ) - _resolves_to_no_binary = DictOption[List[str]]( + _resolves_to_no_binary = DictOption[list[str]]( help=softwrap( f""" When generating a resolve's lockfile, do not use binary packages (i.e. wheels) for @@ -339,7 +340,7 @@ def interpreter_constraints(self) -> tuple[str, ...]: ), advanced=True, ) - _resolves_to_only_binary = DictOption[List[str]]( + _resolves_to_only_binary = DictOption[list[str]]( help=softwrap( f""" When generating a resolve's lockfile, do not use source packages (i.e. sdists) for diff --git a/src/python/pants/backend/python/target_types.py b/src/python/pants/backend/python/target_types.py index d44e6c3e289..1d87288b238 100644 --- a/src/python/pants/backend/python/target_types.py +++ b/src/python/pants/backend/python/target_types.py @@ -7,20 +7,10 @@ import logging import os.path from abc import ABC, abstractmethod +from collections.abc import Iterable, Iterator, Mapping, Sequence from dataclasses import dataclass from enum import Enum -from typing import ( - TYPE_CHECKING, - ClassVar, - Iterable, - Iterator, - Mapping, - Optional, - Sequence, - Tuple, - Union, - cast, -) +from typing import TYPE_CHECKING, ClassVar, cast from packaging.utils import canonicalize_name as canonicalize_project_name @@ -118,7 +108,7 @@ class InterpreterConstraintsField(StringSequenceField, AsyncFieldMixin): """ ) - def value_or_global_default(self, python_setup: PythonSetup) -> Tuple[str, ...]: + def value_or_global_default(self, python_setup: PythonSetup) -> tuple[str, ...]: """Return either the given `compatibility` field or the global interpreter constraints. If interpreter constraints are supplied by the CLI flag, return those only. @@ -351,7 +341,7 @@ class EntryPointField(AsyncFieldMixin, Field): value: EntryPoint | None @classmethod - def compute_value(cls, raw_value: Optional[str], address: Address) -> Optional[EntryPoint]: + def compute_value(cls, raw_value: str | None, address: Address) -> EntryPoint | None: value = super().compute_value(raw_value, address) if value is None: return None @@ -397,7 +387,7 @@ class PexScriptField(Field): value: ConsoleScript | None @classmethod - def compute_value(cls, raw_value: Optional[str], address: Address) -> Optional[ConsoleScript]: + def compute_value(cls, raw_value: str | None, address: Address) -> ConsoleScript | None: value = super().compute_value(raw_value, address) if value is None: return None @@ -422,7 +412,7 @@ class PexExecutableField(Field): value: Executable | None @classmethod - def compute_value(cls, raw_value: Optional[str], address: Address) -> Optional[Executable]: + def compute_value(cls, raw_value: str | None, address: Address) -> Executable | None: value = super().compute_value(raw_value, address) if value is None: return None @@ -524,9 +514,7 @@ class PexInheritPathField(StringField): # TODO(#9388): deprecate allowing this to be a `bool`. @classmethod - def compute_value( - cls, raw_value: Optional[Union[str, bool]], address: Address - ) -> Optional[str]: + def compute_value(cls, raw_value: str | bool | None, address: Address) -> str | None: if isinstance(raw_value, bool): return "prefer" if raw_value else "false" return super().compute_value(raw_value, address) @@ -972,7 +960,7 @@ class PythonTestsTimeoutField(IntField): ) valid_numbers = ValidNumbers.positive_only - def calculate_from_global_options(self, test: TestSubsystem, pytest: PyTest) -> Optional[int]: + def calculate_from_global_options(self, test: TestSubsystem, pytest: PyTest) -> int | None: """Determine the timeout (in seconds) after resolving conflicting global options in the `pytest` and `test` scopes. @@ -1244,8 +1232,8 @@ class _PipRequirementSequenceField(Field): @classmethod def compute_value( - cls, raw_value: Optional[Iterable[str]], address: Address - ) -> Tuple[PipRequirement, ...]: + cls, raw_value: Iterable[str] | None, address: Address + ) -> tuple[PipRequirement, ...]: value = super().compute_value(raw_value, address) if value is None: return () @@ -1452,7 +1440,7 @@ class PythonProvidesField(ScalarField, AsyncFieldMixin): ) @classmethod - def compute_value(cls, raw_value: Optional[PythonArtifact], address: Address) -> PythonArtifact: + def compute_value(cls, raw_value: PythonArtifact | None, address: Address) -> PythonArtifact: return cast(PythonArtifact, super().compute_value(raw_value, address)) @@ -1508,7 +1496,7 @@ class PythonDistributionEntryPoint: """Note that this stores if the entry point comes from an address to a `pex_binary` target.""" entry_point: EntryPoint - pex_binary_address: Optional[Address] + pex_binary_address: Address | None # See `target_type_rules.py` for the `Resolve..Request -> Resolved..` rule @@ -1556,8 +1544,8 @@ class ResolvePythonDistributionEntryPointsRequest: logic for resolving pex_binary addresses etc. """ - entry_points_field: Optional[PythonDistributionEntryPointsField] = None - provides_field: Optional[PythonProvidesField] = None + entry_points_field: PythonDistributionEntryPointsField | None = None + provides_field: PythonProvidesField | None = None def __post_init__(self): # Must provide at least one of these fields. diff --git a/src/python/pants/backend/python/target_types_rules.py b/src/python/pants/backend/python/target_types_rules.py index 1094d7f7741..252484641b3 100644 --- a/src/python/pants/backend/python/target_types_rules.py +++ b/src/python/pants/backend/python/target_types_rules.py @@ -11,9 +11,10 @@ import logging import os.path from collections import defaultdict +from collections.abc import Callable, Generator from dataclasses import dataclass from itertools import chain -from typing import Callable, DefaultDict, Dict, Generator, Optional, Tuple, cast +from typing import DefaultDict, cast from pants.backend.python.dependency_inference.module_mapper import ( PythonModuleOwners, @@ -294,10 +295,10 @@ async def infer_pex_binary_entry_point_dependency( def _determine_entry_point_owner( - maybe_disambiguated: Optional[Address], + maybe_disambiguated: Address | None, owners: PythonModuleOwners, unresolved_ambiguity_handler: Callable[[], None], -) -> Tuple[Address, ...]: +) -> tuple[Address, ...]: """Determine what should be the unambiguous owner for a PEX's entrypoint. This might be empty. @@ -341,12 +342,12 @@ def _handle_unresolved_pex_entrypoint( # ----------------------------------------------------------------------------------------------- -_EntryPointsDictType = Dict[str, Dict[str, str]] +_EntryPointsDictType = dict[str, dict[str, str]] def _classify_entry_points( all_entry_points: _EntryPointsDictType, -) -> Generator[Tuple[bool, str, str, str], None, None]: +) -> Generator[tuple[bool, str, str, str], None, None]: """Looks at each entry point to see if it is a target address or not. Yields tuples: is_target, category, name, entry_point_str. @@ -445,11 +446,11 @@ async def resolve_python_distribution_entry_points( target.address: entry_point for target, entry_point in zip(targets, binary_entry_points) } - entry_points: DefaultDict[str, Dict[str, PythonDistributionEntryPoint]] = defaultdict(dict) + entry_points: DefaultDict[str, dict[str, PythonDistributionEntryPoint]] = defaultdict(dict) # Parse refs/replace with resolved pex entry point, and validate console entry points have function. for is_target, category, name, ref in classified_entry_points: - owner: Optional[Address] = None + owner: Address | None = None if is_target: owner = address_by_ref[ref] entry_point = binary_entry_point_by_address[owner].val diff --git a/src/python/pants/backend/python/target_types_test.py b/src/python/pants/backend/python/target_types_test.py index f3ff83f8647..efd3448ff0b 100644 --- a/src/python/pants/backend/python/target_types_test.py +++ b/src/python/pants/backend/python/target_types_test.py @@ -4,8 +4,8 @@ from __future__ import annotations import logging +from collections.abc import Iterable from textwrap import dedent -from typing import Iterable import pytest diff --git a/src/python/pants/backend/python/typecheck/mypy/rules.py b/src/python/pants/backend/python/typecheck/mypy/rules.py index 7545cdf8917..52dbf1bd4e1 100644 --- a/src/python/pants/backend/python/typecheck/mypy/rules.py +++ b/src/python/pants/backend/python/typecheck/mypy/rules.py @@ -5,10 +5,10 @@ import dataclasses import itertools +from collections.abc import Iterable from dataclasses import dataclass from hashlib import sha256 from textwrap import dedent # noqa: PNT20 -from typing import Iterable, Optional, Tuple import packaging @@ -86,8 +86,8 @@ async def _generate_argv( cache_dir: str, venv_python: str, file_list_path: str, - python_version: Optional[str], -) -> Tuple[str, ...]: + python_version: str | None, +) -> tuple[str, ...]: args = [pex.pex.argv0, f"--python-executable={venv_python}", *mypy.args] if mypy.config: args.append(f"--config-file={mypy.config}") @@ -111,7 +111,7 @@ async def _generate_argv( return tuple(args) -def determine_python_files(files: Iterable[str]) -> Tuple[str, ...]: +def determine_python_files(files: Iterable[str]) -> tuple[str, ...]: """We run over all .py and .pyi files, but .pyi files take precedence. MyPy will error if we say to run over the same module with both its .py and .pyi files, so we diff --git a/src/python/pants/backend/python/typecheck/mypy/subsystem.py b/src/python/pants/backend/python/typecheck/mypy/subsystem.py index dc9a96627a5..6ca65f941e8 100644 --- a/src/python/pants/backend/python/typecheck/mypy/subsystem.py +++ b/src/python/pants/backend/python/typecheck/mypy/subsystem.py @@ -4,8 +4,8 @@ from __future__ import annotations import logging +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.python.subsystems.python_tool_base import PythonToolBase from pants.backend.python.subsystems.setup import PythonSetup diff --git a/src/python/pants/backend/python/typecheck/pyright/rules.py b/src/python/pants/backend/python/typecheck/pyright/rules.py index c5d66acecce..791dbbef8c5 100644 --- a/src/python/pants/backend/python/typecheck/pyright/rules.py +++ b/src/python/pants/backend/python/typecheck/pyright/rules.py @@ -6,8 +6,8 @@ import json import logging import os +from collections.abc import Iterable from dataclasses import dataclass, replace -from typing import Iterable import toml diff --git a/src/python/pants/backend/python/typecheck/pyright/rules_integration_test.py b/src/python/pants/backend/python/typecheck/pyright/rules_integration_test.py index 8aa3baed03d..f9d73344735 100644 --- a/src/python/pants/backend/python/typecheck/pyright/rules_integration_test.py +++ b/src/python/pants/backend/python/typecheck/pyright/rules_integration_test.py @@ -4,8 +4,8 @@ from __future__ import annotations import json +from collections.abc import Iterable from textwrap import dedent -from typing import Iterable import pytest diff --git a/src/python/pants/backend/python/typecheck/pyright/skip_field.py b/src/python/pants/backend/python/typecheck/pyright/skip_field.py index 4f10d8e7fc6..81842c133da 100644 --- a/src/python/pants/backend/python/typecheck/pyright/skip_field.py +++ b/src/python/pants/backend/python/typecheck/pyright/skip_field.py @@ -3,7 +3,7 @@ from __future__ import annotations -from typing import Iterable +from collections.abc import Iterable from pants.backend.python.target_types import ( PythonSourcesGeneratorTarget, diff --git a/src/python/pants/backend/python/typecheck/pytype/rules.py b/src/python/pants/backend/python/typecheck/pytype/rules.py index 55b64313114..cea9012ffb7 100644 --- a/src/python/pants/backend/python/typecheck/pytype/rules.py +++ b/src/python/pants/backend/python/typecheck/pytype/rules.py @@ -4,8 +4,8 @@ from __future__ import annotations import logging +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.python.subsystems.setup import PythonSetup from pants.backend.python.target_types import ( diff --git a/src/python/pants/backend/python/typecheck/pytype/rules_integration_test.py b/src/python/pants/backend/python/typecheck/pytype/rules_integration_test.py index 9debc9dd70e..66d2535cdeb 100644 --- a/src/python/pants/backend/python/typecheck/pytype/rules_integration_test.py +++ b/src/python/pants/backend/python/typecheck/pytype/rules_integration_test.py @@ -3,8 +3,8 @@ from __future__ import annotations +from collections.abc import Iterable from textwrap import dedent -from typing import Iterable import pytest diff --git a/src/python/pants/backend/python/typecheck/pytype/skip_field.py b/src/python/pants/backend/python/typecheck/pytype/skip_field.py index 8ee397d4e44..7ad17d8dfc5 100644 --- a/src/python/pants/backend/python/typecheck/pytype/skip_field.py +++ b/src/python/pants/backend/python/typecheck/pytype/skip_field.py @@ -3,7 +3,7 @@ from __future__ import annotations -from typing import Iterable +from collections.abc import Iterable from pants.backend.python.target_types import ( PythonSourcesGeneratorTarget, diff --git a/src/python/pants/backend/python/util_rules/dists.py b/src/python/pants/backend/python/util_rules/dists.py index 150dd46812f..ed878029866 100644 --- a/src/python/pants/backend/python/util_rules/dists.py +++ b/src/python/pants/backend/python/util_rules/dists.py @@ -6,8 +6,9 @@ import io import os from collections import abc +from collections.abc import Mapping from dataclasses import dataclass -from typing import Any, Mapping +from typing import Any import toml diff --git a/src/python/pants/backend/python/util_rules/entry_points.py b/src/python/pants/backend/python/util_rules/entry_points.py index 8d4aad4e063..15dce422346 100644 --- a/src/python/pants/backend/python/util_rules/entry_points.py +++ b/src/python/pants/backend/python/util_rules/entry_points.py @@ -1,8 +1,8 @@ # Copyright 2024 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). from collections import defaultdict +from collections.abc import Callable, Iterable from dataclasses import dataclass -from typing import Callable, Iterable from pants.backend.python.dependency_inference.module_mapper import ( PythonModuleOwners, diff --git a/src/python/pants/backend/python/util_rules/entry_points_test.py b/src/python/pants/backend/python/util_rules/entry_points_test.py index 959720874c3..564fdea328e 100644 --- a/src/python/pants/backend/python/util_rules/entry_points_test.py +++ b/src/python/pants/backend/python/util_rules/entry_points_test.py @@ -3,8 +3,8 @@ from __future__ import annotations +from collections.abc import Iterable from textwrap import dedent -from typing import Iterable import pytest diff --git a/src/python/pants/backend/python/util_rules/faas.py b/src/python/pants/backend/python/util_rules/faas.py index b60a0b12758..c3d93c727eb 100644 --- a/src/python/pants/backend/python/util_rules/faas.py +++ b/src/python/pants/backend/python/util_rules/faas.py @@ -11,7 +11,7 @@ from dataclasses import dataclass from enum import Enum from pathlib import Path -from typing import ClassVar, Optional, cast +from typing import ClassVar, cast from pants.backend.python.dependency_inference.module_mapper import ( PythonModuleOwners, @@ -132,7 +132,7 @@ class PythonFaaSHandlerField(StringField, AsyncFieldMixin): ) @classmethod - def compute_value(cls, raw_value: Optional[str], address: Address) -> str: + def compute_value(cls, raw_value: str | None, address: Address) -> str: value = cast(str, super().compute_value(raw_value, address)) if ":" not in value: raise InvalidFieldException( diff --git a/src/python/pants/backend/python/util_rules/faas_test.py b/src/python/pants/backend/python/util_rules/faas_test.py index 2dfa3d895a2..290aad2beb1 100644 --- a/src/python/pants/backend/python/util_rules/faas_test.py +++ b/src/python/pants/backend/python/util_rules/faas_test.py @@ -4,7 +4,6 @@ from pathlib import Path from textwrap import dedent -from typing import Optional from unittest.mock import Mock import pytest @@ -171,7 +170,7 @@ def test_infer_handler_dependency(rule_runner: RuleRunner, caplog) -> None: } ) - def assert_inferred(address: Address, *, expected: Optional[Address]) -> None: + def assert_inferred(address: Address, *, expected: Address | None) -> None: tgt = rule_runner.get_target(address) inferred = rule_runner.request( InferredDependencies, diff --git a/src/python/pants/backend/python/util_rules/interpreter_constraints.py b/src/python/pants/backend/python/util_rules/interpreter_constraints.py index bd0e17951ef..319b55006da 100644 --- a/src/python/pants/backend/python/util_rules/interpreter_constraints.py +++ b/src/python/pants/backend/python/util_rules/interpreter_constraints.py @@ -7,7 +7,8 @@ import logging import re from collections import defaultdict -from typing import Iterable, Iterator, Protocol, Sequence, Tuple, TypeVar +from collections.abc import Iterable, Iterator, Sequence +from typing import Protocol, TypeVar from packaging.requirements import InvalidRequirement from pkg_resources import Requirement @@ -39,7 +40,7 @@ def interpreter_constraints(self) -> InterpreterConstraintsField: ... _FS = TypeVar("_FS", bound=FieldSetWithInterpreterConstraints) -RawConstraints = Tuple[str, ...] +RawConstraints = tuple[str, ...] # The current maxes are 2.7.18 and 3.6.15. We go much higher, for safety. diff --git a/src/python/pants/backend/python/util_rules/interpreter_constraints_test.py b/src/python/pants/backend/python/util_rules/interpreter_constraints_test.py index d9516843502..0fa8cf46628 100644 --- a/src/python/pants/backend/python/util_rules/interpreter_constraints_test.py +++ b/src/python/pants/backend/python/util_rules/interpreter_constraints_test.py @@ -3,8 +3,8 @@ from __future__ import annotations +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable import pytest from packaging.requirements import InvalidRequirement diff --git a/src/python/pants/backend/python/util_rules/local_dists.py b/src/python/pants/backend/python/util_rules/local_dists.py index 4b015477a77..9df06f6624d 100644 --- a/src/python/pants/backend/python/util_rules/local_dists.py +++ b/src/python/pants/backend/python/util_rules/local_dists.py @@ -5,8 +5,8 @@ import logging import shlex +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.python.subsystems.setuptools import PythonDistributionFieldSet from pants.backend.python.util_rules.interpreter_constraints import InterpreterConstraints diff --git a/src/python/pants/backend/python/util_rules/lockfile_diff.py b/src/python/pants/backend/python/util_rules/lockfile_diff.py index 568fbf93708..6e78c0c88fc 100644 --- a/src/python/pants/backend/python/util_rules/lockfile_diff.py +++ b/src/python/pants/backend/python/util_rules/lockfile_diff.py @@ -6,8 +6,9 @@ import itertools import json import logging +from collections.abc import Mapping from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Mapping +from typing import TYPE_CHECKING, Any from packaging.version import parse diff --git a/src/python/pants/backend/python/util_rules/lockfile_metadata.py b/src/python/pants/backend/python/util_rules/lockfile_metadata.py index ee433738aaa..b7628c0a121 100644 --- a/src/python/pants/backend/python/util_rules/lockfile_metadata.py +++ b/src/python/pants/backend/python/util_rules/lockfile_metadata.py @@ -3,9 +3,10 @@ from __future__ import annotations +from collections.abc import Iterable from dataclasses import dataclass from enum import Enum -from typing import Any, Iterable, Set, cast +from typing import Any, cast from pants.backend.python.util_rules.interpreter_constraints import InterpreterConstraints from pants.core.util_rules.lockfile_metadata import ( @@ -167,7 +168,7 @@ def _from_json_dict( requirements = metadata( "generated_with_requirements", - Set[PipRequirement], + set[PipRequirement], lambda l: { PipRequirement.parse(i, description_of_origin=lockfile_description) for i in l }, @@ -232,13 +233,13 @@ def _from_json_dict( manylinux = metadata("manylinux", str, lambda l: l) requirement_constraints = metadata( "requirement_constraints", - Set[PipRequirement], + set[PipRequirement], lambda l: { PipRequirement.parse(i, description_of_origin=lockfile_description) for i in l }, ) - only_binary = metadata("only_binary", Set[str], lambda l: set(l)) - no_binary = metadata("no_binary", Set[str], lambda l: set(l)) + only_binary = metadata("only_binary", set[str], lambda l: set(l)) + no_binary = metadata("no_binary", set[str], lambda l: set(l)) return PythonLockfileMetadataV3( valid_for_interpreter_constraints=v2_metadata.valid_for_interpreter_constraints, diff --git a/src/python/pants/backend/python/util_rules/lockfile_metadata_test.py b/src/python/pants/backend/python/util_rules/lockfile_metadata_test.py index 0201e652dac..52300ef0197 100644 --- a/src/python/pants/backend/python/util_rules/lockfile_metadata_test.py +++ b/src/python/pants/backend/python/util_rules/lockfile_metadata_test.py @@ -4,7 +4,7 @@ from __future__ import annotations import itertools -from typing import Iterable +from collections.abc import Iterable import pytest diff --git a/src/python/pants/backend/python/util_rules/package_dists.py b/src/python/pants/backend/python/util_rules/package_dists.py index 39ee9ae9acc..75f7f27a925 100644 --- a/src/python/pants/backend/python/util_rules/package_dists.py +++ b/src/python/pants/backend/python/util_rules/package_dists.py @@ -9,10 +9,11 @@ import pickle from abc import ABC, abstractmethod from collections import defaultdict +from collections.abc import Mapping from dataclasses import dataclass from functools import partial from pathlib import PurePath -from typing import Any, DefaultDict, Dict, List, Mapping, Tuple, cast +from typing import Any, DefaultDict, cast from pants.backend.python.macros.python_artifact import PythonArtifact from pants.backend.python.subsystems.setup import PythonSetup @@ -217,7 +218,7 @@ class SetupKwargs: """The keyword arguments to the `setup()` function in the generated `setup.py`.""" _pickled_bytes: bytes - _overwrite_banned_keys: Tuple[str, ...] + _overwrite_banned_keys: tuple[str, ...] def __init__( self, @@ -225,7 +226,7 @@ def __init__( *, address: Address, _allow_banned_keys: bool = False, - _overwrite_banned_keys: Tuple[str, ...] = (), + _overwrite_banned_keys: tuple[str, ...] = (), ) -> None: super().__init__() if "name" not in kwargs: @@ -270,7 +271,7 @@ def __init__( @memoized_property def kwargs(self) -> dict[str, Any]: - return cast(Dict[str, Any], pickle.loads(self._pickled_bytes)) + return cast(dict[str, Any], pickle.loads(self._pickled_bytes)) @property def name(self) -> str: @@ -303,7 +304,7 @@ def is_applicable(cls, target: Target) -> bool: """Whether the kwargs implementation should be used for this target or not.""" @property - def explicit_kwargs(self) -> Dict[str, Any]: + def explicit_kwargs(self) -> dict[str, Any]: # We return a dict copy of the underlying FrozenDict, because the caller expects a # dict (and we have documented as much). return dict(self.target[PythonProvidesField].value.kwargs) @@ -1017,7 +1018,7 @@ def is_ownable_target(tgt: Target, union_membership: UnionMembership) -> bool: # Convenient type alias for the pair (package name, data files in the package). -PackageDatum = Tuple[str, Tuple[str, ...]] +PackageDatum = tuple[str, tuple[str, ...]] def find_packages( @@ -1136,7 +1137,7 @@ def merge_entry_points( """Merge all entry points, throwing ValueError if there are any conflicts.""" merged = cast( # this gives us a two level deep defaultdict with the inner values being of list type - DefaultDict[str, DefaultDict[str, List[Tuple[str, str]]]], + DefaultDict[str, DefaultDict[str, list[tuple[str, str]]]], defaultdict(partial(defaultdict, list)), ) diff --git a/src/python/pants/backend/python/util_rules/package_dists_test.py b/src/python/pants/backend/python/util_rules/package_dists_test.py index 6ef620d6899..7b0ccb9edbb 100644 --- a/src/python/pants/backend/python/util_rules/package_dists_test.py +++ b/src/python/pants/backend/python/util_rules/package_dists_test.py @@ -4,7 +4,7 @@ from __future__ import annotations import textwrap -from typing import Iterable +from collections.abc import Iterable import pytest diff --git a/src/python/pants/backend/python/util_rules/partition.py b/src/python/pants/backend/python/util_rules/partition.py index b635f30651f..37cd5c431d8 100644 --- a/src/python/pants/backend/python/util_rules/partition.py +++ b/src/python/pants/backend/python/util_rules/partition.py @@ -5,7 +5,8 @@ import itertools from collections import defaultdict -from typing import Iterable, Mapping, Protocol, Sequence, TypeVar +from collections.abc import Iterable, Mapping, Sequence +from typing import Protocol, TypeVar from pants.backend.python.subsystems.setup import PythonSetup from pants.backend.python.target_types import InterpreterConstraintsField, PythonResolveField diff --git a/src/python/pants/backend/python/util_rules/pex.py b/src/python/pants/backend/python/util_rules/pex.py index cc3019d0586..77c6b67bade 100644 --- a/src/python/pants/backend/python/util_rules/pex.py +++ b/src/python/pants/backend/python/util_rules/pex.py @@ -8,10 +8,11 @@ import logging import os import shlex +from collections.abc import Iterable, Iterator, Mapping, Sequence from dataclasses import dataclass from pathlib import PurePath from textwrap import dedent # noqa: PNT20 -from typing import Iterable, Iterator, Mapping, Sequence, TypeVar +from typing import TypeVar import packaging.specifiers import packaging.version diff --git a/src/python/pants/backend/python/util_rules/pex_cli.py b/src/python/pants/backend/python/util_rules/pex_cli.py index 26b763074a3..3d5e3c07cba 100644 --- a/src/python/pants/backend/python/util_rules/pex_cli.py +++ b/src/python/pants/backend/python/util_rules/pex_cli.py @@ -6,8 +6,8 @@ import dataclasses import logging import os.path +from collections.abc import Iterable, Mapping from dataclasses import dataclass -from typing import Iterable, List, Mapping, Optional, Tuple from pants.backend.python.subsystems.python_native_code import PythonNativeCodeSubsystem from pants.backend.python.subsystems.setup import PythonSetup @@ -78,10 +78,10 @@ class PexCliProcess: subcommand: tuple[str, ...] extra_args: tuple[str, ...] description: str = dataclasses.field(compare=False) - additional_input_digest: Optional[Digest] - extra_env: Optional[FrozenDict[str, str]] - output_files: Optional[Tuple[str, ...]] - output_directories: Optional[Tuple[str, ...]] + additional_input_digest: Digest | None + extra_env: FrozenDict[str, str] | None + output_files: tuple[str, ...] | None + output_directories: tuple[str, ...] | None level: LogLevel concurrency_available: int cache_scope: ProcessCacheScope @@ -92,10 +92,10 @@ def __init__( subcommand: Iterable[str], extra_args: Iterable[str], description: str, - additional_input_digest: Optional[Digest] = None, - extra_env: Optional[Mapping[str, str]] = None, - output_files: Optional[Iterable[str]] = None, - output_directories: Optional[Iterable[str]] = None, + additional_input_digest: Digest | None = None, + extra_env: Mapping[str, str] | None = None, + output_files: Iterable[str] | None = None, + output_directories: Iterable[str] | None = None, level: LogLevel = LogLevel.INFO, concurrency_available: int = 0, cache_scope: ProcessCacheScope = ProcessCacheScope.SUCCESSFUL, @@ -143,7 +143,7 @@ async def setup_pex_cli_process( python_setup: PythonSetup, ) -> Process: tmpdir = ".tmp" - gets: List[Get] = [Get(Digest, CreateDigest([Directory(tmpdir)]))] + gets: list[Get] = [Get(Digest, CreateDigest([Directory(tmpdir)]))] cert_args = [] if global_options.ca_certs_path: diff --git a/src/python/pants/backend/python/util_rules/pex_environment.py b/src/python/pants/backend/python/util_rules/pex_environment.py index 5137179f5ba..c436d469f50 100644 --- a/src/python/pants/backend/python/util_rules/pex_environment.py +++ b/src/python/pants/backend/python/util_rules/pex_environment.py @@ -4,9 +4,9 @@ from __future__ import annotations import os +from collections.abc import Mapping from dataclasses import dataclass from pathlib import PurePath -from typing import Mapping from pants.core.subsystems.python_bootstrap import PythonBootstrap from pants.core.util_rules import subprocess_environment, system_binaries diff --git a/src/python/pants/backend/python/util_rules/pex_from_targets.py b/src/python/pants/backend/python/util_rules/pex_from_targets.py index 3eb040a230b..fc4b69ef54b 100644 --- a/src/python/pants/backend/python/util_rules/pex_from_targets.py +++ b/src/python/pants/backend/python/util_rules/pex_from_targets.py @@ -5,8 +5,8 @@ import dataclasses import logging +from collections.abc import Iterable, Mapping from dataclasses import dataclass -from typing import Iterable, Mapping from packaging.utils import canonicalize_name as canonicalize_project_name diff --git a/src/python/pants/backend/python/util_rules/pex_from_targets_test.py b/src/python/pants/backend/python/util_rules/pex_from_targets_test.py index 8f008909e7b..5a02c5eedb3 100644 --- a/src/python/pants/backend/python/util_rules/pex_from_targets_test.py +++ b/src/python/pants/backend/python/util_rules/pex_from_targets_test.py @@ -6,11 +6,12 @@ import importlib.resources import subprocess import sys +from collections.abc import Iterable from dataclasses import dataclass from enum import Enum from pathlib import Path, PurePath from textwrap import dedent -from typing import Iterable, List, cast +from typing import cast from unittest.mock import Mock import pytest @@ -561,7 +562,7 @@ def create_dists(workdir: Path, project: Project, *projects: Project) -> PurePat def requirements(rule_runner: PythonRuleRunner, pex: Pex) -> list[str]: - return cast(List[str], get_all_data(rule_runner, pex).info["requirements"]) + return cast(list[str], get_all_data(rule_runner, pex).info["requirements"]) def test_constraints_validation(tmp_path: Path, rule_runner: PythonRuleRunner) -> None: diff --git a/src/python/pants/backend/python/util_rules/pex_requirements.py b/src/python/pants/backend/python/util_rules/pex_requirements.py index 8cde4a5498c..c23290b0ae2 100644 --- a/src/python/pants/backend/python/util_rules/pex_requirements.py +++ b/src/python/pants/backend/python/util_rules/pex_requirements.py @@ -5,8 +5,9 @@ import importlib.resources import logging +from collections.abc import Iterable, Iterator from dataclasses import dataclass, field -from typing import TYPE_CHECKING, Iterable, Iterator +from typing import TYPE_CHECKING from urllib.parse import urlparse from pants.backend.python.subsystems.repos import PythonRepos diff --git a/src/python/pants/backend/python/util_rules/pex_test_utils.py b/src/python/pants/backend/python/util_rules/pex_test_utils.py index ed6174435e3..eb66ab4be6e 100644 --- a/src/python/pants/backend/python/util_rules/pex_test_utils.py +++ b/src/python/pants/backend/python/util_rules/pex_test_utils.py @@ -6,9 +6,10 @@ import json import os.path import zipfile +from collections.abc import Iterable, Iterator, Mapping from dataclasses import dataclass from pathlib import PurePath -from typing import Any, Iterable, Iterator, Mapping +from typing import Any from pants.backend.python.target_types import MainSpecification, PexLayout from pants.backend.python.util_rules.interpreter_constraints import InterpreterConstraints diff --git a/src/python/pants/backend/python/util_rules/python_sources.py b/src/python/pants/backend/python/util_rules/python_sources.py index 65903a8b973..af856ea067c 100644 --- a/src/python/pants/backend/python/util_rules/python_sources.py +++ b/src/python/pants/backend/python/util_rules/python_sources.py @@ -3,8 +3,8 @@ from __future__ import annotations +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.python.target_types import PythonSourceField from pants.backend.python.util_rules import ancestor_files diff --git a/src/python/pants/backend/python/util_rules/python_sources_test.py b/src/python/pants/backend/python/util_rules/python_sources_test.py index 181477a1c5e..2ca931d3319 100644 --- a/src/python/pants/backend/python/util_rules/python_sources_test.py +++ b/src/python/pants/backend/python/util_rules/python_sources_test.py @@ -4,8 +4,8 @@ from __future__ import annotations import os.path +from collections.abc import Iterable from textwrap import dedent -from typing import Iterable import pytest diff --git a/src/python/pants/backend/rust/util_rules/toolchains.py b/src/python/pants/backend/rust/util_rules/toolchains.py index 63bda496260..9c33a3cea0d 100644 --- a/src/python/pants/backend/rust/util_rules/toolchains.py +++ b/src/python/pants/backend/rust/util_rules/toolchains.py @@ -4,8 +4,8 @@ import dataclasses import os +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.rust.subsystems.rust import RustSubsystem from pants.core.util_rules.system_binaries import ( diff --git a/src/python/pants/backend/scala/bsp/rules.py b/src/python/pants/backend/scala/bsp/rules.py index bb6b3c5f4c7..385bbbe7c1c 100644 --- a/src/python/pants/backend/scala/bsp/rules.py +++ b/src/python/pants/backend/scala/bsp/rules.py @@ -4,9 +4,9 @@ import logging import textwrap +from collections.abc import Callable from dataclasses import dataclass from pathlib import Path -from typing import Callable from pants.backend.scala.bsp.spec import ( ScalaBuildTarget, diff --git a/src/python/pants/backend/scala/compile/scalac_plugins.py b/src/python/pants/backend/scala/compile/scalac_plugins.py index 2d098edaac4..61c5ea7519c 100644 --- a/src/python/pants/backend/scala/compile/scalac_plugins.py +++ b/src/python/pants/backend/scala/compile/scalac_plugins.py @@ -3,8 +3,8 @@ from __future__ import annotations +from collections.abc import Iterable, Iterator from dataclasses import dataclass -from typing import Iterable, Iterator from pants.backend.scala.subsystems.scalac import Scalac from pants.backend.scala.target_types import ( diff --git a/src/python/pants/backend/scala/dependency_inference/scala_parser.py b/src/python/pants/backend/scala/dependency_inference/scala_parser.py index 797b4f7aab9..e1136c898d7 100644 --- a/src/python/pants/backend/scala/dependency_inference/scala_parser.py +++ b/src/python/pants/backend/scala/dependency_inference/scala_parser.py @@ -5,8 +5,9 @@ import json import logging import os +from collections.abc import Iterator, Mapping from dataclasses import dataclass -from typing import Any, Iterator, Mapping +from typing import Any from pants.backend.scala.subsystems.scala import ScalaSubsystem from pants.backend.scala.subsystems.scalac import Scalac diff --git a/src/python/pants/backend/scala/dependency_inference/symbol_mapper.py b/src/python/pants/backend/scala/dependency_inference/symbol_mapper.py index ab6db09ba90..189947b5eb9 100644 --- a/src/python/pants/backend/scala/dependency_inference/symbol_mapper.py +++ b/src/python/pants/backend/scala/dependency_inference/symbol_mapper.py @@ -3,7 +3,7 @@ from __future__ import annotations from collections import defaultdict -from typing import Mapping +from collections.abc import Mapping from pants.backend.scala.dependency_inference.scala_parser import ScalaSourceDependencyAnalysis from pants.backend.scala.target_types import ScalaSourceField diff --git a/src/python/pants/backend/scala/goals/tailor.py b/src/python/pants/backend/scala/goals/tailor.py index 5d408b1ad86..a1199cca0c2 100644 --- a/src/python/pants/backend/scala/goals/tailor.py +++ b/src/python/pants/backend/scala/goals/tailor.py @@ -4,8 +4,8 @@ from __future__ import annotations import os +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.scala.subsystems.scala import ScalaSubsystem from pants.backend.scala.target_types import ( diff --git a/src/python/pants/backend/scala/lint/scalafix/rules.py b/src/python/pants/backend/scala/lint/scalafix/rules.py index 70a0c1655e8..22f7b1cfbc4 100644 --- a/src/python/pants/backend/scala/lint/scalafix/rules.py +++ b/src/python/pants/backend/scala/lint/scalafix/rules.py @@ -4,9 +4,10 @@ import os.path from collections import defaultdict +from collections.abc import Iterable from dataclasses import dataclass from pathlib import PurePath -from typing import Iterable, cast +from typing import cast from pants.backend.scala.lint.scalafix.extra_fields import SkipScalafixField from pants.backend.scala.lint.scalafix.subsystem import ScalafixSubsystem diff --git a/src/python/pants/backend/scala/lint/scalafix/rules_integration_test.py b/src/python/pants/backend/scala/lint/scalafix/rules_integration_test.py index 789d313faba..45574d5d040 100644 --- a/src/python/pants/backend/scala/lint/scalafix/rules_integration_test.py +++ b/src/python/pants/backend/scala/lint/scalafix/rules_integration_test.py @@ -2,8 +2,9 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). from __future__ import annotations +from collections.abc import Callable from textwrap import dedent -from typing import Any, Callable, TypeVar, overload +from typing import Any, TypeVar, overload import pytest diff --git a/src/python/pants/backend/scala/test/scalatest_test.py b/src/python/pants/backend/scala/test/scalatest_test.py index a996fabb07c..0ed24c13f2a 100644 --- a/src/python/pants/backend/scala/test/scalatest_test.py +++ b/src/python/pants/backend/scala/test/scalatest_test.py @@ -3,8 +3,8 @@ from __future__ import annotations +from collections.abc import Mapping from textwrap import dedent -from typing import List, Mapping import pytest @@ -287,7 +287,7 @@ def run_scalatest_test( target_name: str, relative_file_path: str, *, - extra_args: List[str] | None = None, + extra_args: list[str] | None = None, env: Mapping[str, str] | None = None, ) -> TestResult: args = extra_args or [] diff --git a/src/python/pants/backend/shell/goals/tailor.py b/src/python/pants/backend/shell/goals/tailor.py index a3ee9bba826..5ad3d336540 100644 --- a/src/python/pants/backend/shell/goals/tailor.py +++ b/src/python/pants/backend/shell/goals/tailor.py @@ -4,8 +4,8 @@ from __future__ import annotations import os +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.shell.subsystems.shell_setup import ShellSetup from pants.backend.shell.target_types import ( diff --git a/src/python/pants/backend/shell/lint/shellcheck/subsystem.py b/src/python/pants/backend/shell/lint/shellcheck/subsystem.py index a108f11f856..57b47579bdc 100644 --- a/src/python/pants/backend/shell/lint/shellcheck/subsystem.py +++ b/src/python/pants/backend/shell/lint/shellcheck/subsystem.py @@ -4,7 +4,7 @@ from __future__ import annotations import os.path -from typing import Iterable +from collections.abc import Iterable from pants.core.util_rules.config_files import ConfigFilesRequest from pants.core.util_rules.external_tool import TemplatedExternalTool diff --git a/src/python/pants/backend/shell/lint/shfmt/subsystem.py b/src/python/pants/backend/shell/lint/shfmt/subsystem.py index 4b5696dce32..c8458bc8f33 100644 --- a/src/python/pants/backend/shell/lint/shfmt/subsystem.py +++ b/src/python/pants/backend/shell/lint/shfmt/subsystem.py @@ -4,7 +4,7 @@ from __future__ import annotations import os.path -from typing import Iterable +from collections.abc import Iterable from pants.core.util_rules.config_files import ConfigFilesRequest from pants.core.util_rules.external_tool import TemplatedExternalTool diff --git a/src/python/pants/backend/sql/lint/sqlfluff/rules.py b/src/python/pants/backend/sql/lint/sqlfluff/rules.py index b02b7cd4e23..a708f15efd9 100644 --- a/src/python/pants/backend/sql/lint/sqlfluff/rules.py +++ b/src/python/pants/backend/sql/lint/sqlfluff/rules.py @@ -2,10 +2,9 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). from __future__ import annotations +from collections.abc import Iterable from dataclasses import dataclass -from typing import Any, Iterable, Tuple - -from typing_extensions import assert_never +from typing import Any, assert_never from pants.backend.python.util_rules import pex from pants.backend.python.util_rules.pex import PexRequest, VenvPexProcess, create_venv_pex @@ -73,7 +72,7 @@ async def run_sqlfluff( MergeDigests((request.snapshot.digest, config_files.snapshot.digest)) ) - initial_args: Tuple[str, ...] = () + initial_args: tuple[str, ...] = () if request.mode is SqlfluffMode.FMT: initial_args = ("format",) elif request.mode is SqlfluffMode.FIX: diff --git a/src/python/pants/backend/sql/lint/sqlfluff/skip_field.py b/src/python/pants/backend/sql/lint/sqlfluff/skip_field.py index b233cb6e440..c2da89874a2 100644 --- a/src/python/pants/backend/sql/lint/sqlfluff/skip_field.py +++ b/src/python/pants/backend/sql/lint/sqlfluff/skip_field.py @@ -1,7 +1,7 @@ # Copyright 2024 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). -from typing import Iterable +from collections.abc import Iterable from pants.backend.sql.target_types import SqlSourcesGeneratorTarget, SqlSourceTarget from pants.engine.target import BoolField diff --git a/src/python/pants/backend/sql/lint/sqlfluff/subsystem.py b/src/python/pants/backend/sql/lint/sqlfluff/subsystem.py index c1688d00141..8c0d06156c9 100644 --- a/src/python/pants/backend/sql/lint/sqlfluff/subsystem.py +++ b/src/python/pants/backend/sql/lint/sqlfluff/subsystem.py @@ -4,9 +4,9 @@ from __future__ import annotations import os.path +from collections.abc import Iterable from dataclasses import dataclass from enum import Enum -from typing import Iterable from pants.backend.python.subsystems.python_tool_base import PythonToolBase from pants.backend.python.target_types import ConsoleScript diff --git a/src/python/pants/backend/swift/goals/tailor.py b/src/python/pants/backend/swift/goals/tailor.py index 3905d7cddf5..b079fd3be6d 100644 --- a/src/python/pants/backend/swift/goals/tailor.py +++ b/src/python/pants/backend/swift/goals/tailor.py @@ -3,8 +3,8 @@ from __future__ import annotations +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.swift.target_types import SWIFT_FILE_EXTENSIONS, SwiftSourcesGeneratorTarget from pants.core.goals.tailor import ( diff --git a/src/python/pants/backend/terraform/dependencies.py b/src/python/pants/backend/terraform/dependencies.py index c5e11a7f80e..3f63996c13c 100644 --- a/src/python/pants/backend/terraform/dependencies.py +++ b/src/python/pants/backend/terraform/dependencies.py @@ -5,7 +5,6 @@ import os import os.path from dataclasses import dataclass -from typing import Optional from pants.backend.terraform.dependency_inference import ( TerraformDeploymentInvocationFiles, @@ -37,7 +36,7 @@ @dataclass(frozen=True) class TerraformDependenciesRequest: chdir: str - backend_config: Optional[str] + backend_config: str | None lockfile: bool dependencies_files: Digest diff --git a/src/python/pants/backend/terraform/dependencies_test.py b/src/python/pants/backend/terraform/dependencies_test.py index 63214064517..f1e56e94dd2 100644 --- a/src/python/pants/backend/terraform/dependencies_test.py +++ b/src/python/pants/backend/terraform/dependencies_test.py @@ -6,7 +6,6 @@ import json import textwrap from pathlib import Path -from typing import Optional from pants.backend.terraform.dependencies import TerraformInitRequest, TerraformInitResponse from pants.backend.terraform.goals.deploy import DeployTerraformFieldSet @@ -46,11 +45,11 @@ def _do_init_terraform( return initialised_files, initialised_entries -def find_file(files: DigestContents, pattern: str) -> Optional[FileContent]: +def find_file(files: DigestContents, pattern: str) -> FileContent | None: return next((file for file in files if Path(file.path).match(pattern)), None) -def find_link(entries: DigestEntries, pattern: str) -> Optional[SymlinkEntry]: +def find_link(entries: DigestEntries, pattern: str) -> SymlinkEntry | None: for entry in entries: if not isinstance(entry, SymlinkEntry): continue diff --git a/src/python/pants/backend/terraform/dependency_inference.py b/src/python/pants/backend/terraform/dependency_inference.py index fa61697a5ad..63893ad1be2 100644 --- a/src/python/pants/backend/terraform/dependency_inference.py +++ b/src/python/pants/backend/terraform/dependency_inference.py @@ -2,9 +2,9 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). from __future__ import annotations +from collections.abc import Iterable, Sequence from dataclasses import dataclass from pathlib import PurePath -from typing import Iterable, Optional, Sequence from pants.backend.python.subsystems.python_tool_base import PythonToolRequirementsBase from pants.backend.python.target_types import EntryPoint @@ -151,7 +151,7 @@ class TerraformDeploymentInvocationFiles: backend_configs: tuple[TerraformBackendTarget, ...] vars_files: tuple[TerraformVarFileTarget, ...] - lockfile: Optional[LockfileTarget] + lockfile: LockfileTarget | None @rule diff --git a/src/python/pants/backend/terraform/goals/check.py b/src/python/pants/backend/terraform/goals/check.py index 47f4d1d5f24..99a04b09b9c 100644 --- a/src/python/pants/backend/terraform/goals/check.py +++ b/src/python/pants/backend/terraform/goals/check.py @@ -1,7 +1,6 @@ # Copyright 2021 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). from dataclasses import dataclass -from typing import Union from pants.backend.terraform.dependencies import TerraformInitRequest, TerraformInitResponse from pants.backend.terraform.target_types import ( @@ -50,7 +49,7 @@ class TerraformCheckRequest(CheckRequest): def terraform_fieldset_to_init_request( - terraform_fieldset: Union[TerraformDeploymentFieldSet, TerraformFieldSet] + terraform_fieldset: TerraformDeploymentFieldSet | TerraformFieldSet, ) -> TerraformInitRequest: if isinstance(terraform_fieldset, TerraformDeploymentFieldSet): deployment = terraform_fieldset diff --git a/src/python/pants/backend/terraform/goals/check_test.py b/src/python/pants/backend/terraform/goals/check_test.py index b86d485cdde..a1dab27e91a 100644 --- a/src/python/pants/backend/terraform/goals/check_test.py +++ b/src/python/pants/backend/terraform/goals/check_test.py @@ -3,7 +3,7 @@ from __future__ import annotations import textwrap -from typing import Dict, Sequence +from collections.abc import Sequence import pytest @@ -221,7 +221,7 @@ def test_conflicting_provider_versions(rule_runner: RuleRunner) -> None: target_name = "in_folder" versions = ["3.2.1", "3.2.2"] - def make_terraform_module(version: str) -> Dict[str, str]: + def make_terraform_module(version: str) -> dict[str, str]: return { f"folder{version}/BUILD": textwrap.dedent( f"""\ diff --git a/src/python/pants/backend/terraform/goals/tailor.py b/src/python/pants/backend/terraform/goals/tailor.py index b89175ed899..d11f467ed69 100644 --- a/src/python/pants/backend/terraform/goals/tailor.py +++ b/src/python/pants/backend/terraform/goals/tailor.py @@ -5,7 +5,6 @@ import os.path from dataclasses import dataclass -from typing import List from pants.backend.terraform.target_types import ( TerraformBackendTarget, @@ -40,7 +39,7 @@ async def find_putative_terraform_module_targets( ) -> PutativeTargets: if not terraform.tailor: return PutativeTargets() - putative_targets: List[PutativeTarget] = [] + putative_targets: list[PutativeTarget] = [] all_terraform_files = await Get(Paths, PathGlobs, request.path_globs("*.tf")) unowned_terraform_files = set(all_terraform_files.files) - set(all_owned_sources) diff --git a/src/python/pants/backend/terraform/hcl2_parser.py b/src/python/pants/backend/terraform/hcl2_parser.py index 06dd38bb789..187c175d604 100644 --- a/src/python/pants/backend/terraform/hcl2_parser.py +++ b/src/python/pants/backend/terraform/hcl2_parser.py @@ -3,7 +3,6 @@ import sys from pathlib import PurePath -from typing import Set # # Note: This file is used as a pex entry point in the execution sandbox. @@ -27,7 +26,7 @@ def resolve_pure_path(base: PurePath, relative_path: PurePath) -> PurePath: return PurePath(*parts) -def extract_module_source_paths(path: PurePath, raw_content: bytes) -> Set[str]: +def extract_module_source_paths(path: PurePath, raw_content: bytes) -> set[str]: # Import here so we can still test this file with pytest (since `hcl2` is not present in # normal Pants venv.) import hcl2 # type: ignore[import-not-found] # pants: no-infer-dep diff --git a/src/python/pants/backend/terraform/lint/tffmt/tffmt_integration_test.py b/src/python/pants/backend/terraform/lint/tffmt/tffmt_integration_test.py index ef0fc918b52..714a4bd3b27 100644 --- a/src/python/pants/backend/terraform/lint/tffmt/tffmt_integration_test.py +++ b/src/python/pants/backend/terraform/lint/tffmt/tffmt_integration_test.py @@ -3,7 +3,7 @@ from __future__ import annotations import textwrap -from typing import List, NewType +from typing import NewType import pytest @@ -22,7 +22,7 @@ from pants.engine.target import Target from pants.testutil.rule_runner import QueryRule, RuleRunner -RuleRunnerOptions = NewType("RuleRunnerOptions", List[str]) +RuleRunnerOptions = NewType("RuleRunnerOptions", list[str]) available_tf_versions = [ @@ -105,7 +105,7 @@ def rule_runner() -> RuleRunner: def make_target( - rule_runner: RuleRunner, source_files: List[FileContent], *, target_name="target" + rule_runner: RuleRunner, source_files: list[FileContent], *, target_name="target" ) -> Target: rule_runner.write_files( { @@ -118,7 +118,7 @@ def make_target( def run_tffmt( rule_runner: RuleRunner, - targets: List[Target], + targets: list[Target], options: RuleRunnerOptions, ) -> FmtResult | None: rule_runner.set_options(options) @@ -159,7 +159,7 @@ def get_content(rule_runner: RuleRunner, digest: Digest) -> DigestContents: return rule_runner.request(DigestContents, [digest]) -def get_snapshot(rule_runner: RuleRunner, source_files: List[FileContent]) -> Snapshot: +def get_snapshot(rule_runner: RuleRunner, source_files: list[FileContent]) -> Snapshot: digest = rule_runner.request(Digest, [CreateDigest(source_files)]) return rule_runner.request(Snapshot, [digest]) diff --git a/src/python/pants/backend/terraform/partition.py b/src/python/pants/backend/terraform/partition.py index baa9db4a4a1..ac1fa4b8e57 100644 --- a/src/python/pants/backend/terraform/partition.py +++ b/src/python/pants/backend/terraform/partition.py @@ -5,7 +5,7 @@ import os from collections import defaultdict -from typing import Iterable +from collections.abc import Iterable def partition_files_by_directory(filepaths: Iterable[str]) -> dict[str, list[str]]: diff --git a/src/python/pants/backend/terraform/tool.py b/src/python/pants/backend/terraform/tool.py index cc7d5b4bc38..48467b0c9c3 100644 --- a/src/python/pants/backend/terraform/tool.py +++ b/src/python/pants/backend/terraform/tool.py @@ -18,9 +18,9 @@ import os import shlex +from collections.abc import Iterable from dataclasses import dataclass from pathlib import Path -from typing import Iterable, Tuple from pants.core.goals.resolves import ExportableTool from pants.core.util_rules import external_tool @@ -456,7 +456,7 @@ async def setup_terraform_process( "__terraform": downloaded_terraform.digest, } - def prepend_paths(paths: Tuple[str, ...]) -> Tuple[str, ...]: + def prepend_paths(paths: tuple[str, ...]) -> tuple[str, ...]: return tuple((Path(request.chdir) / path).as_posix() for path in paths) # Initialise the Terraform provider cache, since Terraform expects the directory to already exist. diff --git a/src/python/pants/backend/tools/preamble/subsystem.py b/src/python/pants/backend/tools/preamble/subsystem.py index 7aefb47d176..af46e04bcaf 100644 --- a/src/python/pants/backend/tools/preamble/subsystem.py +++ b/src/python/pants/backend/tools/preamble/subsystem.py @@ -2,7 +2,7 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). from __future__ import annotations -from typing import Sequence +from collections.abc import Sequence from pants.option.option_types import DictOption, SkipOption from pants.option.subsystem import Subsystem diff --git a/src/python/pants/backend/tools/semgrep/rules.py b/src/python/pants/backend/tools/semgrep/rules.py index 61323e90c77..b7cbfe15a4f 100644 --- a/src/python/pants/backend/tools/semgrep/rules.py +++ b/src/python/pants/backend/tools/semgrep/rules.py @@ -5,9 +5,9 @@ import itertools import logging from collections import defaultdict +from collections.abc import Iterable from dataclasses import dataclass from pathlib import PurePath -from typing import Iterable from pants.backend.python.util_rules import pex from pants.backend.python.util_rules.pex import VenvPexProcess, create_venv_pex diff --git a/src/python/pants/backend/tools/semgrep/rules_integration_test.py b/src/python/pants/backend/tools/semgrep/rules_integration_test.py index 126e00647d5..2bccd2c1099 100644 --- a/src/python/pants/backend/tools/semgrep/rules_integration_test.py +++ b/src/python/pants/backend/tools/semgrep/rules_integration_test.py @@ -3,8 +3,8 @@ from __future__ import annotations +from collections.abc import Sequence from textwrap import dedent -from typing import Sequence import pytest diff --git a/src/python/pants/backend/tools/semgrep/subsystem.py b/src/python/pants/backend/tools/semgrep/subsystem.py index 36b04cc648e..9c9273d49e6 100644 --- a/src/python/pants/backend/tools/semgrep/subsystem.py +++ b/src/python/pants/backend/tools/semgrep/subsystem.py @@ -3,8 +3,8 @@ from __future__ import annotations +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.python.subsystems.python_tool_base import PythonToolBase from pants.backend.python.target_types import ConsoleScript diff --git a/src/python/pants/backend/tools/trufflehog/rules.py b/src/python/pants/backend/tools/trufflehog/rules.py index 6299d624e05..84cafa386bc 100644 --- a/src/python/pants/backend/tools/trufflehog/rules.py +++ b/src/python/pants/backend/tools/trufflehog/rules.py @@ -4,7 +4,7 @@ from __future__ import annotations -from typing import Iterable +from collections.abc import Iterable from pants.backend.tools.trufflehog.subsystem import Trufflehog from pants.core.goals.lint import LintFilesRequest, LintResult diff --git a/src/python/pants/backend/tools/workunit_logger/rules.py b/src/python/pants/backend/tools/workunit_logger/rules.py index 65c2eac88a5..a41827ff1b9 100644 --- a/src/python/pants/backend/tools/workunit_logger/rules.py +++ b/src/python/pants/backend/tools/workunit_logger/rules.py @@ -2,7 +2,7 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). import json import logging -from typing import Any, Dict, Tuple +from typing import Any from pants.engine.internals.scheduler import Workunit from pants.engine.rules import collect_rules, rule @@ -48,7 +48,7 @@ class WorkunitLoggerCallback(WorkunitsCallback): def __init__(self, wulogger: "WorkunitLogger"): self.wulogger = wulogger - self._completed_workunits: Dict[str, object] = {} + self._completed_workunits: dict[str, object] = {} @property def can_finish_async(self) -> bool: @@ -57,8 +57,8 @@ def can_finish_async(self) -> bool: def __call__( self, *, - completed_workunits: Tuple[Workunit, ...], - started_workunits: Tuple[Workunit, ...], + completed_workunits: tuple[Workunit, ...], + started_workunits: tuple[Workunit, ...], context: StreamingWorkunitContext, finished: bool = False, **kwargs: Any, diff --git a/src/python/pants/backend/tools/yamllint/subsystem.py b/src/python/pants/backend/tools/yamllint/subsystem.py index 4bbb6b8f925..19b39e272d2 100644 --- a/src/python/pants/backend/tools/yamllint/subsystem.py +++ b/src/python/pants/backend/tools/yamllint/subsystem.py @@ -3,7 +3,7 @@ from __future__ import annotations -from typing import Iterable +from collections.abc import Iterable from pants.backend.python.subsystems.python_tool_base import PythonToolBase from pants.backend.python.target_types import ConsoleScript diff --git a/src/python/pants/backend/tsx/goals/tailor.py b/src/python/pants/backend/tsx/goals/tailor.py index 4f77c2d9d73..46ed0590222 100644 --- a/src/python/pants/backend/tsx/goals/tailor.py +++ b/src/python/pants/backend/tsx/goals/tailor.py @@ -4,8 +4,8 @@ from __future__ import annotations import dataclasses +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.tsx.target_types import ( TSX_FILE_EXTENSIONS, diff --git a/src/python/pants/backend/typescript/dependency_inference/rules.py b/src/python/pants/backend/typescript/dependency_inference/rules.py index 5e5aaa9ef53..0c285e2e37c 100644 --- a/src/python/pants/backend/typescript/dependency_inference/rules.py +++ b/src/python/pants/backend/typescript/dependency_inference/rules.py @@ -4,8 +4,8 @@ import itertools import os.path +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.backend.javascript import package_json from pants.backend.javascript.dependency_inference.rules import ( diff --git a/src/python/pants/backend/typescript/goals/tailor.py b/src/python/pants/backend/typescript/goals/tailor.py index 5afcdda6d98..b9e29e055cf 100644 --- a/src/python/pants/backend/typescript/goals/tailor.py +++ b/src/python/pants/backend/typescript/goals/tailor.py @@ -1,8 +1,8 @@ # Copyright 2023 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). import dataclasses +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable, Union from pants.backend.typescript.target_types import ( TS_FILE_EXTENSIONS, @@ -55,7 +55,7 @@ async def find_putative_ts_targets( ) -def rules() -> Iterable[Union[Rule, UnionRule]]: +def rules() -> Iterable[Rule | UnionRule]: return ( *collect_rules(), UnionRule(PutativeTargetsRequest, PutativeTypeScriptTargetsRequest), diff --git a/src/python/pants/backend/typescript/tsconfig.py b/src/python/pants/backend/typescript/tsconfig.py index c70e6fd0ff8..5d64fa35219 100644 --- a/src/python/pants/backend/typescript/tsconfig.py +++ b/src/python/pants/backend/typescript/tsconfig.py @@ -14,9 +14,10 @@ import logging import os import re +from collections.abc import Iterable from dataclasses import dataclass from pathlib import PurePath -from typing import Iterable, Literal +from typing import Literal from pants.engine.collection import Collection from pants.engine.fs import DigestContents, FileContent, PathGlobs diff --git a/src/python/pants/backend/visibility/glob.py b/src/python/pants/backend/visibility/glob.py index 79c7a2c5e6b..fb806412c01 100644 --- a/src/python/pants/backend/visibility/glob.py +++ b/src/python/pants/backend/visibility/glob.py @@ -8,7 +8,8 @@ from collections.abc import Mapping, Sequence from dataclasses import dataclass, field from enum import Enum -from typing import Any, Pattern +from re import Pattern +from typing import Any from pants.engine.addresses import Address from pants.engine.internals.target_adaptor import TargetAdaptor diff --git a/src/python/pants/backend/visibility/glob_test.py b/src/python/pants/backend/visibility/glob_test.py index 1896c099313..d59530c9b3f 100644 --- a/src/python/pants/backend/visibility/glob_test.py +++ b/src/python/pants/backend/visibility/glob_test.py @@ -4,7 +4,8 @@ import os import re -from typing import Any, Mapping +from collections.abc import Mapping +from typing import Any import pytest diff --git a/src/python/pants/backend/visibility/rule_types.py b/src/python/pants/backend/visibility/rule_types.py index 5148d98f994..31e84de3d48 100644 --- a/src/python/pants/backend/visibility/rule_types.py +++ b/src/python/pants/backend/visibility/rule_types.py @@ -5,10 +5,11 @@ import itertools import logging import os.path +from collections.abc import Iterable, Iterator, Sequence from dataclasses import dataclass, field from pathlib import PurePath from pprint import pformat -from typing import Any, Iterable, Iterator, Sequence, cast +from typing import Any, cast from pants.backend.visibility.glob import TargetGlob from pants.engine.addresses import Address From 5687703f019fb209e8b53506d5e0a323f2be46c4 Mon Sep 17 00:00:00 2001 From: sj Date: Mon, 3 Feb 2025 09:21:03 -0500 Subject: [PATCH 04/10] Upgraded the non-backend parts of Pants to 3.11 syntax --- src/python/pants/base/build_root.py | 4 +- src/python/pants/base/deprecated.py | 3 +- src/python/pants/base/exception_sink.py | 4 +- .../base/exception_sink_integration_test.py | 5 +- src/python/pants/base/parse_context.py | 3 +- src/python/pants/base/specs.py | 3 +- src/python/pants/base/specs_parser.py | 2 +- src/python/pants/bin/daemon_pants_runner.py | 9 +- .../pants/bin/loader_integration_test.py | 3 +- .../local_pants_runner_integration_test.py | 2 +- src/python/pants/bin/pants_runner.py | 4 +- src/python/pants/bin/remote_pants_runner.py | 4 +- src/python/pants/bsp/context.py | 2 +- src/python/pants/bsp/goal.py | 2 +- src/python/pants/bsp/testutil.py | 5 +- src/python/pants/bsp/util_rules/compile.py | 6 +- src/python/pants/bsp/util_rules/queries.py | 2 +- src/python/pants/bsp/util_rules/resources.py | 6 +- src/python/pants/bsp/util_rules/targets.py | 19 +- src/python/pants/build_graph/address.py | 2 +- .../pants/build_graph/build_configuration.py | 4 +- .../build_graph/build_configuration_test.py | 9 +- .../pants/build_graph/build_file_aliases.py | 3 +- .../subproject_integration_test.py | 2 +- src/python/pants/core/goals/check.py | 3 +- src/python/pants/core/goals/check_test.py | 8 +- src/python/pants/core/goals/deploy.py | 2 +- src/python/pants/core/goals/export.py | 3 +- src/python/pants/core/goals/export_test.py | 7 +- src/python/pants/core/goals/fix.py | 17 +- src/python/pants/core/goals/fix_test.py | 8 +- src/python/pants/core/goals/fmt.py | 2 +- .../pants/core/goals/generate_lockfiles.py | 7 +- .../core/goals/generate_lockfiles_test.py | 4 +- src/python/pants/core/goals/lint.py | 5 +- src/python/pants/core/goals/lint_test.py | 9 +- .../core/goals/multi_tool_goal_helper.py | 3 +- src/python/pants/core/goals/package.py | 2 +- src/python/pants/core/goals/publish.py | 6 +- src/python/pants/core/goals/repl.py | 9 +- src/python/pants/core/goals/run.py | 11 +- src/python/pants/core/goals/run_test.py | 3 +- src/python/pants/core/goals/tailor.py | 3 +- src/python/pants/core/goals/test.py | 11 +- src/python/pants/core/goals/test_test.py | 3 +- .../core/goals/update_build_files_test.py | 2 +- .../pants/core/subsystems/python_bootstrap.py | 6 +- .../core/subsystems/python_bootstrap_test.py | 5 +- src/python/pants/core/target_types.py | 7 +- .../core/util_rules/adhoc_process_support.py | 5 +- .../pants/core/util_rules/archive_test.py | 3 +- src/python/pants/core/util_rules/asdf.py | 2 +- src/python/pants/core/util_rules/asdf_test.py | 2 +- .../pants/core/util_rules/config_files.py | 2 +- .../pants/core/util_rules/environments.py | 11 +- .../core/util_rules/environments_test.py | 2 +- .../core/util_rules/lockfile_metadata.py | 11 +- src/python/pants/core/util_rules/ownership.py | 2 +- .../pants/core/util_rules/partitions.py | 3 +- .../pants/core/util_rules/search_paths.py | 3 +- .../core/util_rules/search_paths_test.py | 2 +- .../pants/core/util_rules/source_files.py | 16 +- .../core/util_rules/source_files_test.py | 3 +- .../util_rules/stripped_source_files_test.py | 2 +- .../core/util_rules/subprocess_environment.py | 3 +- .../pants/core/util_rules/system_binaries.py | 5 +- src/python/pants/core/util_rules/testutil.py | 3 +- .../pants/core/util_rules/wrap_source.py | 4 +- src/python/pants/engine/addresses.py | 2 +- src/python/pants/engine/collection.py | 7 +- src/python/pants/engine/console.py | 3 +- src/python/pants/engine/desktop.py | 6 +- src/python/pants/engine/download_file.py | 6 +- src/python/pants/engine/env_vars.py | 12 +- src/python/pants/engine/environment_test.py | 3 +- src/python/pants/engine/explorer.py | 3 +- src/python/pants/engine/fs.py | 13 +- src/python/pants/engine/fs_test.py | 13 +- src/python/pants/engine/goal.py | 7 +- .../pants/engine/internals/build_files.py | 3 +- .../engine/internals/build_files_test.py | 3 +- src/python/pants/engine/internals/defaults.py | 5 +- .../pants/engine/internals/defaults_test.py | 3 +- .../pants/engine/internals/engine_test.py | 9 +- .../pants/engine/internals/engine_testutil.py | 2 +- src/python/pants/engine/internals/graph.py | 17 +- .../pants/engine/internals/graph_test.py | 10 +- src/python/pants/engine/internals/mapper.py | 3 +- .../pants/engine/internals/native_engine.pyi | 50 ++-- src/python/pants/engine/internals/nodes.py | 4 +- .../pants/engine/internals/parametrize.py | 5 +- src/python/pants/engine/internals/parser.py | 3 +- .../pants/engine/internals/rule_visitor.py | 9 +- .../engine/internals/rule_visitor_test.py | 2 +- .../pants/engine/internals/scheduler.py | 5 +- .../pants/engine/internals/selectors.py | 17 +- .../pants/engine/internals/selectors_test.py | 2 +- src/python/pants/engine/internals/session.py | 6 +- .../pants/engine/internals/specs_rules.py | 2 +- .../engine/internals/specs_rules_test.py | 4 +- .../engine/internals/synthetic_targets.py | 3 +- .../pants/engine/internals/target_adaptor.py | 4 +- src/python/pants/engine/internals/testutil.py | 2 +- src/python/pants/engine/process.py | 6 +- src/python/pants/engine/rules.py | 61 ++--- src/python/pants/engine/rules_test.py | 25 +- .../engine/streaming_workunit_handler.py | 5 +- ...aming_workunit_handler_integration_test.py | 2 +- src/python/pants/engine/target.py | 219 +++++++++--------- src/python/pants/engine/target_test.py | 43 ++-- src/python/pants/engine/unions.py | 3 +- src/python/pants/goal/migrate_call_by_name.py | 3 +- .../pants/goal/migrate_call_by_name_test.py | 3 +- src/python/pants/goal/stats_aggregator.py | 8 +- src/python/pants/help/help_formatter_test.py | 3 +- src/python/pants/help/help_info_extracter.py | 24 +- .../pants/help/help_info_extracter_test.py | 9 +- src/python/pants/help/help_printer.py | 23 +- src/python/pants/help/help_tools.py | 3 +- src/python/pants/help/maybe_color.py | 3 +- src/python/pants/init/engine_initializer.py | 3 +- src/python/pants/init/extension_loader.py | 13 +- .../init/load_backends_integration_test.py | 5 +- src/python/pants/init/logging.py | 2 +- src/python/pants/init/options_initializer.py | 4 +- src/python/pants/init/plugin_resolver.py | 7 +- src/python/pants/jvm/classpath.py | 2 +- src/python/pants/jvm/compile.py | 3 +- src/python/pants/jvm/compile_test.py | 5 +- .../dependency_inference/artifact_mapper.py | 7 +- src/python/pants/jvm/goals/lockfile.py | 2 +- src/python/pants/jvm/jar_tool/jar_tool.py | 2 +- src/python/pants/jvm/jdk_rules.py | 3 +- .../pants/jvm/package/deploy_jar_test.py | 2 +- src/python/pants/jvm/package/war.py | 2 +- src/python/pants/jvm/resolve/common.py | 2 +- .../pants/jvm/resolve/coursier_fetch.py | 9 +- .../jvm/resolve/coursier_fetch_filter_test.py | 3 +- .../pants/jvm/resolve/coursier_setup.py | 9 +- .../pants/jvm/resolve/lockfile_metadata.py | 3 +- src/python/pants/jvm/run.py | 6 +- src/python/pants/jvm/shading/rules.py | 2 +- src/python/pants/jvm/strip_jar/strip_jar.py | 3 +- src/python/pants/jvm/target_types.py | 23 +- src/python/pants/jvm/test/junit_test.py | 2 +- src/python/pants/jvm/test/testutil.py | 2 +- src/python/pants/option/custom_types.py | 3 +- src/python/pants/option/custom_types_test.py | 8 +- src/python/pants/option/errors.py | 3 +- src/python/pants/option/global_options.py | 5 +- src/python/pants/option/native_options.py | 15 +- src/python/pants/option/option_types.py | 3 +- .../pants/option/option_value_container.py | 2 +- src/python/pants/option/options.py | 3 +- .../pants/option/options_bootstrapper.py | 3 +- src/python/pants/option/options_test.py | 7 +- src/python/pants/option/ranked_value.py | 9 +- src/python/pants/option/registrar.py | 3 +- src/python/pants/option/scope.py | 16 +- src/python/pants/option/subsystem.py | 3 +- src/python/pants/pantsd/pants_daemon_core.py | 3 +- src/python/pants/pantsd/process_manager.py | 3 +- .../pants/pantsd/service/pants_service.py | 10 +- .../pants/pantsd/service/scheduler_service.py | 8 +- src/python/pants/source/filespec_test.py | 7 +- src/python/pants/source/source_root.py | 2 +- src/python/pants/source/source_root_test.py | 8 +- src/python/pants/testutil/option_util.py | 3 +- .../pants/testutil/pants_integration_test.py | 7 +- src/python/pants/testutil/process_util.py | 2 +- .../testutil/python_interpreter_selection.py | 2 +- .../pants/testutil/python_rule_runner.py | 2 +- src/python/pants/testutil/rule_runner.py | 29 +-- src/python/pants/util/collections.py | 3 +- src/python/pants/util/contextutil.py | 3 +- src/python/pants/util/contextutil_test.py | 2 +- src/python/pants/util/cstutil.py | 3 +- src/python/pants/util/dirutil.py | 3 +- src/python/pants/util/dirutil_test.py | 2 +- src/python/pants/util/enums.py | 5 +- src/python/pants/util/filtering_test.py | 2 +- src/python/pants/util/frozendict.py | 3 +- src/python/pants/util/memo.py | 17 +- src/python/pants/util/meta.py | 15 +- src/python/pants/util/ordered_set.py | 5 +- src/python/pants/util/ordered_set_test.py | 11 +- src/python/pants/util/requirements.py | 2 +- src/python/pants/util/strutil.py | 3 +- src/python/pants/util/value_interpolation.py | 3 +- src/python/pants/vcs/changed.py | 2 +- .../pants/vcs/changed_integration_test.py | 2 +- src/python/pants/vcs/git.py | 3 +- src/python/pants/vcs/git_test.py | 3 +- src/python/pants/vcs/hunk.py | 5 +- .../generate_github_workflows.py | 9 +- src/python/pants_release/release.py | 3 +- 196 files changed, 695 insertions(+), 738 deletions(-) diff --git a/src/python/pants/base/build_root.py b/src/python/pants/base/build_root.py index 86c206a2cee..c6b3098cd56 100644 --- a/src/python/pants/base/build_root.py +++ b/src/python/pants/base/build_root.py @@ -2,9 +2,9 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). import os +from collections.abc import Iterator from contextlib import contextmanager from pathlib import Path -from typing import Iterator, Optional from pants.util.meta import SingletonMetaclass @@ -36,7 +36,7 @@ def find_buildroot(self) -> str: return str(buildroot) def __init__(self) -> None: - self._root_dir: Optional[str] = None + self._root_dir: str | None = None @property def pathlib_path(self) -> Path: diff --git a/src/python/pants/base/deprecated.py b/src/python/pants/base/deprecated.py index d065b73c333..abbb3965f67 100644 --- a/src/python/pants/base/deprecated.py +++ b/src/python/pants/base/deprecated.py @@ -5,8 +5,9 @@ import inspect import logging +from collections.abc import Callable from functools import wraps -from typing import Any, Callable, TypeVar +from typing import Any, TypeVar from packaging.version import InvalidVersion, Version diff --git a/src/python/pants/base/exception_sink.py b/src/python/pants/base/exception_sink.py index 665cdc4f475..fd9d3fe3dd0 100644 --- a/src/python/pants/base/exception_sink.py +++ b/src/python/pants/base/exception_sink.py @@ -10,8 +10,8 @@ import sys import threading import traceback +from collections.abc import Callable, Iterator from contextlib import contextmanager -from typing import Callable, Dict, Iterator import psutil import setproctitle @@ -34,7 +34,7 @@ class SignalHandler: """ @property - def signal_handler_mapping(self) -> Dict[signal.Signals, Callable]: + def signal_handler_mapping(self) -> dict[signal.Signals, Callable]: """A dict mapping (signal number) -> (a method handling the signal).""" # Could use an enum here, but we never end up doing any matching on the specific signal value, # instead just iterating over the registered signals to set handlers, so a dict is probably diff --git a/src/python/pants/base/exception_sink_integration_test.py b/src/python/pants/base/exception_sink_integration_test.py index 4ac1b53779e..6e9b4a56341 100644 --- a/src/python/pants/base/exception_sink_integration_test.py +++ b/src/python/pants/base/exception_sink_integration_test.py @@ -6,7 +6,6 @@ import signal import time from pathlib import Path -from typing import List, Tuple import pytest @@ -19,7 +18,7 @@ pytestmark = pytest.mark.platform_specific_behavior -def lifecycle_stub_cmdline() -> List[str]: +def lifecycle_stub_cmdline() -> list[str]: # Load the testprojects pants-plugins to get some testing tasks and subsystems. testproject_backend_src_dir = os.path.join( get_buildroot(), "testprojects/pants-plugins/src/python" @@ -36,7 +35,7 @@ def lifecycle_stub_cmdline() -> List[str]: return lifecycle_stub_cmdline -def get_log_file_paths(workdir: str, pid: int) -> Tuple[str, str]: +def get_log_file_paths(workdir: str, pid: int) -> tuple[str, str]: pid_specific_log_file = ExceptionSink.exceptions_log_path(for_pid=pid, in_dir=workdir) assert os.path.isfile(pid_specific_log_file) diff --git a/src/python/pants/base/parse_context.py b/src/python/pants/base/parse_context.py index 910bc5d3cfc..2bb7d27347f 100644 --- a/src/python/pants/base/parse_context.py +++ b/src/python/pants/base/parse_context.py @@ -2,7 +2,8 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). import os -from typing import Any, Mapping, Protocol +from collections.abc import Mapping +from typing import Any, Protocol class FilePathOracle(Protocol): diff --git a/src/python/pants/base/specs.py b/src/python/pants/base/specs.py index e6bd7c5b74f..508cb7dbcff 100644 --- a/src/python/pants/base/specs.py +++ b/src/python/pants/base/specs.py @@ -5,8 +5,9 @@ import os from abc import ABC, abstractmethod +from collections.abc import Iterable, Iterator from dataclasses import dataclass -from typing import ClassVar, Iterable, Iterator, Protocol, cast +from typing import ClassVar, Protocol, cast from pants.base.glob_match_error_behavior import GlobMatchErrorBehavior from pants.build_graph.address import Address diff --git a/src/python/pants/base/specs_parser.py b/src/python/pants/base/specs_parser.py index 507014878a8..3154a697e83 100644 --- a/src/python/pants/base/specs_parser.py +++ b/src/python/pants/base/specs_parser.py @@ -4,8 +4,8 @@ from __future__ import annotations import os.path +from collections.abc import Iterable from pathlib import Path, PurePath -from typing import Iterable from pants.base.build_environment import get_buildroot from pants.base.glob_match_error_behavior import GlobMatchErrorBehavior diff --git a/src/python/pants/bin/daemon_pants_runner.py b/src/python/pants/bin/daemon_pants_runner.py index 40e1765b275..48a455b36d3 100644 --- a/src/python/pants/bin/daemon_pants_runner.py +++ b/src/python/pants/bin/daemon_pants_runner.py @@ -7,7 +7,6 @@ import time from contextlib import contextmanager from threading import Lock -from typing import Dict, Tuple from pants.base.exiter import PANTS_FAILED_EXIT_CODE, ExitCode from pants.bin.local_pants_runner import LocalPantsRunner @@ -97,8 +96,8 @@ def should_keep_polling(now): def single_daemonized_run( self, - args: Tuple[str, ...], - env: Dict[str, str], + args: tuple[str, ...], + env: dict[str, str], working_dir: str, cancellation_latch: PySessionCancellationLatch, ) -> ExitCode: @@ -150,8 +149,8 @@ def single_daemonized_run( def __call__( self, command: str, - args: Tuple[str, ...], - env: Dict[str, str], + args: tuple[str, ...], + env: dict[str, str], working_dir: str, cancellation_latch: PySessionCancellationLatch, stdin_fileno: int, diff --git a/src/python/pants/bin/loader_integration_test.py b/src/python/pants/bin/loader_integration_test.py index a198b80deb2..6a49d6a8e73 100644 --- a/src/python/pants/bin/loader_integration_test.py +++ b/src/python/pants/bin/loader_integration_test.py @@ -2,7 +2,6 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). import os -from typing import Union from pants.bin.pants_env_vars import ( DAEMON_ENTRYPOINT, @@ -86,7 +85,7 @@ def run(limit: str) -> PantsResult: def test_non_utf8_env_vars() -> None: - env: dict[Union[str, bytes], Union[str, bytes]] = { + env: dict[str | bytes, str | bytes] = { "FOO": b"B\xa5R", b"F\xa5O": "BAR", } diff --git a/src/python/pants/bin/local_pants_runner_integration_test.py b/src/python/pants/bin/local_pants_runner_integration_test.py index c53f3d9ef7c..c195f5b2b03 100644 --- a/src/python/pants/bin/local_pants_runner_integration_test.py +++ b/src/python/pants/bin/local_pants_runner_integration_test.py @@ -1,7 +1,7 @@ # Copyright 2021 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). -from typing import Sequence +from collections.abc import Sequence from pants.testutil.pants_integration_test import PantsResult, run_pants diff --git a/src/python/pants/bin/pants_runner.py b/src/python/pants/bin/pants_runner.py index 3cf16efa054..ec92eafeac4 100644 --- a/src/python/pants/bin/pants_runner.py +++ b/src/python/pants/bin/pants_runner.py @@ -6,8 +6,8 @@ import platform import sys import warnings +from collections.abc import Mapping from dataclasses import dataclass -from typing import List, Mapping from packaging.version import Version @@ -35,7 +35,7 @@ class PantsRunner: """A higher-level runner that delegates runs to either a LocalPantsRunner or RemotePantsRunner.""" - args: List[str] + args: list[str] env: Mapping[str, str] # This could be a bootstrap option, but it's preferable to keep these very limited to make it diff --git a/src/python/pants/bin/remote_pants_runner.py b/src/python/pants/bin/remote_pants_runner.py index da1deecea06..b040f469eac 100644 --- a/src/python/pants/bin/remote_pants_runner.py +++ b/src/python/pants/bin/remote_pants_runner.py @@ -7,8 +7,8 @@ import sys import termios import time +from collections.abc import Mapping from contextlib import contextmanager -from typing import List, Mapping from pants.base.exiter import ExitCode from pants.engine.internals.native_engine import ( @@ -97,7 +97,7 @@ class Terminated(Exception): def __init__( self, - args: List[str], + args: list[str], env: Mapping[str, str], options_bootstrapper: OptionsBootstrapper, ) -> None: diff --git a/src/python/pants/bsp/context.py b/src/python/pants/bsp/context.py index e7d322317a6..f73a0459213 100644 --- a/src/python/pants/bsp/context.py +++ b/src/python/pants/bsp/context.py @@ -3,8 +3,8 @@ from __future__ import annotations import threading +from collections.abc import Callable from pathlib import Path -from typing import Callable from pants.bsp.spec.lifecycle import InitializeBuildParams from pants.bsp.spec.notification import BSPNotification diff --git a/src/python/pants/bsp/goal.py b/src/python/pants/bsp/goal.py index c5577c975f7..7a24c5b5c29 100644 --- a/src/python/pants/bsp/goal.py +++ b/src/python/pants/bsp/goal.py @@ -8,7 +8,7 @@ import shlex import sys import textwrap -from typing import Mapping +from collections.abc import Mapping from pants.base.build_root import BuildRoot from pants.base.exiter import PANTS_FAILED_EXIT_CODE, PANTS_SUCCEEDED_EXIT_CODE, ExitCode diff --git a/src/python/pants/bsp/testutil.py b/src/python/pants/bsp/testutil.py index 84bbc585694..920a56d8acf 100644 --- a/src/python/pants/bsp/testutil.py +++ b/src/python/pants/bsp/testutil.py @@ -5,10 +5,11 @@ import functools import os +from collections.abc import Iterable from contextlib import contextmanager from dataclasses import dataclass from threading import Thread -from typing import Any, BinaryIO, Dict, Iterable, Tuple +from typing import Any, BinaryIO from pylsp_jsonrpc.endpoint import Endpoint # type: ignore[import-untyped] from pylsp_jsonrpc.streams import ( # type: ignore[import-untyped] @@ -58,7 +59,7 @@ def setup_pipes(): # A notification method name, and a subset of its fields. -NotificationSubset = Tuple[str, Dict[str, Any]] +NotificationSubset = tuple[str, dict[str, Any]] @dataclass diff --git a/src/python/pants/bsp/util_rules/compile.py b/src/python/pants/bsp/util_rules/compile.py index bb83ecffc75..b83f4cb6e8e 100644 --- a/src/python/pants/bsp/util_rules/compile.py +++ b/src/python/pants/bsp/util_rules/compile.py @@ -7,7 +7,7 @@ import uuid from collections import defaultdict from dataclasses import dataclass -from typing import Type, TypeVar +from typing import TypeVar from pants.bsp.context import BSPContext from pants.bsp.protocol import BSPHandlerMapping @@ -53,10 +53,10 @@ async def compile_bsp_target( union_membership: UnionMembership, ) -> BSPCompileResult: targets = await Get(Targets, BSPBuildTargetInternal, request.bsp_target) - compile_request_types: FrozenOrderedSet[Type[BSPCompileRequest]] = union_membership.get( + compile_request_types: FrozenOrderedSet[type[BSPCompileRequest]] = union_membership.get( BSPCompileRequest ) - field_sets_by_request_type: dict[Type[BSPCompileRequest], set[FieldSet]] = defaultdict(set) + field_sets_by_request_type: dict[type[BSPCompileRequest], set[FieldSet]] = defaultdict(set) for target in targets: for compile_request_type in compile_request_types: field_set_type = compile_request_type.field_set_type diff --git a/src/python/pants/bsp/util_rules/queries.py b/src/python/pants/bsp/util_rules/queries.py index ff22433a79a..86c5c82de8e 100644 --- a/src/python/pants/bsp/util_rules/queries.py +++ b/src/python/pants/bsp/util_rules/queries.py @@ -2,7 +2,7 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). from __future__ import annotations -from typing import Iterable +from collections.abc import Iterable from pants.bsp.protocol import BSPHandlerMapping from pants.engine.environment import EnvironmentName diff --git a/src/python/pants/bsp/util_rules/resources.py b/src/python/pants/bsp/util_rules/resources.py index c5d4722af0c..33b3a4c4e91 100644 --- a/src/python/pants/bsp/util_rules/resources.py +++ b/src/python/pants/bsp/util_rules/resources.py @@ -5,7 +5,7 @@ import logging from collections import defaultdict from dataclasses import dataclass -from typing import Type, TypeVar +from typing import TypeVar from pants.bsp.protocol import BSPHandlerMapping from pants.bsp.spec.base import BuildTargetIdentifier @@ -45,10 +45,10 @@ async def resources_bsp_target( union_membership: UnionMembership, ) -> BSPResourcesResult: targets = await Get(Targets, BSPBuildTargetInternal, request.bsp_target) - resources_request_types: FrozenOrderedSet[Type[BSPResourcesRequest]] = union_membership.get( + resources_request_types: FrozenOrderedSet[type[BSPResourcesRequest]] = union_membership.get( BSPResourcesRequest ) - field_sets_by_request_type: dict[Type[BSPResourcesRequest], set[FieldSet]] = defaultdict(set) + field_sets_by_request_type: dict[type[BSPResourcesRequest], set[FieldSet]] = defaultdict(set) for target in targets: for resources_request_type in resources_request_types: field_set_type = resources_request_type.field_set_type diff --git a/src/python/pants/bsp/util_rules/targets.py b/src/python/pants/bsp/util_rules/targets.py index 1999d246690..79d0e4102af 100644 --- a/src/python/pants/bsp/util_rules/targets.py +++ b/src/python/pants/bsp/util_rules/targets.py @@ -5,9 +5,10 @@ import itertools import logging from collections import defaultdict +from collections.abc import Sequence from dataclasses import dataclass from pathlib import Path -from typing import ClassVar, Generic, Sequence, Type, TypeVar +from typing import ClassVar, Generic, TypeVar import toml @@ -74,7 +75,7 @@ class BSPBuildTargetsMetadataRequest(Generic[_FS]): language_id: ClassVar[str] can_merge_metadata_from: ClassVar[tuple[str, ...]] - field_set_type: ClassVar[Type[_FS]] # type: ignore[misc] + field_set_type: ClassVar[type[_FS]] # type: ignore[misc] resolve_prefix: ClassVar[str] resolve_field: ClassVar[type[Field]] @@ -358,7 +359,7 @@ async def generate_one_bsp_build_target_request( field_sets_by_request_type: dict[type[BSPBuildTargetsMetadataRequest], OrderedSet[FieldSet]] = ( defaultdict(OrderedSet) ) - metadata_request_types: FrozenOrderedSet[Type[BSPBuildTargetsMetadataRequest]] = ( + metadata_request_types: FrozenOrderedSet[type[BSPBuildTargetsMetadataRequest]] = ( union_membership.get(BSPBuildTargetsMetadataRequest) ) metadata_request_types_by_lang_id: dict[str, type[BSPBuildTargetsMetadataRequest]] = {} @@ -375,7 +376,7 @@ async def generate_one_bsp_build_target_request( for tgt in targets: for metadata_request_type in metadata_request_types: - field_set_type: Type[FieldSet] = metadata_request_type.field_set_type + field_set_type: type[FieldSet] = metadata_request_type.field_set_type if field_set_type.is_applicable(tgt): field_sets_by_request_type[metadata_request_type].add(field_set_type.create(tgt)) @@ -541,7 +542,7 @@ async def bsp_dependency_sources(request: DependencySourcesParams) -> Dependency class BSPDependencyModulesRequest(Generic[_FS]): """Hook to allow language backends to provide dependency modules.""" - field_set_type: ClassVar[Type[_FS]] # type: ignore[misc] + field_set_type: ClassVar[type[_FS]] # type: ignore[misc] field_sets: tuple[_FS, ...] @@ -577,10 +578,10 @@ async def resolve_one_dependency_module( ) -> ResolveOneDependencyModuleResult: targets = await Get(Targets, BuildTargetIdentifier, request.bsp_target_id) - field_sets_by_request_type: dict[Type[BSPDependencyModulesRequest], list[FieldSet]] = ( + field_sets_by_request_type: dict[type[BSPDependencyModulesRequest], list[FieldSet]] = ( defaultdict(list) ) - dep_module_request_types: FrozenOrderedSet[Type[BSPDependencyModulesRequest]] = ( + dep_module_request_types: FrozenOrderedSet[type[BSPDependencyModulesRequest]] = ( union_membership.get(BSPDependencyModulesRequest) ) for tgt in targets: @@ -639,7 +640,7 @@ async def bsp_dependency_modules( class BSPCompileRequest(Generic[_FS]): """Hook to allow language backends to compile targets.""" - field_set_type: ClassVar[Type[_FS]] # type: ignore[misc] + field_set_type: ClassVar[type[_FS]] # type: ignore[misc] bsp_target: BSPBuildTargetInternal field_sets: tuple[_FS, ...] @@ -669,7 +670,7 @@ class BSPCompileResult: class BSPResourcesRequest(Generic[_FS]): """Hook to allow language backends to provide resources for targets.""" - field_set_type: ClassVar[Type[_FS]] # type: ignore[misc] + field_set_type: ClassVar[type[_FS]] # type: ignore[misc] bsp_target: BSPBuildTargetInternal field_sets: tuple[_FS, ...] diff --git a/src/python/pants/build_graph/address.py b/src/python/pants/build_graph/address.py index d2554d9463f..686fb730696 100644 --- a/src/python/pants/build_graph/address.py +++ b/src/python/pants/build_graph/address.py @@ -4,8 +4,8 @@ from __future__ import annotations import dataclasses +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from pants.base.exceptions import MappingError from pants.engine.engine_aware import EngineAwareParameter diff --git a/src/python/pants/build_graph/build_configuration.py b/src/python/pants/build_graph/build_configuration.py index 9f7d9bc9f0c..5feeda0d2de 100644 --- a/src/python/pants/build_graph/build_configuration.py +++ b/src/python/pants/build_graph/build_configuration.py @@ -5,10 +5,10 @@ import logging from collections import defaultdict -from collections.abc import Iterable +from collections.abc import Callable, Iterable from dataclasses import dataclass, field from enum import Enum -from typing import Any, Callable, DefaultDict +from typing import Any, DefaultDict from pants.backend.project_info.filter_targets import FilterSubsystem from pants.build_graph.build_file_aliases import BuildFileAliases diff --git a/src/python/pants/build_graph/build_configuration_test.py b/src/python/pants/build_graph/build_configuration_test.py index 0880cd442c2..620580a4e18 100644 --- a/src/python/pants/build_graph/build_configuration_test.py +++ b/src/python/pants/build_graph/build_configuration_test.py @@ -1,7 +1,6 @@ # Copyright 2014 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). -from typing import Type import pytest @@ -79,13 +78,13 @@ class B: def test_validation(caplog, bc_builder: BuildConfiguration.Builder) -> None: - def mk_dummy_subsys(_options_scope: str, goal: bool = False) -> Type[Subsystem]: + def mk_dummy_subsys(_options_scope: str, goal: bool = False) -> type[Subsystem]: class DummySubsystem(GoalSubsystem if goal else Subsystem): # type: ignore[misc] options_scope = _options_scope return DummySubsystem - def mk_dummy_tgt(_alias: str) -> Type[Target]: + def mk_dummy_tgt(_alias: str) -> type[Target]: class DummyTarget(Target): alias = _alias core_fields = tuple() @@ -120,7 +119,7 @@ class DummyTarget(Target): def test_register_subsystems(bc_builder: BuildConfiguration.Builder) -> None: - def mk_dummy_subsys(_options_scope: str) -> Type[Subsystem]: + def mk_dummy_subsys(_options_scope: str) -> type[Subsystem]: class DummySubsystem(Subsystem): options_scope = _options_scope @@ -147,7 +146,7 @@ class DummySubsystem(Subsystem): def test_register_target_types(bc_builder: BuildConfiguration.Builder) -> None: - def mk_dummy_tgt(_alias: str) -> Type[Target]: + def mk_dummy_tgt(_alias: str) -> type[Target]: class DummyTarget(Target): alias = _alias core_fields = tuple() diff --git a/src/python/pants/build_graph/build_file_aliases.py b/src/python/pants/build_graph/build_file_aliases.py index c8fd9039557..33dd570bc86 100644 --- a/src/python/pants/build_graph/build_file_aliases.py +++ b/src/python/pants/build_graph/build_file_aliases.py @@ -3,8 +3,9 @@ from __future__ import annotations +from collections.abc import Callable, Mapping from dataclasses import dataclass -from typing import Any, Callable, Mapping +from typing import Any from pants.base.parse_context import ParseContext from pants.util.frozendict import FrozenDict diff --git a/src/python/pants/build_graph/subproject_integration_test.py b/src/python/pants/build_graph/subproject_integration_test.py index 3256803f9fd..957d28854e6 100644 --- a/src/python/pants/build_graph/subproject_integration_test.py +++ b/src/python/pants/build_graph/subproject_integration_test.py @@ -1,9 +1,9 @@ # Copyright 2017 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). +from collections.abc import Iterator from contextlib import contextmanager from textwrap import dedent -from typing import Iterator from pants.testutil.pants_integration_test import run_pants from pants.util.dirutil import safe_file_dump, safe_rmtree diff --git a/src/python/pants/core/goals/check.py b/src/python/pants/core/goals/check.py index ae13e3cb704..2f1893d77ac 100644 --- a/src/python/pants/core/goals/check.py +++ b/src/python/pants/core/goals/check.py @@ -5,8 +5,9 @@ import logging from collections import defaultdict +from collections.abc import Iterable from dataclasses import dataclass -from typing import Any, ClassVar, Generic, Iterable, TypeVar, cast +from typing import Any, ClassVar, Generic, TypeVar, cast from pants.core.goals.lint import REPORT_DIR as REPORT_DIR # noqa: F401 from pants.core.goals.multi_tool_goal_helper import ( diff --git a/src/python/pants/core/goals/check_test.py b/src/python/pants/core/goals/check_test.py index ebbfc5d28fc..97d0d0ad4b8 100644 --- a/src/python/pants/core/goals/check_test.py +++ b/src/python/pants/core/goals/check_test.py @@ -4,9 +4,9 @@ from __future__ import annotations from abc import ABCMeta, abstractmethod +from collections.abc import Iterable, Sequence from pathlib import Path from textwrap import dedent -from typing import Iterable, Optional, Sequence, Tuple, Type import pytest @@ -143,7 +143,7 @@ def exit_code(_: Iterable[Address]) -> int: return -1 -def make_target(address: Optional[Address] = None) -> Target: +def make_target(address: Address | None = None) -> Target: if address is None: address = Address("", target_name="tests") return MockTarget({}, address) @@ -151,10 +151,10 @@ def make_target(address: Optional[Address] = None) -> Target: def run_typecheck_rule( *, - request_types: Sequence[Type[CheckRequest]], + request_types: Sequence[type[CheckRequest]], targets: list[Target], only: list[str] | None = None, -) -> Tuple[int, str]: +) -> tuple[int, str]: union_membership = UnionMembership({CheckRequest: request_types}) check_subsystem = create_subsystem(CheckSubsystem, only=only or []) rule_runner = RuleRunner(bootstrap_args=["-lwarn"]) diff --git a/src/python/pants/core/goals/deploy.py b/src/python/pants/core/goals/deploy.py index d3190508da8..61aa342620d 100644 --- a/src/python/pants/core/goals/deploy.py +++ b/src/python/pants/core/goals/deploy.py @@ -5,9 +5,9 @@ import logging from abc import ABCMeta +from collections.abc import Iterable from dataclasses import dataclass from itertools import chain -from typing import Iterable from pants.core.goals.package import PackageFieldSet from pants.core.goals.publish import PublishFieldSet, PublishProcesses, PublishProcessesRequest diff --git a/src/python/pants/core/goals/export.py b/src/python/pants/core/goals/export.py index 250d1011c27..0af67083f4a 100644 --- a/src/python/pants/core/goals/export.py +++ b/src/python/pants/core/goals/export.py @@ -6,9 +6,10 @@ import itertools import os from collections import defaultdict +from collections.abc import Iterable, Mapping, Sequence from dataclasses import dataclass from pathlib import Path -from typing import Iterable, Mapping, Sequence, cast +from typing import cast from pants.base.build_root import BuildRoot from pants.core.goals.generate_lockfiles import ( diff --git a/src/python/pants/core/goals/export_test.py b/src/python/pants/core/goals/export_test.py index 8467c1089d8..c0017134a53 100644 --- a/src/python/pants/core/goals/export_test.py +++ b/src/python/pants/core/goals/export_test.py @@ -6,7 +6,6 @@ import os import subprocess from pathlib import Path -from typing import List, Tuple from _pytest.monkeypatch import MonkeyPatch @@ -89,9 +88,9 @@ def list_files_with_paths(directory): def run_export_rule( rule_runner: RuleRunner, monkeypatch: MonkeyPatch, - resolves: List[str] | None = None, - binaries: List[str] | None = None, -) -> Tuple[int, str]: + resolves: list[str] | None = None, + binaries: list[str] | None = None, +) -> tuple[int, str]: resolves = resolves or [] binaries = binaries or [] union_membership = UnionMembership({ExportRequest: [MockExportRequest]}) diff --git a/src/python/pants/core/goals/fix.py b/src/python/pants/core/goals/fix.py index 76b81694887..52fd152d297 100644 --- a/src/python/pants/core/goals/fix.py +++ b/src/python/pants/core/goals/fix.py @@ -6,20 +6,9 @@ import itertools import logging from collections import defaultdict +from collections.abc import Callable, Iterable, Iterator, Sequence from dataclasses import dataclass -from typing import ( - Any, - Callable, - ClassVar, - Iterable, - Iterator, - NamedTuple, - Protocol, - Sequence, - Tuple, - Type, - TypeVar, -) +from typing import Any, ClassVar, NamedTuple, Protocol, TypeVar from pants.base.specs import Specs from pants.core.goals.lint import ( @@ -346,7 +335,7 @@ def batch_by_size(files: Iterable[str]) -> Iterator[tuple[str, ...]]: yield tuple(batch) def _make_disjoint_batch_requests() -> Iterable[_FixBatchRequest]: - partition_infos: Iterable[Tuple[Type[AbstractFixRequest], Any]] + partition_infos: Iterable[tuple[type[AbstractFixRequest], Any]] files: Sequence[str] partition_infos_by_files = defaultdict(list) diff --git a/src/python/pants/core/goals/fix_test.py b/src/python/pants/core/goals/fix_test.py index 7f7cba3b333..4a98602b5fd 100644 --- a/src/python/pants/core/goals/fix_test.py +++ b/src/python/pants/core/goals/fix_test.py @@ -7,10 +7,10 @@ import itertools import logging import re +from collections.abc import Iterable from dataclasses import dataclass from pathlib import Path, PurePath from textwrap import dedent -from typing import Iterable, List, Type import pytest @@ -254,8 +254,8 @@ def brickify(contents: bytes) -> bytes: def fix_rule_runner( - target_types: List[Type[Target]], - request_types: List[Type[AbstractFixRequest]] = [], + target_types: list[type[Target]], + request_types: list[type[AbstractFixRequest]] = [], ) -> RuleRunner: return RuleRunner( rules=[ @@ -272,7 +272,7 @@ def fix_rule_runner( def run_fix( rule_runner: RuleRunner, *, - target_specs: List[str], + target_specs: list[str], only: list[str] | None = None, extra_args: Iterable[str] = (), ) -> str: diff --git a/src/python/pants/core/goals/fmt.py b/src/python/pants/core/goals/fmt.py index b6fc499591a..5abcfcf038d 100644 --- a/src/python/pants/core/goals/fmt.py +++ b/src/python/pants/core/goals/fmt.py @@ -4,7 +4,7 @@ from __future__ import annotations import logging -from typing import Iterable +from collections.abc import Iterable from pants.base.specs import Specs from pants.core.goals.fix import AbstractFixRequest, FixFilesRequest, FixResult, FixTargetsRequest diff --git a/src/python/pants/core/goals/generate_lockfiles.py b/src/python/pants/core/goals/generate_lockfiles.py index 220b6a4a366..395404ff1ab 100644 --- a/src/python/pants/core/goals/generate_lockfiles.py +++ b/src/python/pants/core/goals/generate_lockfiles.py @@ -6,9 +6,10 @@ import itertools import logging from collections import defaultdict +from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence from dataclasses import dataclass, replace from enum import Enum -from typing import Callable, Iterable, Iterator, Mapping, Protocol, Sequence, Tuple, Type, cast +from typing import Protocol, cast from pants.core.goals.resolves import ExportableTool from pants.engine.collection import Collection, DeduplicatedCollection @@ -134,7 +135,7 @@ def __str__(self) -> str: ... PackageName = str LockfilePackages = FrozenDict[PackageName, PackageVersion] -ChangedPackages = FrozenDict[PackageName, Tuple[PackageVersion, PackageVersion]] +ChangedPackages = FrozenDict[PackageName, tuple[PackageVersion, PackageVersion]] @dataclass(frozen=True) @@ -379,7 +380,7 @@ def determine_resolves_to_generate( def filter_lockfiles_for_unconfigured_exportable_tools( generate_lockfile_requests: Sequence[GenerateLockfile], - exportabletools_by_name: dict[str, Type[ExportableTool]], + exportabletools_by_name: dict[str, type[ExportableTool]], *, resolve_specified: bool, ) -> tuple[tuple[str, ...], tuple[GenerateLockfile, ...]]: diff --git a/src/python/pants/core/goals/generate_lockfiles_test.py b/src/python/pants/core/goals/generate_lockfiles_test.py index 63fe88db4c6..30157e50eaa 100644 --- a/src/python/pants/core/goals/generate_lockfiles_test.py +++ b/src/python/pants/core/goals/generate_lockfiles_test.py @@ -4,9 +4,9 @@ from __future__ import annotations import re -from collections.abc import Mapping +from collections.abc import Iterable, Mapping from dataclasses import asdict -from typing import Any, Iterable +from typing import Any from unittest.mock import Mock import pytest diff --git a/src/python/pants/core/goals/lint.py b/src/python/pants/core/goals/lint.py index 9b59207bab4..1100c60bc3d 100644 --- a/src/python/pants/core/goals/lint.py +++ b/src/python/pants/core/goals/lint.py @@ -5,10 +5,9 @@ import logging from collections import defaultdict +from collections.abc import Callable, Iterable, Iterator, Sequence from dataclasses import dataclass -from typing import Any, Callable, ClassVar, Iterable, Iterator, Protocol, Sequence, TypeVar, cast - -from typing_extensions import final +from typing import Any, ClassVar, Protocol, TypeVar, cast, final from pants.base.specs import Specs from pants.core.goals.multi_tool_goal_helper import ( diff --git a/src/python/pants/core/goals/lint_test.py b/src/python/pants/core/goals/lint_test.py index ee8c5b3b6f2..bae3db31573 100644 --- a/src/python/pants/core/goals/lint_test.py +++ b/src/python/pants/core/goals/lint_test.py @@ -4,10 +4,11 @@ from __future__ import annotations from abc import ABCMeta, abstractmethod +from collections.abc import Iterable from dataclasses import dataclass from pathlib import Path from textwrap import dedent -from typing import Any, Iterable, Optional, Tuple, Type, TypeVar +from typing import Any, TypeVar import pytest @@ -312,7 +313,7 @@ def rule_runner() -> RuleRunner: return RuleRunner() -def make_target(address: Optional[Address] = None) -> Target: +def make_target(address: Address | None = None) -> Target: return MockTarget( {MockRequiredField.alias: "present"}, address or Address("", target_name="tests") ) @@ -321,13 +322,13 @@ def make_target(address: Optional[Address] = None) -> Target: def run_lint_rule( rule_runner: RuleRunner, *, - lint_request_types: Iterable[Type[_LintRequestT]], + lint_request_types: Iterable[type[_LintRequestT]], targets: list[Target], batch_size: int = 128, only: list[str] | None = None, skip_formatters: bool = False, skip_fixers: bool = False, -) -> Tuple[int, str]: +) -> tuple[int, str]: union_membership = UnionMembership( { AbstractLintRequest: lint_request_types, diff --git a/src/python/pants/core/goals/multi_tool_goal_helper.py b/src/python/pants/core/goals/multi_tool_goal_helper.py index 81abb10eac5..27d719f4dac 100644 --- a/src/python/pants/core/goals/multi_tool_goal_helper.py +++ b/src/python/pants/core/goals/multi_tool_goal_helper.py @@ -5,7 +5,8 @@ import logging import os.path -from typing import Iterable, Mapping, Protocol, Sequence, TypeVar +from collections.abc import Iterable, Mapping, Sequence +from typing import Protocol, TypeVar from pants.core.util_rules.distdir import DistDir from pants.engine.fs import EMPTY_DIGEST, Digest, Workspace diff --git a/src/python/pants/core/goals/package.py b/src/python/pants/core/goals/package.py index 2566a4a3b36..ff03b9012a3 100644 --- a/src/python/pants/core/goals/package.py +++ b/src/python/pants/core/goals/package.py @@ -6,9 +6,9 @@ import logging import os from abc import ABCMeta +from collections.abc import Iterable from dataclasses import dataclass from string import Template -from typing import Iterable from pants.core.util_rules import distdir from pants.core.util_rules.distdir import DistDir diff --git a/src/python/pants/core/goals/publish.py b/src/python/pants/core/goals/publish.py index a7b52a296e0..e5777963344 100644 --- a/src/python/pants/core/goals/publish.py +++ b/src/python/pants/core/goals/publish.py @@ -25,9 +25,7 @@ async def publish_example(request: PublishToMyRepoRequest, ...) -> PublishProces from abc import ABCMeta from dataclasses import asdict, dataclass, field, is_dataclass, replace from itertools import chain -from typing import ClassVar, Generic, Type, TypeVar - -from typing_extensions import final +from typing import ClassVar, Generic, TypeVar, final from pants.core.goals.package import BuiltPackage, EnvironmentAwarePackageRequest, PackageFieldSet from pants.engine.addresses import Address @@ -98,7 +96,7 @@ class PublishFieldSet(Generic[_T], FieldSet, metaclass=ABCMeta): """ # Subclasses must provide this, to a union member (subclass) of `PublishRequest`. - publish_request_type: ClassVar[Type[_T]] # type: ignore[misc] + publish_request_type: ClassVar[type[_T]] # type: ignore[misc] @final def _request(self, packages: tuple[BuiltPackage, ...]) -> _T: diff --git a/src/python/pants/core/goals/repl.py b/src/python/pants/core/goals/repl.py index 29be143fbb1..2490a82487c 100644 --- a/src/python/pants/core/goals/repl.py +++ b/src/python/pants/core/goals/repl.py @@ -4,8 +4,9 @@ import os from abc import ABC +from collections.abc import Iterable, Mapping, Sequence from dataclasses import dataclass -from typing import ClassVar, Iterable, Mapping, Optional, Sequence, Tuple, Type, cast +from typing import ClassVar, Optional, cast from pants.core.util_rules.environments import _warn_on_non_local_environments from pants.engine.addresses import Addresses @@ -78,7 +79,7 @@ class Repl(Goal): @dataclass(frozen=True) class ReplRequest: digest: Digest - args: Tuple[str, ...] + args: tuple[str, ...] extra_env: FrozenDict[str, str] immutable_input_digests: FrozenDict[str, Digest] append_only_caches: FrozenDict[str, str] @@ -89,7 +90,7 @@ def __init__( *, digest: Digest, args: Iterable[str], - extra_env: Optional[Mapping[str, str]] = None, + extra_env: Mapping[str, str] | None = None, immutable_input_digests: Mapping[str, Digest] | None = None, append_only_caches: Mapping[str, str] | None = None, run_in_workspace: bool = True, @@ -119,7 +120,7 @@ async def run_repl( repl_shell_name = repl_subsystem.shell or "python" implementations = {impl.name: impl for impl in union_membership[ReplImplementation]} repl_implementation_cls = cast( - Optional[Type[ReplImplementation]], implementations.get(repl_shell_name) + Optional[type[ReplImplementation]], implementations.get(repl_shell_name) ) if repl_implementation_cls is None: available = sorted(implementations.keys()) diff --git a/src/python/pants/core/goals/run.py b/src/python/pants/core/goals/run.py index 9a58c1c6207..90b3ebd6c8f 100644 --- a/src/python/pants/core/goals/run.py +++ b/src/python/pants/core/goals/run.py @@ -5,11 +5,10 @@ import logging from abc import ABCMeta +from collections.abc import Iterable, Mapping from dataclasses import dataclass from enum import Enum -from typing import Any, ClassVar, Iterable, Mapping, Optional, Tuple, TypeVar, Union - -from typing_extensions import final +from typing import Any, ClassVar, TypeVar, final from pants.core.subsystems.debug_adapter import DebugAdapterSubsystem from pants.core.util_rules.environments import _warn_on_non_local_environments @@ -80,7 +79,7 @@ class RunFieldSet(FieldSet, metaclass=ABCMeta): @final @classmethod - def rules(cls) -> Iterable[Union[Rule, UnionRule]]: + def rules(cls) -> Iterable[Rule | UnionRule]: yield UnionRule(RunFieldSet, cls) if not cls.supports_debug_adapter: yield from _unsupported_debug_adapter_rules(cls) @@ -103,7 +102,7 @@ class RunRequest: digest: Digest # Values in args and in env can contain the format specifier "{chroot}", which will # be substituted with the (absolute) chroot path. - args: Tuple[str, ...] + args: tuple[str, ...] extra_env: FrozenDict[str, str] immutable_input_digests: Mapping[str, Digest] | None = None append_only_caches: Mapping[str, str] | None = None @@ -113,7 +112,7 @@ def __init__( *, digest: Digest, args: Iterable[str], - extra_env: Optional[Mapping[str, str]] = None, + extra_env: Mapping[str, str] | None = None, immutable_input_digests: Mapping[str, Digest] | None = None, append_only_caches: Mapping[str, str] | None = None, ) -> None: diff --git a/src/python/pants/core/goals/run_test.py b/src/python/pants/core/goals/run_test.py index 27ee9aad2ba..99ccd3c53de 100644 --- a/src/python/pants/core/goals/run_test.py +++ b/src/python/pants/core/goals/run_test.py @@ -5,7 +5,8 @@ import os import sys -from typing import Iterable, Mapping, cast +from collections.abc import Iterable, Mapping +from typing import cast import pytest from _pytest.monkeypatch import MonkeyPatch diff --git a/src/python/pants/core/goals/tailor.py b/src/python/pants/core/goals/tailor.py index ffa6e3900b3..26330e307a5 100644 --- a/src/python/pants/core/goals/tailor.py +++ b/src/python/pants/core/goals/tailor.py @@ -9,9 +9,10 @@ import os from abc import ABCMeta from collections import defaultdict +from collections.abc import Iterable, Iterator, Mapping from dataclasses import dataclass from pathlib import Path -from typing import Iterable, Iterator, Mapping, cast +from typing import cast from pants.base.specs import AncestorGlobSpec, DirLiteralSpec, RawSpecs, Specs from pants.build_graph.address import Address diff --git a/src/python/pants/core/goals/test.py b/src/python/pants/core/goals/test.py index 592d3782bdf..c13aa40c5e5 100644 --- a/src/python/pants/core/goals/test.py +++ b/src/python/pants/core/goals/test.py @@ -9,11 +9,12 @@ import os import shlex from abc import ABC, ABCMeta +from collections.abc import Iterable, Sequence from dataclasses import dataclass, field from datetime import datetime from enum import Enum from pathlib import PurePath -from typing import Any, ClassVar, Iterable, Optional, Sequence, Tuple, TypeVar, cast +from typing import Any, ClassVar, TypeVar, cast from pants.core.goals.multi_tool_goal_helper import SkippableSubsystem from pants.core.goals.package import BuiltPackage, EnvironmentAwarePackageRequest, PackageFieldSet @@ -98,7 +99,7 @@ class TestResult(EngineAwareReturnType): # True if the core test rules should log that extra output was written. log_extra_output: bool = False # All results including failed attempts - process_results: Tuple[FallibleProcessResult, ...] = field(default_factory=tuple) + process_results: tuple[FallibleProcessResult, ...] = field(default_factory=tuple) output_simplifier: Simplifier = Simplifier() @@ -138,7 +139,7 @@ def no_tests_found_in_batch( @staticmethod def from_fallible_process_result( - process_results: Tuple[FallibleProcessResult, ...], + process_results: tuple[FallibleProcessResult, ...], address: Address, output_setting: ShowOutput, *, @@ -168,7 +169,7 @@ def from_fallible_process_result( @staticmethod def from_batched_fallible_process_result( - process_results: Tuple[FallibleProcessResult, ...], + process_results: tuple[FallibleProcessResult, ...], batch: TestRequest.Batch[_TestFieldSetT, Any], output_setting: ShowOutput, *, @@ -728,7 +729,7 @@ class extending this one. """ ) - def calculate_from_global_options(self, test: TestSubsystem) -> Optional[int]: + def calculate_from_global_options(self, test: TestSubsystem) -> int | None: if not test.timeouts: return None if self.value is None: diff --git a/src/python/pants/core/goals/test_test.py b/src/python/pants/core/goals/test_test.py index ce9a7b414f9..6e1f9145eb2 100644 --- a/src/python/pants/core/goals/test_test.py +++ b/src/python/pants/core/goals/test_test.py @@ -4,11 +4,12 @@ from __future__ import annotations from abc import abstractmethod +from collections.abc import Iterable from dataclasses import dataclass from functools import partial from pathlib import Path from textwrap import dedent -from typing import Any, Iterable +from typing import Any import pytest from _pytest.monkeypatch import MonkeyPatch diff --git a/src/python/pants/core/goals/update_build_files_test.py b/src/python/pants/core/goals/update_build_files_test.py index 79997adec4f..0b5e8be57fb 100644 --- a/src/python/pants/core/goals/update_build_files_test.py +++ b/src/python/pants/core/goals/update_build_files_test.py @@ -3,9 +3,9 @@ from __future__ import annotations +from collections.abc import Iterable from pathlib import Path from textwrap import dedent -from typing import Iterable import pytest diff --git a/src/python/pants/core/subsystems/python_bootstrap.py b/src/python/pants/core/subsystems/python_bootstrap.py index 507e29ee27f..e0e2f14ddb6 100644 --- a/src/python/pants/core/subsystems/python_bootstrap.py +++ b/src/python/pants/core/subsystems/python_bootstrap.py @@ -7,8 +7,8 @@ import logging import os import sys +from collections.abc import Collection from dataclasses import dataclass -from typing import Collection, Optional from pants.core.util_rules import asdf, search_paths from pants.core.util_rules.asdf import AsdfPathString, AsdfToolPathsResult @@ -227,7 +227,7 @@ async def _expand_interpreter_search_paths( # This method is copied from the pex package, located at pex.variables.Variables._get_kv(). # It is copied here to avoid a hard dependency on pex. -def _get_kv(variable: str) -> Optional[list[str]]: +def _get_kv(variable: str) -> list[str] | None: kv = variable.strip().split("=") if len(list(filter(None, kv))) == 2: return kv @@ -237,7 +237,7 @@ def _get_kv(variable: str) -> Optional[list[str]]: # This method is copied from the pex package, located at pex.variables.Variables.from_rc(). # It is copied here to avoid a hard dependency on pex. -def _read_pex_rc(rc: Optional[str] = None) -> dict[str, str]: +def _read_pex_rc(rc: str | None = None) -> dict[str, str]: """Read pex runtime configuration variables from a pexrc file. :param rc: an absolute path to a pexrc file. diff --git a/src/python/pants/core/subsystems/python_bootstrap_test.py b/src/python/pants/core/subsystems/python_bootstrap_test.py index 331001fa8b8..e21cd377474 100644 --- a/src/python/pants/core/subsystems/python_bootstrap_test.py +++ b/src/python/pants/core/subsystems/python_bootstrap_test.py @@ -4,8 +4,9 @@ from __future__ import annotations import os +from collections.abc import Iterable, Sequence from contextlib import contextmanager -from typing import Iterable, List, Sequence, TypeVar +from typing import TypeVar import pytest @@ -86,7 +87,7 @@ def fake_pyenv_root(fake_versions, fake_local_version): yield pyenv_root, fake_version_dirs, fake_local_version_dirs -def materialize_indices(sequence: Sequence[_T], indices: Iterable[int]) -> List[_T]: +def materialize_indices(sequence: Sequence[_T], indices: Iterable[int]) -> list[_T]: return [sequence[i] for i in indices] diff --git a/src/python/pants/core/target_types.py b/src/python/pants/core/target_types.py index dc3036f5797..001b99083af 100644 --- a/src/python/pants/core/target_types.py +++ b/src/python/pants/core/target_types.py @@ -7,9 +7,10 @@ import os import urllib.parse from collections import defaultdict +from collections.abc import Sequence from dataclasses import dataclass from pathlib import PurePath -from typing import Generic, Optional, Sequence, TypeVar, Union, cast +from typing import Generic, TypeVar, cast from pants.core.goals import package from pants.core.goals.package import ( @@ -235,9 +236,9 @@ class AssetSourceField(SingleSourceField): @classmethod def compute_value( # type: ignore[override] cls, - raw_value: Optional[Union[str, http_source, per_platform[http_source]]], + raw_value: str | http_source | per_platform[http_source] | None, address: Address, - ) -> Optional[Union[str, http_source, per_platform[http_source]]]: + ) -> str | http_source | per_platform[http_source] | None: if raw_value is None or isinstance(raw_value, str): return super().compute_value(raw_value, address) elif isinstance(raw_value, per_platform): diff --git a/src/python/pants/core/util_rules/adhoc_process_support.py b/src/python/pants/core/util_rules/adhoc_process_support.py index e4688e00dc0..5044c5ce8aa 100644 --- a/src/python/pants/core/util_rules/adhoc_process_support.py +++ b/src/python/pants/core/util_rules/adhoc_process_support.py @@ -8,11 +8,12 @@ import logging import os import shlex +from collections.abc import Iterable, Mapping from dataclasses import dataclass from datetime import datetime from enum import Enum from textwrap import dedent # noqa: PNT20 -from typing import Iterable, Mapping, TypeVar, Union +from typing import TypeVar from pants.base.glob_match_error_behavior import GlobMatchErrorBehavior from pants.build_graph.address import Address @@ -858,7 +859,7 @@ def _output_at_build_root(process: Process, bash: BashBinary) -> Process: ) -def parse_relative_directory(workdir_in: str, relative_to: Union[Address, str]) -> str: +def parse_relative_directory(workdir_in: str, relative_to: Address | str) -> str: """Convert the `workdir` field into something that can be understood by `Process`.""" if isinstance(relative_to, Address): diff --git a/src/python/pants/core/util_rules/archive_test.py b/src/python/pants/core/util_rules/archive_test.py index fc0aa123222..46683b1afbf 100644 --- a/src/python/pants/core/util_rules/archive_test.py +++ b/src/python/pants/core/util_rules/archive_test.py @@ -6,8 +6,9 @@ import subprocess import tarfile import zipfile +from collections.abc import Callable from io import BytesIO -from typing import Callable, cast +from typing import cast import pytest diff --git a/src/python/pants/core/util_rules/asdf.py b/src/python/pants/core/util_rules/asdf.py index e391fd765b5..7ae3ff04d45 100644 --- a/src/python/pants/core/util_rules/asdf.py +++ b/src/python/pants/core/util_rules/asdf.py @@ -4,10 +4,10 @@ import logging import re +from collections.abc import Collection from dataclasses import dataclass from enum import Enum from pathlib import Path, PurePath -from typing import Collection from pants.base.build_environment import get_buildroot from pants.base.build_root import BuildRoot diff --git a/src/python/pants/core/util_rules/asdf_test.py b/src/python/pants/core/util_rules/asdf_test.py index 6c966ecc510..ea6bf0275e6 100644 --- a/src/python/pants/core/util_rules/asdf_test.py +++ b/src/python/pants/core/util_rules/asdf_test.py @@ -2,8 +2,8 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). from __future__ import annotations +from collections.abc import Mapping from pathlib import PurePath -from typing import Mapping import pytest diff --git a/src/python/pants/core/util_rules/config_files.py b/src/python/pants/core/util_rules/config_files.py index 50c7c7aa4d5..134ddf3d4ee 100644 --- a/src/python/pants/core/util_rules/config_files.py +++ b/src/python/pants/core/util_rules/config_files.py @@ -5,9 +5,9 @@ import logging import os +from collections.abc import Iterable, Mapping from dataclasses import dataclass from enum import Enum -from typing import Iterable, Mapping from pants.base.glob_match_error_behavior import GlobMatchErrorBehavior from pants.engine.fs import EMPTY_SNAPSHOT, DigestContents, PathGlobs, Snapshot diff --git a/src/python/pants/core/util_rules/environments.py b/src/python/pants/core/util_rules/environments.py index fbad11812fe..78f2c2147c7 100644 --- a/src/python/pants/core/util_rules/environments.py +++ b/src/python/pants/core/util_rules/environments.py @@ -6,9 +6,10 @@ import dataclasses import logging import shlex +from collections.abc import Callable, Iterable, Sequence from dataclasses import dataclass from itertools import groupby -from typing import Any, Callable, ClassVar, Iterable, Optional, Sequence, Tuple, Type, Union, cast +from typing import Any, ClassVar, cast from pants.build_graph.address import Address, AddressInput from pants.engine.engine_aware import EngineAwareParameter @@ -1114,8 +1115,8 @@ class _EnvironmentSensitiveOptionFieldMixin: class ShellStringSequenceField(StringSequenceField): @classmethod def compute_value( - cls, raw_value: Optional[Iterable[str]], address: Address - ) -> Optional[Tuple[str, ...]]: + cls, raw_value: Iterable[str] | None, address: Address + ) -> tuple[str, ...] | None: """Computes a flattened shlexed arg list from an iterable of strings.""" if not raw_value: return () @@ -1124,13 +1125,13 @@ def compute_value( # Maps between non-list option value types and corresponding fields -_SIMPLE_OPTIONS: dict[Union[Type, Callable[[str], Any]], Type[Field]] = { +_SIMPLE_OPTIONS: dict[type | Callable[[str], Any], type[Field]] = { str: StringField, } # Maps between the member types for list options. Each element is the # field type, and the `value` type for the field. -_LIST_OPTIONS: dict[Union[Type, Callable[[str], Any]], Type[Field]] = { +_LIST_OPTIONS: dict[type | Callable[[str], Any], type[Field]] = { str: StringSequenceField, custom_types.shell_str: ShellStringSequenceField, } diff --git a/src/python/pants/core/util_rules/environments_test.py b/src/python/pants/core/util_rules/environments_test.py index 46eaeeef239..086678d8c86 100644 --- a/src/python/pants/core/util_rules/environments_test.py +++ b/src/python/pants/core/util_rules/environments_test.py @@ -3,9 +3,9 @@ from __future__ import annotations +from collections.abc import Sequence from dataclasses import dataclass from textwrap import dedent -from typing import Sequence import pytest diff --git a/src/python/pants/core/util_rules/lockfile_metadata.py b/src/python/pants/core/util_rules/lockfile_metadata.py index 1294b520e9f..fdbe8ec82d9 100644 --- a/src/python/pants/core/util_rules/lockfile_metadata.py +++ b/src/python/pants/core/util_rules/lockfile_metadata.py @@ -5,9 +5,10 @@ import hashlib import json +from collections.abc import Callable, Iterable from dataclasses import dataclass from enum import Enum -from typing import Any, Callable, ClassVar, Generic, Iterable, Tuple, Type, TypeVar, cast +from typing import Any, ClassVar, Generic, TypeVar, cast from pants.util.docutil import bin_name from pants.util.ordered_set import FrozenOrderedSet @@ -24,11 +25,11 @@ class LockfileScope(Enum): _LockfileMetadataSubclass = TypeVar("_LockfileMetadataSubclass", bound="LockfileMetadata") # N.B. the value type is `type[_LockfileMetadataSubclass]` -_concrete_metadata_classes: dict[Tuple[LockfileScope, int], type] = {} +_concrete_metadata_classes: dict[tuple[LockfileScope, int], type] = {} # Registrar types (pre-declaring to avoid repetition) -RegisterClassForVersion = Callable[[Type["LockfileMetadata"]], Type["LockfileMetadata"]] +RegisterClassForVersion = Callable[[type["LockfileMetadata"]], type["LockfileMetadata"]] def lockfile_metadata_registrar(scope: LockfileScope) -> Callable[[int], RegisterClassForVersion]: @@ -43,7 +44,7 @@ def _lockfile_metadata_version( The class must be a frozen dataclass """ - def _dec(cls: Type[LockfileMetadata]) -> Type[LockfileMetadata]: + def _dec(cls: type[LockfileMetadata]) -> type[LockfileMetadata]: # Only frozen dataclasses may be registered as lockfile metadata: cls_dataclass_params = getattr(cls, "__dataclass_params__", None) if not cls_dataclass_params or not cls_dataclass_params.frozen: @@ -215,7 +216,7 @@ def __render_header_dict(self) -> dict[Any, Any]: `dict` containing the metadata attributes that should be stored in the lockfile. """ - attrs: dict[Any, Tuple[Any, Type]] = {} # attr name -> (value, where we first saw it) + attrs: dict[Any, tuple[Any, type]] = {} # attr name -> (value, where we first saw it) for cls in reversed(self.__class__.__mro__[:-1]): new_attrs = cast(LockfileMetadata, cls).additional_header_attrs(self) for attr in new_attrs: diff --git a/src/python/pants/core/util_rules/ownership.py b/src/python/pants/core/util_rules/ownership.py index 2b69fc39e81..7d600013a57 100644 --- a/src/python/pants/core/util_rules/ownership.py +++ b/src/python/pants/core/util_rules/ownership.py @@ -1,6 +1,6 @@ # Copyright 2023 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). -from typing import Iterable +from collections.abc import Iterable from pants.core.goals.tailor import AllOwnedSources, PutativeTargetsRequest from pants.engine.fs import PathGlobs, Paths diff --git a/src/python/pants/core/util_rules/partitions.py b/src/python/pants/core/util_rules/partitions.py index bdedf6198d8..58e8921d433 100644 --- a/src/python/pants/core/util_rules/partitions.py +++ b/src/python/pants/core/util_rules/partitions.py @@ -6,9 +6,10 @@ from __future__ import annotations import itertools +from collections.abc import Iterable from dataclasses import dataclass from enum import Enum -from typing import Generic, Iterable, Protocol, TypeVar, overload +from typing import Generic, Protocol, TypeVar, overload from pants.core.goals.multi_tool_goal_helper import SkippableSubsystem from pants.engine.collection import Collection diff --git a/src/python/pants/core/util_rules/search_paths.py b/src/python/pants/core/util_rules/search_paths.py index 2ea9d735fa8..fb64f683ff2 100644 --- a/src/python/pants/core/util_rules/search_paths.py +++ b/src/python/pants/core/util_rules/search_paths.py @@ -4,9 +4,10 @@ import logging import os +from collections.abc import Iterable from dataclasses import dataclass from pathlib import Path -from typing import Any, ClassVar, Iterable +from typing import Any, ClassVar from pants.base.build_environment import get_buildroot from pants.core.util_rules.environments import EnvironmentTarget diff --git a/src/python/pants/core/util_rules/search_paths_test.py b/src/python/pants/core/util_rules/search_paths_test.py index 4955d47b707..deeacfd0792 100644 --- a/src/python/pants/core/util_rules/search_paths_test.py +++ b/src/python/pants/core/util_rules/search_paths_test.py @@ -3,8 +3,8 @@ from __future__ import annotations import os +from collections.abc import Generator from contextlib import contextmanager -from typing import Generator import pytest diff --git a/src/python/pants/core/util_rules/source_files.py b/src/python/pants/core/util_rules/source_files.py index 055891ee8a0..8317f2f00e9 100644 --- a/src/python/pants/core/util_rules/source_files.py +++ b/src/python/pants/core/util_rules/source_files.py @@ -1,9 +1,9 @@ # Copyright 2020 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). +from collections.abc import Collection, Iterable from dataclasses import dataclass from pathlib import PurePath -from typing import Collection, Iterable, Set, Tuple, Type, Union from pants.engine.fs import MergeDigests, Snapshot from pants.engine.rules import Get, MultiGet, collect_rules, rule @@ -18,24 +18,24 @@ class SourceFiles: # The subset of files in snapshot that are not intended to have an associated source root. # That is, the sources of files() targets. - unrooted_files: Tuple[str, ...] + unrooted_files: tuple[str, ...] @property - def files(self) -> Tuple[str, ...]: + def files(self) -> tuple[str, ...]: return self.snapshot.files @dataclass(frozen=True) class SourceFilesRequest: - sources_fields: Tuple[SourcesField, ...] - for_sources_types: Tuple[Type[SourcesField], ...] + sources_fields: tuple[SourcesField, ...] + for_sources_types: tuple[type[SourcesField], ...] enable_codegen: bool def __init__( self, sources_fields: Iterable[SourcesField], *, - for_sources_types: Iterable[Type[SourcesField]] = (SourcesField,), + for_sources_types: Iterable[type[SourcesField]] = (SourcesField,), enable_codegen: bool = False, ) -> None: object.__setattr__(self, "sources_fields", tuple(sources_fields)) @@ -46,7 +46,7 @@ def __init__( @rule(desc="Get all relevant source files") async def determine_source_files(request: SourceFilesRequest) -> SourceFiles: """Merge all `SourceBaseField`s into one Snapshot.""" - unrooted_files: Set[str] = set() + unrooted_files: set[str] = set() all_hydrated_sources = await MultiGet( Get( HydratedSources, @@ -74,7 +74,7 @@ async def determine_source_files(request: SourceFilesRequest) -> SourceFiles: class ClassifiedSources: target_type: type[Target] files: Collection[str] - name: Union[str, None] = None + name: str | None = None def classify_files_for_sources_and_tests( diff --git a/src/python/pants/core/util_rules/source_files_test.py b/src/python/pants/core/util_rules/source_files_test.py index 42d37c4f1da..3d5c6da0ec6 100644 --- a/src/python/pants/core/util_rules/source_files_test.py +++ b/src/python/pants/core/util_rules/source_files_test.py @@ -4,9 +4,10 @@ from __future__ import annotations import itertools +from collections.abc import Iterable from functools import partial from pathlib import PurePath -from typing import Iterable, NamedTuple +from typing import NamedTuple import pytest diff --git a/src/python/pants/core/util_rules/stripped_source_files_test.py b/src/python/pants/core/util_rules/stripped_source_files_test.py index 9380a25caf8..55786f7aa27 100644 --- a/src/python/pants/core/util_rules/stripped_source_files_test.py +++ b/src/python/pants/core/util_rules/stripped_source_files_test.py @@ -3,7 +3,7 @@ from __future__ import annotations -from typing import Sequence +from collections.abc import Sequence import pytest diff --git a/src/python/pants/core/util_rules/subprocess_environment.py b/src/python/pants/core/util_rules/subprocess_environment.py index bf821e05ea9..6f19983a6d3 100644 --- a/src/python/pants/core/util_rules/subprocess_environment.py +++ b/src/python/pants/core/util_rules/subprocess_environment.py @@ -2,7 +2,6 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). from dataclasses import dataclass -from typing import Tuple from pants.engine.env_vars import EnvironmentVars, EnvironmentVarsRequest from pants.engine.rules import Get, collect_rules, rule @@ -38,7 +37,7 @@ class EnvironmentAware: ) @property - def env_vars_to_pass_to_subprocesses(self) -> Tuple[str, ...]: + def env_vars_to_pass_to_subprocesses(self) -> tuple[str, ...]: return tuple(sorted(set(self._env_vars))) diff --git a/src/python/pants/core/util_rules/system_binaries.py b/src/python/pants/core/util_rules/system_binaries.py index 8c3c0b9ee7f..303acd02008 100644 --- a/src/python/pants/core/util_rules/system_binaries.py +++ b/src/python/pants/core/util_rules/system_binaries.py @@ -9,13 +9,12 @@ import os import shlex import subprocess +from collections.abc import Iterable, Mapping, Sequence from dataclasses import dataclass from enum import Enum from itertools import groupby from textwrap import dedent # noqa: PNT20 -from typing import Iterable, Mapping, Sequence - -from typing_extensions import Self +from typing import Self from pants.core.subsystems import python_bootstrap from pants.core.util_rules.environments import EnvironmentTarget diff --git a/src/python/pants/core/util_rules/testutil.py b/src/python/pants/core/util_rules/testutil.py index f06382064f2..43e3ec2d541 100644 --- a/src/python/pants/core/util_rules/testutil.py +++ b/src/python/pants/core/util_rules/testutil.py @@ -2,9 +2,10 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). from __future__ import annotations +from collections.abc import Iterable, Sequence from contextlib import contextmanager from pathlib import Path -from typing import Iterable, Sequence, TypeVar +from typing import TypeVar from pants.util.contextutil import temporary_dir diff --git a/src/python/pants/core/util_rules/wrap_source.py b/src/python/pants/core/util_rules/wrap_source.py index 6b3694789c2..d8fdc21c85c 100644 --- a/src/python/pants/core/util_rules/wrap_source.py +++ b/src/python/pants/core/util_rules/wrap_source.py @@ -5,8 +5,8 @@ from __future__ import annotations import logging +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable, Union from pants.core.target_types import FileSourceField from pants.core.util_rules.source_files import SourceFiles, SourceFilesRequest @@ -34,7 +34,7 @@ @dataclass(frozen=True) class WrapSource: - rules: tuple[Union[Rule, UnionRule], ...] + rules: tuple[Rule | UnionRule, ...] target_types: tuple[type[Target], ...] diff --git a/src/python/pants/engine/addresses.py b/src/python/pants/engine/addresses.py index 4a0255cb4d1..44765dd6415 100644 --- a/src/python/pants/engine/addresses.py +++ b/src/python/pants/engine/addresses.py @@ -3,8 +3,8 @@ from __future__ import annotations +from collections.abc import Iterable, Sequence from dataclasses import dataclass -from typing import Iterable, Sequence from pants.build_graph.address import Address as Address from pants.build_graph.address import AddressInput as AddressInput # noqa: F401: rexport. diff --git a/src/python/pants/engine/collection.py b/src/python/pants/engine/collection.py index e1ae60499e1..cbcdddb9a0c 100644 --- a/src/python/pants/engine/collection.py +++ b/src/python/pants/engine/collection.py @@ -3,14 +3,15 @@ from __future__ import annotations -from typing import Any, ClassVar, Iterable, Tuple, TypeVar, cast, overload +from collections.abc import Iterable +from typing import Any, ClassVar, TypeVar, cast, overload from pants.util.ordered_set import FrozenOrderedSet T = TypeVar("T") -class Collection(Tuple[T, ...]): +class Collection(tuple[T, ...]): """A light newtype around immutable sequences for use with the V2 engine. This should be subclassed when you want to create a distinct collection type, such as: @@ -35,7 +36,7 @@ def __getitem__(self, index: int | slice) -> T | Collection[T]: # noqa: F811 result = super().__getitem__(index) if isinstance(index, int): return cast(T, result) - return self.__class__(cast(Tuple[T, ...], result)) + return self.__class__(cast(tuple[T, ...], result)) def __eq__(self, other: Any) -> bool: if self is other: diff --git a/src/python/pants/engine/console.py b/src/python/pants/engine/console.py index 8f65cee31f0..7fcd6d7b3fc 100644 --- a/src/python/pants/engine/console.py +++ b/src/python/pants/engine/console.py @@ -3,7 +3,8 @@ from __future__ import annotations import sys -from typing import Callable, TextIO +from collections.abc import Callable +from typing import TextIO from colors import blue, cyan, green, magenta, red, yellow diff --git a/src/python/pants/engine/desktop.py b/src/python/pants/engine/desktop.py index 8957f0c751c..5ba37bf199e 100644 --- a/src/python/pants/engine/desktop.py +++ b/src/python/pants/engine/desktop.py @@ -2,9 +2,9 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). import logging +from collections.abc import Iterable from dataclasses import dataclass from pathlib import PurePath -from typing import Iterable, Tuple from pants.core.util_rules.environments import ChosenLocalEnvironmentName, EnvironmentName from pants.core.util_rules.system_binaries import BinaryPathRequest, BinaryPaths @@ -18,7 +18,7 @@ @dataclass(frozen=True) class OpenFilesRequest: - files: Tuple[PurePath, ...] + files: tuple[PurePath, ...] error_if_open_not_found: bool def __init__(self, files: Iterable[PurePath], *, error_if_open_not_found: bool = True) -> None: @@ -28,7 +28,7 @@ def __init__(self, files: Iterable[PurePath], *, error_if_open_not_found: bool = @dataclass(frozen=True) class OpenFiles: - processes: Tuple[InteractiveProcess, ...] + processes: tuple[InteractiveProcess, ...] @rule diff --git a/src/python/pants/engine/download_file.py b/src/python/pants/engine/download_file.py index 9329938326d..fb15fa79c99 100644 --- a/src/python/pants/engine/download_file.py +++ b/src/python/pants/engine/download_file.py @@ -3,7 +3,7 @@ from dataclasses import dataclass from fnmatch import fnmatch -from typing import ClassVar, Optional +from typing import ClassVar from urllib.parse import urlparse from pants.engine.fs import Digest, DownloadFile, NativeDownloadFile @@ -43,14 +43,14 @@ def rules(): ] """ - match_scheme: ClassVar[Optional[str]] = None + match_scheme: ClassVar[str | None] = None """The scheme to match (e.g. 'ftp' or 's3') or `None` to match all schemes. The scheme is matched using `fnmatch`, see https://docs.python.org/3/library/fnmatch.html for more information. """ - match_authority: ClassVar[Optional[str]] = None + match_authority: ClassVar[str | None] = None """The authority to match (e.g. 'pantsbuild.org' or 's3.amazonaws.com') or `None` to match all authorities. The authority is matched using `fnmatch`, see https://docs.python.org/3/library/fnmatch.html for more diff --git a/src/python/pants/engine/env_vars.py b/src/python/pants/engine/env_vars.py index ea80235b9be..6301c0d73f7 100644 --- a/src/python/pants/engine/env_vars.py +++ b/src/python/pants/engine/env_vars.py @@ -5,8 +5,8 @@ import fnmatch import re +from collections.abc import Iterator, Sequence from dataclasses import dataclass -from typing import Dict, Iterator, Optional, Sequence from pants.util.frozendict import FrozenDict from pants.util.ordered_set import FrozenOrderedSet @@ -29,7 +29,7 @@ class CompleteEnvironmentVars(FrozenDict): """ def get_subset( - self, requested: Sequence[str], *, allowed: Optional[Sequence[str]] = None + self, requested: Sequence[str], *, allowed: Sequence[str] | None = None ) -> FrozenDict[str, str]: """Extract a subset of named env vars. @@ -44,9 +44,9 @@ def get_subset( will be raised. """ allowed_set = None if allowed is None else set(allowed) - env_var_subset: Dict[str, str] = {} + env_var_subset: dict[str, str] = {} - def check_and_set(name: str, value: Optional[str]): + def check_and_set(name: str, value: str | None): if allowed_set is not None and name not in allowed_set: raise ValueError( f"{name} is not in the list of variable names that are allowed to be set. " @@ -97,9 +97,9 @@ class EnvironmentVarsRequest: """ requested: FrozenOrderedSet[str] - allowed: Optional[FrozenOrderedSet[str]] + allowed: FrozenOrderedSet[str] | None - def __init__(self, requested: Sequence[str], allowed: Optional[Sequence[str]] = None): + def __init__(self, requested: Sequence[str], allowed: Sequence[str] | None = None): object.__setattr__(self, "requested", FrozenOrderedSet(requested)) object.__setattr__(self, "allowed", None if allowed is None else FrozenOrderedSet(allowed)) diff --git a/src/python/pants/engine/environment_test.py b/src/python/pants/engine/environment_test.py index 7568a058a2d..f767fc7976d 100644 --- a/src/python/pants/engine/environment_test.py +++ b/src/python/pants/engine/environment_test.py @@ -1,7 +1,6 @@ # Copyright 2020 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). -from typing import Dict, List import pytest @@ -21,7 +20,7 @@ (['A=has a " in it'], {"A": 'has a " in it'}), ], ) -def test_complete_environment(input_strs: List[str], expected: Dict[str, str]) -> None: +def test_complete_environment(input_strs: list[str], expected: dict[str, str]) -> None: pants_env = CompleteEnvironmentVars({"A": "a", "B": "b", "C": "c"}) subset = pants_env.get_subset(input_strs) diff --git a/src/python/pants/engine/explorer.py b/src/python/pants/engine/explorer.py index afe27c080c0..0ae0c84ab60 100644 --- a/src/python/pants/engine/explorer.py +++ b/src/python/pants/engine/explorer.py @@ -3,8 +3,9 @@ from __future__ import annotations +from collections.abc import Callable, Iterable from dataclasses import dataclass -from typing import Any, Callable, Iterable, TypeVar, cast +from typing import Any, TypeVar, cast from pants.base.exiter import ExitCode from pants.build_graph.build_configuration import BuildConfiguration diff --git a/src/python/pants/engine/fs.py b/src/python/pants/engine/fs.py index 57b5d31e932..3993ba3d96c 100644 --- a/src/python/pants/engine/fs.py +++ b/src/python/pants/engine/fs.py @@ -3,10 +3,11 @@ from __future__ import annotations +from collections.abc import Iterable, Mapping, Sequence from dataclasses import dataclass from datetime import timedelta from enum import Enum -from typing import TYPE_CHECKING, Iterable, Mapping, Optional, Sequence, Tuple, Union +from typing import TYPE_CHECKING, Union # Note: several of these types are re-exported as the public API of `engine/fs.py`. from pants.base.glob_match_error_behavior import GlobMatchErrorBehavior as GlobMatchErrorBehavior @@ -38,8 +39,8 @@ class Paths: or save them to the LMDB store. """ - files: Tuple[str, ...] - dirs: Tuple[str, ...] + files: tuple[str, ...] + dirs: tuple[str, ...] @dataclass(frozen=True) @@ -155,7 +156,7 @@ class GlobExpansionConjunction(Enum): @dataclass(frozen=True) class PathGlobs: - globs: Tuple[str, ...] + globs: tuple[str, ...] glob_match_error_behavior: GlobMatchErrorBehavior conjunction: GlobExpansionConjunction description_of_origin: str | None @@ -221,7 +222,7 @@ class PathGlobsAndRoot: path_globs: PathGlobs root: str - digest_hint: Optional[Digest] = None + digest_hint: Digest | None = None @dataclass(frozen=True) @@ -302,7 +303,7 @@ def write_digest( self, digest: Digest, *, - path_prefix: Optional[str] = None, + path_prefix: str | None = None, clear_paths: Sequence[str] = (), side_effecting: bool = True, ) -> None: diff --git a/src/python/pants/engine/fs_test.py b/src/python/pants/engine/fs_test.py index 68ab527fb60..f0321b81583 100644 --- a/src/python/pants/engine/fs_test.py +++ b/src/python/pants/engine/fs_test.py @@ -11,11 +11,12 @@ import ssl import tarfile import time +from collections.abc import Callable, Iterable from dataclasses import dataclass from http.server import BaseHTTPRequestHandler from io import BytesIO from pathlib import Path -from typing import Any, Callable, Dict, Iterable, Optional, Set, Union +from typing import Any import pytest @@ -408,7 +409,7 @@ def test_path_globs_symlink_loop(rule_runner: RuleRunner) -> None: def test_path_globs_to_digest_contents(rule_runner: RuleRunner) -> None: setup_fs_test_tar(rule_runner) - def get_contents(globs: Iterable[str]) -> Set[FileContent]: + def get_contents(globs: Iterable[str]) -> set[FileContent]: return set(rule_runner.request(DigestContents, [PathGlobs(globs)])) assert get_contents(["4.txt", "a/4.txt.ln"]) == { @@ -425,7 +426,7 @@ def get_contents(globs: Iterable[str]) -> Set[FileContent]: def test_path_globs_to_digest_entries(rule_runner: RuleRunner) -> None: setup_fs_test_tar(rule_runner) - def get_entries(globs: Iterable[str]) -> Set[Union[FileEntry, Directory, SymlinkEntry]]: + def get_entries(globs: Iterable[str]) -> set[FileEntry | Directory | SymlinkEntry]: return set(rule_runner.request(DigestEntries, [PathGlobs(globs)])) assert get_entries(["4.txt", "a/4.txt.ln"]) == { @@ -1332,7 +1333,7 @@ def test_invalidated_after_parent_deletion(rule_runner: RuleRunner) -> None: """Test that FileContent is invalidated after deleting the parent directory.""" setup_fs_test_tar(rule_runner) - def read_file() -> Optional[str]: + def read_file() -> str | None: digest_contents = rule_runner.request(DigestContents, [PathGlobs(["a/b/1.txt"])]) if not digest_contents: return None @@ -1491,8 +1492,8 @@ def test_snapshot_hash_and_eq() -> None: ) def test_snapshot_diff( rule_runner: RuleRunner, - before: Dict[str, str], - after: Dict[str, str], + before: dict[str, str], + after: dict[str, str], expected_diff: SnapshotDiff, ) -> None: diff = SnapshotDiff.from_snapshots( diff --git a/src/python/pants/engine/goal.py b/src/python/pants/engine/goal.py index 0ff5acb6398..e0ad4e0d6e9 100644 --- a/src/python/pants/engine/goal.py +++ b/src/python/pants/engine/goal.py @@ -3,12 +3,11 @@ from __future__ import annotations from abc import abstractmethod +from collections.abc import Callable, Iterator from contextlib import contextmanager from dataclasses import dataclass, field from enum import Enum -from typing import TYPE_CHECKING, Callable, ClassVar, Iterator, Type, cast - -from typing_extensions import final +from typing import TYPE_CHECKING, ClassVar, cast, final from pants.engine.engine_aware import EngineAwareReturnType from pants.engine.unions import UnionMembership @@ -99,7 +98,7 @@ class EnvironmentBehavior(Enum): USES_ENVIRONMENTS = 3 exit_code: int - subsystem_cls: ClassVar[Type[GoalSubsystem]] + subsystem_cls: ClassVar[type[GoalSubsystem]] f"""Indicates that a Goal has been migrated to compute EnvironmentNames to build targets in. diff --git a/src/python/pants/engine/internals/build_files.py b/src/python/pants/engine/internals/build_files.py index 050496a6c54..fbe4de693ce 100644 --- a/src/python/pants/engine/internals/build_files.py +++ b/src/python/pants/engine/internals/build_files.py @@ -11,9 +11,10 @@ import sys import typing from collections import defaultdict +from collections.abc import Sequence from dataclasses import dataclass from pathlib import PurePath -from typing import Any, Sequence, cast +from typing import Any, cast import typing_extensions diff --git a/src/python/pants/engine/internals/build_files_test.py b/src/python/pants/engine/internals/build_files_test.py index feeb4509d39..0d60b940eaf 100644 --- a/src/python/pants/engine/internals/build_files_test.py +++ b/src/python/pants/engine/internals/build_files_test.py @@ -5,8 +5,9 @@ import logging import re +from collections.abc import Mapping from textwrap import dedent -from typing import Any, Mapping, cast +from typing import Any, cast import pytest diff --git a/src/python/pants/engine/internals/defaults.py b/src/python/pants/engine/internals/defaults.py index 1e928b7b114..570e1b0e140 100644 --- a/src/python/pants/engine/internals/defaults.py +++ b/src/python/pants/engine/internals/defaults.py @@ -12,8 +12,9 @@ """ from __future__ import annotations +from collections.abc import Callable, Iterable, Mapping from dataclasses import dataclass -from typing import Any, Callable, Iterable, Mapping, Tuple, Union +from typing import Any, Union from pants.engine.addresses import Address from pants.engine.internals.parametrize import Parametrize @@ -29,7 +30,7 @@ from pants.util.frozendict import FrozenDict SetDefaultsValueT = Mapping[str, Any] -SetDefaultsKeyT = Union[str, Tuple[str, ...]] +SetDefaultsKeyT = Union[str, tuple[str, ...]] SetDefaultsT = Mapping[SetDefaultsKeyT, SetDefaultsValueT] diff --git a/src/python/pants/engine/internals/defaults_test.py b/src/python/pants/engine/internals/defaults_test.py index 349a9344f32..1dca498b4d6 100644 --- a/src/python/pants/engine/internals/defaults_test.py +++ b/src/python/pants/engine/internals/defaults_test.py @@ -4,7 +4,8 @@ from __future__ import annotations from collections import namedtuple -from typing import Any, Mapping +from collections.abc import Mapping +from typing import Any import pytest diff --git a/src/python/pants/engine/internals/engine_test.py b/src/python/pants/engine/internals/engine_test.py index f7c44aaeb6e..58dc2f9e47e 100644 --- a/src/python/pants/engine/internals/engine_test.py +++ b/src/python/pants/engine/internals/engine_test.py @@ -6,7 +6,6 @@ from dataclasses import dataclass, field from pathlib import Path from textwrap import dedent -from typing import List, Optional, Tuple import pytest @@ -274,8 +273,8 @@ class WorkunitTracker(WorkunitsCallback): """This class records every non-empty batch of started and completed workunits received from the engine.""" - finished_workunit_chunks: List[List[dict]] = field(default_factory=list) - started_workunit_chunks: List[List[dict]] = field(default_factory=list) + finished_workunit_chunks: list[list[dict]] = field(default_factory=list) + started_workunit_chunks: list[list[dict]] = field(default_factory=list) finished: bool = False @property @@ -310,7 +309,7 @@ def run_tracker() -> RunTracker: class TestStreamingWorkunit(SchedulerTestBase): def _fixture_for_rules( self, tmp_path: Path, rules, max_workunit_verbosity: LogLevel = LogLevel.INFO - ) -> Tuple[SchedulerSession, WorkunitTracker, StreamingWorkunitHandler]: + ) -> tuple[SchedulerSession, WorkunitTracker, StreamingWorkunitHandler]: scheduler = self.mk_scheduler( tmp_path, rules, @@ -547,7 +546,7 @@ def test_engine_aware_none_case(self, tmp_path: Path) -> None: # If level() returns None, the engine shouldn't try to set # a new workunit level. class ModifiedOutput(EngineAwareReturnType): - _level: Optional[LogLevel] + _level: LogLevel | None val: int def level(self): diff --git a/src/python/pants/engine/internals/engine_testutil.py b/src/python/pants/engine/internals/engine_testutil.py index fd9a5d6a15c..03189c93071 100644 --- a/src/python/pants/engine/internals/engine_testutil.py +++ b/src/python/pants/engine/internals/engine_testutil.py @@ -4,7 +4,7 @@ from __future__ import annotations import re -from typing import Callable +from collections.abc import Callable def assert_equal_with_printing( diff --git a/src/python/pants/engine/internals/graph.py b/src/python/pants/engine/internals/graph.py index fd703e3ca6e..16f1c5c7be3 100644 --- a/src/python/pants/engine/internals/graph.py +++ b/src/python/pants/engine/internals/graph.py @@ -10,21 +10,10 @@ import logging import os.path from collections import defaultdict +from collections.abc import Iterable, Iterator, Mapping, Sequence from dataclasses import dataclass from pathlib import PurePath -from typing import ( - Any, - DefaultDict, - FrozenSet, - Iterable, - Iterator, - Mapping, - NamedTuple, - Sequence, - Type, - TypeVar, - cast, -) +from typing import Any, DefaultDict, NamedTuple, Type, TypeVar, cast from pants.base.deprecated import warn_or_error from pants.base.specs import AncestorGlobSpec, RawSpecsWithoutFileOwners, RecursiveGlobSpec @@ -1042,7 +1031,7 @@ def calc_source_block_mapping( ) -class FilesWithSourceBlocks(FrozenSet[str]): +class FilesWithSourceBlocks(frozenset[str]): pass diff --git a/src/python/pants/engine/internals/graph_test.py b/src/python/pants/engine/internals/graph_test.py index c82cf60c40c..9f3a0e17758 100644 --- a/src/python/pants/engine/internals/graph_test.py +++ b/src/python/pants/engine/internals/graph_test.py @@ -6,10 +6,10 @@ import dataclasses import itertools import os.path +from collections.abc import Iterable from dataclasses import dataclass from pathlib import PurePath from textwrap import dedent -from typing import Iterable, List, Set, Tuple, Type import pytest @@ -484,7 +484,7 @@ def test_coarsened_targets(transitive_targets_rule_runner: RuleRunner) -> None: ) def assert_coarsened( - a: Address, expected_members: List[Address], expected_dependencies: List[Address] + a: Address, expected_members: list[Address], expected_dependencies: list[Address] ) -> None: coarsened_targets = transitive_targets_rule_runner.request( CoarsenedTargets, @@ -551,7 +551,7 @@ def assert_failed_cycle( *, root_target_name: str, subject_target_name: str, - path_target_names: Tuple[str, ...], + path_target_names: tuple[str, ...], ) -> None: with pytest.raises(ExecutionError) as e: rule_runner.request( @@ -845,7 +845,7 @@ def assert_owners( rule_runner: RuleRunner, requested: Iterable[str], *, - expected: Set[Address], + expected: set[Address], match_if_owning_build_file_included_in_sources: bool = False, ) -> None: result = rule_runner.request( @@ -1884,7 +1884,7 @@ class ExpectedRange(MultipleSourcesField): sources_rule_runner.write_files(dict.fromkeys(["f1.txt", "f2.txt", "f3.txt", "f4.txt"], "")) - def hydrate(sources_cls: Type[MultipleSourcesField], sources: Iterable[str]) -> HydratedSources: + def hydrate(sources_cls: type[MultipleSourcesField], sources: Iterable[str]) -> HydratedSources: return sources_rule_runner.request( HydratedSources, [ diff --git a/src/python/pants/engine/internals/mapper.py b/src/python/pants/engine/internals/mapper.py index 75803e77588..d83e37397fb 100644 --- a/src/python/pants/engine/internals/mapper.py +++ b/src/python/pants/engine/internals/mapper.py @@ -4,8 +4,9 @@ from __future__ import annotations import os.path +from collections.abc import Iterable, Mapping from dataclasses import dataclass -from typing import Iterable, Mapping, TypeVar +from typing import TypeVar from pants.backend.project_info.filter_targets import FilterSubsystem from pants.base.exceptions import MappingError diff --git a/src/python/pants/engine/internals/native_engine.pyi b/src/python/pants/engine/internals/native_engine.pyi index 8e7cfcea799..0b298777a66 100644 --- a/src/python/pants/engine/internals/native_engine.pyi +++ b/src/python/pants/engine/internals/native_engine.pyi @@ -3,26 +3,10 @@ from __future__ import annotations +from collections.abc import Callable, Iterable, Mapping, Sequence from datetime import datetime from io import RawIOBase -from typing import ( - Any, - Callable, - ClassVar, - FrozenSet, - Generic, - Iterable, - Mapping, - Optional, - Protocol, - Sequence, - TextIO, - Tuple, - TypeVar, - overload, -) - -from typing_extensions import Self +from typing import Any, ClassVar, Generic, Optional, Protocol, Self, TextIO, TypeVar, overload from pants.engine.fs import ( CreateDigest, @@ -65,9 +49,9 @@ class PyFailure: # Address # ------------------------------------------------------------------------------ -BANNED_CHARS_IN_TARGET_NAME: FrozenSet -BANNED_CHARS_IN_GENERATED_NAME: FrozenSet -BANNED_CHARS_IN_PARAMETERS: FrozenSet +BANNED_CHARS_IN_TARGET_NAME: frozenset +BANNED_CHARS_IN_GENERATED_NAME: frozenset +BANNED_CHARS_IN_PARAMETERS: frozenset def address_spec_parse( spec: str, @@ -668,7 +652,7 @@ class PyOptionId: ) -> None: ... class PyPantsCommand: - def builtin_or_auxiliary_goal(self) -> Optional[str]: ... + def builtin_or_auxiliary_goal(self) -> str | None: ... def goals(self) -> list[str]: ... def unknown_goals(self) -> list[str]: ... def specs(self) -> list[str]: ... @@ -681,28 +665,28 @@ class PyConfigSource: T = TypeVar("T") # List of tuples of (value, rank, details string). -OptionValueDerivation = list[Tuple[T, int, str]] +OptionValueDerivation = list[tuple[T, int, str]] # A tuple (value, rank of value, optional derivation of value). -OptionValue = Tuple[Optional[T], int, Optional[OptionValueDerivation]] +OptionValue = tuple[Optional[T], int, Optional[OptionValueDerivation]] def py_bin_name() -> str: ... class PyOptionParser: def __init__( self, - args: Optional[Sequence[str]], + args: Sequence[str] | None, env: dict[str, str], - configs: Optional[Sequence[PyConfigSource]], + configs: Sequence[PyConfigSource] | None, allow_pantsrc: bool, include_derivation: bool, - known_scopes_to_flags: Optional[dict[str, frozenset[str]]], - known_goals: Optional[Sequence[PyGoalInfo]], + known_scopes_to_flags: dict[str, frozenset[str]] | None, + known_goals: Sequence[PyGoalInfo] | None, ) -> None: ... - def get_bool(self, option_id: PyOptionId, default: Optional[bool]) -> OptionValue[bool]: ... - def get_int(self, option_id: PyOptionId, default: Optional[int]) -> OptionValue[int]: ... - def get_float(self, option_id: PyOptionId, default: Optional[float]) -> OptionValue[float]: ... - def get_string(self, option_id: PyOptionId, default: Optional[str]) -> OptionValue[str]: ... + def get_bool(self, option_id: PyOptionId, default: bool | None) -> OptionValue[bool]: ... + def get_int(self, option_id: PyOptionId, default: int | None) -> OptionValue[int]: ... + def get_float(self, option_id: PyOptionId, default: float | None) -> OptionValue[float]: ... + def get_string(self, option_id: PyOptionId, default: str | None) -> OptionValue[str]: ... def get_bool_list( self, option_id: PyOptionId, default: list[bool] ) -> OptionValue[list[bool]]: ... @@ -921,7 +905,7 @@ def rule_subgraph_visualize( def garbage_collect_store(scheduler: PyScheduler, target_size_bytes: int) -> None: ... def lease_files_in_graph(scheduler: PyScheduler, session: PySession) -> None: ... def strongly_connected_components( - adjacency_lists: Sequence[Tuple[Any, Sequence[Any]]] + adjacency_lists: Sequence[tuple[Any, Sequence[Any]]] ) -> Sequence[Sequence[Any]]: ... def hash_prefix_zero_bits(item: str) -> int: ... diff --git a/src/python/pants/engine/internals/nodes.py b/src/python/pants/engine/internals/nodes.py index f2d453653d6..241fe00a8b6 100644 --- a/src/python/pants/engine/internals/nodes.py +++ b/src/python/pants/engine/internals/nodes.py @@ -4,7 +4,7 @@ from __future__ import annotations from dataclasses import dataclass -from typing import Any, Optional, Tuple +from typing import Any, Optional @dataclass(frozen=True) @@ -14,7 +14,7 @@ class Return: value: Any -_Frame = Tuple[str, Optional[str]] +_Frame = tuple[str, Optional[str]] @dataclass(frozen=True) diff --git a/src/python/pants/engine/internals/parametrize.py b/src/python/pants/engine/internals/parametrize.py index 68189c19436..404bf27d0cb 100644 --- a/src/python/pants/engine/internals/parametrize.py +++ b/src/python/pants/engine/internals/parametrize.py @@ -7,12 +7,11 @@ import itertools import operator from collections import abc, defaultdict +from collections.abc import Iterator, Mapping from dataclasses import dataclass from enum import Enum from functools import reduce -from typing import Any, Iterator, Mapping, cast - -from typing_extensions import Self +from typing import Any, Self, cast from pants.build_graph.address import BANNED_CHARS_IN_PARAMETERS from pants.engine.addresses import Address diff --git a/src/python/pants/engine/internals/parser.py b/src/python/pants/engine/internals/parser.py index cba242fd533..e3535e90cd6 100644 --- a/src/python/pants/engine/internals/parser.py +++ b/src/python/pants/engine/internals/parser.py @@ -11,11 +11,12 @@ import tokenize import traceback import typing +from collections.abc import Callable, Iterable, Mapping from dataclasses import InitVar, dataclass, field from difflib import get_close_matches from io import StringIO from pathlib import PurePath -from typing import Annotated, Any, Callable, Iterable, Mapping, TypeVar +from typing import Annotated, Any, TypeVar import typing_extensions diff --git a/src/python/pants/engine/internals/rule_visitor.py b/src/python/pants/engine/internals/rule_visitor.py index ef75ff8276c..b34c275d78d 100644 --- a/src/python/pants/engine/internals/rule_visitor.py +++ b/src/python/pants/engine/internals/rule_visitor.py @@ -7,9 +7,10 @@ import itertools import logging import sys +from collections.abc import Callable, Iterator, Sequence from contextlib import contextmanager from functools import partial -from typing import Any, Callable, Iterator, List, Sequence, get_type_hints +from typing import Any, get_type_hints import typing_extensions @@ -144,7 +145,7 @@ def __init__(self, func: Callable): self.source_file = inspect.getsourcefile(func) or "" self.types = _TypeStack(func) - self.awaitables: List[AwaitableConstraints] = [] + self.awaitables: list[AwaitableConstraints] = [] self.visit(ast.parse(source)) def _format(self, node: ast.AST, msg: str) -> str: @@ -201,7 +202,7 @@ def _check_constraint_arg_type(self, resolved: Any, node: ast.AST) -> type: ) return resolved - def _get_inputs(self, input_nodes: Sequence[Any]) -> tuple[Sequence[Any], List[Any]]: + def _get_inputs(self, input_nodes: Sequence[Any]) -> tuple[Sequence[Any], list[Any]]: if not input_nodes: return input_nodes, [] if len(input_nodes) != 1: @@ -390,5 +391,5 @@ def visit_Assign(self, assign_node: ast.Assign) -> None: @memoized -def collect_awaitables(func: Callable) -> List[AwaitableConstraints]: +def collect_awaitables(func: Callable) -> list[AwaitableConstraints]: return _AwaitableCollector(func).awaitables diff --git a/src/python/pants/engine/internals/rule_visitor_test.py b/src/python/pants/engine/internals/rule_visitor_test.py index 1ca8ddb36ae..69370aa37f2 100644 --- a/src/python/pants/engine/internals/rule_visitor_test.py +++ b/src/python/pants/engine/internals/rule_visitor_test.py @@ -3,8 +3,8 @@ from __future__ import annotations +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable import pytest diff --git a/src/python/pants/engine/internals/scheduler.py b/src/python/pants/engine/internals/scheduler.py index 0b4af130f04..0325551d421 100644 --- a/src/python/pants/engine/internals/scheduler.py +++ b/src/python/pants/engine/internals/scheduler.py @@ -6,10 +6,11 @@ import logging import os import time +from collections.abc import Callable, Iterable, Sequence from dataclasses import dataclass from pathlib import PurePath from types import CoroutineType -from typing import Any, Callable, Dict, Iterable, NoReturn, Sequence, cast +from typing import Any, NoReturn, cast from typing_extensions import TypedDict @@ -80,7 +81,7 @@ logger = logging.getLogger(__name__) -Workunit = Dict[str, Any] +Workunit = dict[str, Any] class PolledWorkunits(TypedDict): diff --git a/src/python/pants/engine/internals/selectors.py b/src/python/pants/engine/internals/selectors.py index c4a04110bd0..139e5ff9e57 100644 --- a/src/python/pants/engine/internals/selectors.py +++ b/src/python/pants/engine/internals/selectors.py @@ -5,20 +5,9 @@ import ast import itertools +from collections.abc import Coroutine, Generator, Iterable, Sequence from dataclasses import dataclass -from typing import ( - TYPE_CHECKING, - Any, - Coroutine, - Generator, - Generic, - Iterable, - Sequence, - Tuple, - TypeVar, - cast, - overload, -) +from typing import TYPE_CHECKING, Any, Generic, TypeVar, cast, overload from pants.engine.internals.native_engine import PyGeneratorResponseCall, PyGeneratorResponseGet from pants.util.strutil import softwrap @@ -172,7 +161,7 @@ class _MultiGet: def __await__(self) -> Generator[tuple[Get | Coroutine, ...], None, tuple]: result = yield self.gets - return cast(Tuple, result) + return cast(tuple, result) # These type variables are used to parametrize from 1 to 10 Gets when used in a tuple-style diff --git a/src/python/pants/engine/internals/selectors_test.py b/src/python/pants/engine/internals/selectors_test.py index d8dae2bdedd..1cf2b35c9a4 100644 --- a/src/python/pants/engine/internals/selectors_test.py +++ b/src/python/pants/engine/internals/selectors_test.py @@ -2,8 +2,8 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). import re +from collections.abc import Callable from dataclasses import dataclass -from typing import Callable import pytest diff --git a/src/python/pants/engine/internals/session.py b/src/python/pants/engine/internals/session.py index 1f6fb73675b..57454cb3d2b 100644 --- a/src/python/pants/engine/internals/session.py +++ b/src/python/pants/engine/internals/session.py @@ -1,7 +1,7 @@ # Copyright 2016 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). -from typing import Any, Type, TypeVar, cast +from typing import Any, TypeVar, cast from pants.util.frozendict import FrozenDict @@ -16,7 +16,7 @@ class RunId(int): """ -class SessionValues(FrozenDict[Type, Any]): +class SessionValues(FrozenDict[type, Any]): """Values set for the Session, and exposed to @rules. Generally, each type provided via `SessionValues` should have a simple rule that returns the @@ -24,7 +24,7 @@ class SessionValues(FrozenDict[Type, Any]): `SessionValues`. """ - def __getitem__(self, item: Type[_T]) -> _T: + def __getitem__(self, item: type[_T]) -> _T: try: return cast(_T, super().__getitem__(item)) except KeyError: diff --git a/src/python/pants/engine/internals/specs_rules.py b/src/python/pants/engine/internals/specs_rules.py index b6f7117f341..3659e449d17 100644 --- a/src/python/pants/engine/internals/specs_rules.py +++ b/src/python/pants/engine/internals/specs_rules.py @@ -8,7 +8,7 @@ import logging import os from collections import defaultdict -from typing import Iterable +from collections.abc import Iterable from pants.backend.project_info.filter_targets import FilterSubsystem from pants.base.specs import ( diff --git a/src/python/pants/engine/internals/specs_rules_test.py b/src/python/pants/engine/internals/specs_rules_test.py index aaf31c4877d..d0f8e6222c5 100644 --- a/src/python/pants/engine/internals/specs_rules_test.py +++ b/src/python/pants/engine/internals/specs_rules_test.py @@ -3,9 +3,9 @@ from __future__ import annotations +from collections.abc import Iterable from dataclasses import dataclass from textwrap import dedent -from typing import Iterable, Type import pytest @@ -877,7 +877,7 @@ class FieldSetSubclass2(FieldSetSuperclass): invalid_spec = AddressLiteralSpec("", "invalid") def find_valid_field_sets( - superclass: Type, + superclass: type, specs: Iterable[Spec], *, no_applicable_behavior: NoApplicableTargetsBehavior = NoApplicableTargetsBehavior.ignore, diff --git a/src/python/pants/engine/internals/synthetic_targets.py b/src/python/pants/engine/internals/synthetic_targets.py index 2774f5bac13..96d90e810c4 100644 --- a/src/python/pants/engine/internals/synthetic_targets.py +++ b/src/python/pants/engine/internals/synthetic_targets.py @@ -75,8 +75,9 @@ def rules(): import itertools import os.path +from collections.abc import Iterable, Iterator, Sequence from dataclasses import dataclass -from typing import ClassVar, Iterable, Iterator, Sequence +from typing import ClassVar from pants.base.specs import GlobSpecsProtocol from pants.engine.collection import Collection diff --git a/src/python/pants/engine/internals/target_adaptor.py b/src/python/pants/engine/internals/target_adaptor.py index b5125ab0e07..b5eec22c08c 100644 --- a/src/python/pants/engine/internals/target_adaptor.py +++ b/src/python/pants/engine/internals/target_adaptor.py @@ -5,9 +5,7 @@ import dataclasses from dataclasses import dataclass -from typing import Any - -from typing_extensions import final +from typing import Any, final from pants.build_graph.address import Address from pants.engine.engine_aware import EngineAwareParameter diff --git a/src/python/pants/engine/internals/testutil.py b/src/python/pants/engine/internals/testutil.py index 59e96e65f30..ec4e9dd1944 100644 --- a/src/python/pants/engine/internals/testutil.py +++ b/src/python/pants/engine/internals/testutil.py @@ -3,7 +3,7 @@ from __future__ import annotations -from typing import Iterable +from collections.abc import Iterable from pants.base.glob_match_error_behavior import GlobMatchErrorBehavior from pants.base.specs import RawSpecs, RawSpecsWithoutFileOwners, Spec diff --git a/src/python/pants/engine/process.py b/src/python/pants/engine/process.py index 9990a20b659..16fcc972989 100644 --- a/src/python/pants/engine/process.py +++ b/src/python/pants/engine/process.py @@ -5,9 +5,9 @@ import dataclasses import logging +from collections.abc import Iterable, Mapping from dataclasses import dataclass, field from enum import Enum -from typing import Iterable, List, Mapping, Tuple from pants.engine.engine_aware import SideEffecting from pants.engine.fs import EMPTY_DIGEST, Digest, FileDigest @@ -201,7 +201,7 @@ def platform(self) -> Platform: @dataclass(frozen=True) class ProcessResultWithRetries: - results: Tuple[FallibleProcessResult, ...] + results: tuple[FallibleProcessResult, ...] @property def last(self): @@ -354,7 +354,7 @@ def fallible_to_exec_result_or_raise( @rule async def execute_process_with_retry(req: ProcessWithRetries) -> ProcessResultWithRetries: - results: List[FallibleProcessResult] = [] + results: list[FallibleProcessResult] = [] for attempt in range(0, req.attempts): proc = dataclasses.replace(req.proc, attempt=attempt) result = ( diff --git a/src/python/pants/engine/rules.py b/src/python/pants/engine/rules.py index 0962eccedcc..72a5e6a43c2 100644 --- a/src/python/pants/engine/rules.py +++ b/src/python/pants/engine/rules.py @@ -6,26 +6,11 @@ import functools import inspect import sys +from collections.abc import Callable, Coroutine, Iterable, Mapping, Sequence from dataclasses import dataclass from enum import Enum from types import FrameType, ModuleType -from typing import ( - Any, - Callable, - Coroutine, - Iterable, - Mapping, - Optional, - Protocol, - Sequence, - Tuple, - Type, - TypeVar, - Union, - cast, - get_type_hints, - overload, -) +from typing import Any, Protocol, TypeVar, Union, cast, get_type_hints, overload from typing_extensions import ParamSpec @@ -79,13 +64,13 @@ async def wrapper(*args, __implicitly: Sequence[Any] = (), **kwargs): def _make_rule( func_id: str, rule_type: RuleType, - return_type: Type, - parameter_types: dict[str, Type], - masked_types: Iterable[Type], + return_type: type, + parameter_types: dict[str, type], + masked_types: Iterable[type], *, cacheable: bool, canonical_name: str, - desc: Optional[str], + desc: str | None, level: LogLevel, ) -> RuleDecorator: """A @decorator that declares that a particular static function may be used as a TaskRule. @@ -167,10 +152,10 @@ class DuplicateRuleError(TypeError): def _ensure_type_annotation( *, - type_annotation: Optional[Type], + type_annotation: type | None, name: str, - raise_type: Type[InvalidTypeAnnotation], -) -> Type: + raise_type: type[InvalidTypeAnnotation], +) -> type: if type_annotation is None: raise raise_type(f"{name} is missing a type annotation.") if not isinstance(type_annotation, type): @@ -312,8 +297,8 @@ def rule_decorator(func: SyncRuleT | AsyncRuleT, **kwargs) -> AsyncRuleT: def validate_requirements( func_id: str, - parameter_types: dict[str, Type], - awaitables: Tuple[AwaitableConstraints, ...], + parameter_types: dict[str, type], + awaitables: tuple[AwaitableConstraints, ...], cacheable: bool, ) -> None: # TODO: Technically this will also fire for an @_uncacheable_rule, but we don't expose those as @@ -367,7 +352,7 @@ def rule(func: Callable[P, R]) -> Callable[P, Coroutine[Any, Any, R]]: ... @overload def rule( *args, func: None = None, **kwargs: Any -) -> Callable[[Union[SyncRuleT, AsyncRuleT]], AsyncRuleT]: ... +) -> Callable[[SyncRuleT | AsyncRuleT], AsyncRuleT]: ... def rule(*args, **kwargs): @@ -385,7 +370,7 @@ def goal_rule(func: Callable[P, R]) -> Callable[P, Coroutine[Any, Any, R]]: ... @overload def goal_rule( *args, func: None = None, **kwargs: Any -) -> Callable[[Union[SyncRuleT, AsyncRuleT]], AsyncRuleT]: ... +) -> Callable[[SyncRuleT | AsyncRuleT], AsyncRuleT]: ... def goal_rule(*args, **kwargs): @@ -407,7 +392,7 @@ def _uncacheable_rule(func: Callable[P, R]) -> Callable[P, Coroutine[Any, Any, R @overload def _uncacheable_rule( *args, func: None = None, **kwargs: Any -) -> Callable[[Union[SyncRuleT, AsyncRuleT]], AsyncRuleT]: ... +) -> Callable[[SyncRuleT | AsyncRuleT], AsyncRuleT]: ... # This has a "private" name, as we don't (yet?) want it to be part of the rule API, at least @@ -428,7 +413,7 @@ def output_type(self): """An output `type` for the rule.""" -def collect_rules(*namespaces: Union[ModuleType, Mapping[str, Any]]) -> Iterable[Rule]: +def collect_rules(*namespaces: ModuleType | Mapping[str, Any]) -> Iterable[Rule]: """Collects all @rules in the given namespaces. If no namespaces are given, collects all the @rules in the caller's module namespace. @@ -471,13 +456,13 @@ class TaskRule: prefer the `@rule` constructor. """ - output_type: Type - parameters: FrozenDict[str, Type] - awaitables: Tuple[AwaitableConstraints, ...] - masked_types: Tuple[Type, ...] + output_type: type + parameters: FrozenDict[str, type] + awaitables: tuple[AwaitableConstraints, ...] + masked_types: tuple[type, ...] func: Callable canonical_name: str - desc: Optional[str] = None + desc: str | None = None level: LogLevel = LogLevel.TRACE cacheable: bool = True @@ -499,10 +484,10 @@ class QueryRule: that the relevant portions of the RuleGraph are generated. """ - output_type: Type - input_types: Tuple[Type, ...] + output_type: type + input_types: tuple[type, ...] - def __init__(self, output_type: Type, input_types: Iterable[Type]) -> None: + def __init__(self, output_type: type, input_types: Iterable[type]) -> None: object.__setattr__(self, "output_type", output_type) object.__setattr__(self, "input_types", tuple(input_types)) diff --git a/src/python/pants/engine/rules_test.py b/src/python/pants/engine/rules_test.py index f6230bbfc7c..c4334dd3647 100644 --- a/src/python/pants/engine/rules_test.py +++ b/src/python/pants/engine/rules_test.py @@ -2,11 +2,12 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). import re +from collections.abc import Callable from dataclasses import dataclass from enum import Enum from pathlib import Path from textwrap import dedent -from typing import Callable, List, Optional, Tuple, Type, Union, get_type_hints +from typing import get_type_hints import pytest @@ -52,7 +53,7 @@ def create_scheduler(rules, validate=True): def fmt_rule( - rule: Callable, *, gets: Optional[List[Tuple[str, str]]] = None, multiline: bool = False + rule: Callable, *, gets: list[tuple[str, str]] | None = None, multiline: bool = False ) -> str: """Generate the str that the engine will use for the rule. @@ -86,8 +87,8 @@ def fmt_rust_function(func: Callable) -> str: @dataclass(frozen=True) class RuleFormatRequest: rule: Callable - for_param: Optional[Union[Type, Tuple[Type, ...]]] = None - gets: Optional[List[Tuple[str, str]]] = None + for_param: type | tuple[type, ...] | None = None + gets: list[tuple[str, str]] | None = None def format(self) -> str: msg = fmt_rule(self.rule, gets=self.gets, multiline=True) @@ -111,10 +112,10 @@ def format_rule(cls, obj): def fmt_param_edge( - param: Type, - product: Union[Type, Tuple[Type, ...]], - via_func: Union[Type, RuleFormatRequest], - return_func: Optional[RuleFormatRequest] = None, + param: type, + product: type | tuple[type, ...], + via_func: type | RuleFormatRequest, + return_func: RuleFormatRequest | None = None, ) -> str: if isinstance(via_func, type): via_func_str = f"Select({via_func.__name__})" @@ -150,7 +151,7 @@ class GraphVertexType(Enum): intrinsic = "intrinsic" param = "param" - def graph_vertex_color_fmt_str(self) -> Optional[str]: + def graph_vertex_color_fmt_str(self) -> str | None: olive = "0.2214,0.7179,0.8528" gray = "0.576,0,0.6242" orange = "0.08,0.5,0.976" @@ -172,9 +173,9 @@ def graph_vertex_color_fmt_str(self) -> Optional[str]: def fmt_non_param_edge( - subject: Union[Type, Callable, RuleFormatRequest], - product: Union[Type, Tuple[Type, ...]], - return_func: Optional[RuleFormatRequest] = None, + subject: type | Callable | RuleFormatRequest, + product: type | tuple[type, ...], + return_func: RuleFormatRequest | None = None, rule_type: GraphVertexType = GraphVertexType.task, append_for_product: bool = True, ) -> str: diff --git a/src/python/pants/engine/streaming_workunit_handler.py b/src/python/pants/engine/streaming_workunit_handler.py index 012b8cfc1cf..245b366af94 100644 --- a/src/python/pants/engine/streaming_workunit_handler.py +++ b/src/python/pants/engine/streaming_workunit_handler.py @@ -6,8 +6,9 @@ import logging import threading from abc import ABC, abstractmethod +from collections.abc import Callable, Iterable, Sequence from dataclasses import dataclass -from typing import Any, Callable, Iterable, Sequence, Tuple +from typing import Any from pants.base.specs import Specs from pants.core.util_rules.environments import determine_bootstrap_environment @@ -195,7 +196,7 @@ class WorkunitsCallbackFactory: callback_factory: Callable[[], WorkunitsCallback | None] -class WorkunitsCallbackFactories(Tuple[WorkunitsCallbackFactory, ...]): +class WorkunitsCallbackFactories(tuple[WorkunitsCallbackFactory, ...]): """A list of registered factories for WorkunitsCallback instances.""" diff --git a/src/python/pants/engine/streaming_workunit_handler_integration_test.py b/src/python/pants/engine/streaming_workunit_handler_integration_test.py index 3e50dcefc77..0b242466e7c 100644 --- a/src/python/pants/engine/streaming_workunit_handler_integration_test.py +++ b/src/python/pants/engine/streaming_workunit_handler_integration_test.py @@ -5,7 +5,7 @@ import os import signal -from typing import Mapping +from collections.abc import Mapping import pytest from workunit_logger.register import FINISHED_SUCCESSFULLY diff --git a/src/python/pants/engine/target.py b/src/python/pants/engine/target.py index 3d73dd6547e..1d1216f8371 100644 --- a/src/python/pants/engine/target.py +++ b/src/python/pants/engine/target.py @@ -14,6 +14,7 @@ import zlib from abc import ABC, ABCMeta, abstractmethod from collections import deque +from collections.abc import Callable, Iterable, Iterator, KeysView, Mapping, Sequence from dataclasses import dataclass from enum import Enum from operator import attrgetter @@ -21,28 +22,16 @@ from typing import ( AbstractSet, Any, - Callable, ClassVar, - Dict, Generic, - Iterable, - Iterator, - KeysView, - Mapping, - Optional, Protocol, - Sequence, - Set, - Tuple, - Type, + Self, TypeVar, - Union, cast, + final, get_type_hints, ) -from typing_extensions import Self, final - from pants.base.deprecated import warn_or_error from pants.engine.addresses import Address, Addresses, UnparsedAddressInputs, assert_single_address from pants.engine.collection import Collection @@ -135,7 +124,7 @@ def hydrate_sources(request: HydrateSourcesRequest) -> HydratedSources: address: Address @final - def __new__(cls, raw_value: Optional[Any], address: Address) -> Self: + def __new__(cls, raw_value: Any | None, address: Address) -> Self: obj = super().__new__(cls, raw_value, address) # type: ignore[call-arg] # N.B.: We store the address here and not in the Field base class, because the memory usage # of storing this value in every field was shown to be excessive / lead to performance @@ -255,7 +244,7 @@ class Target: # Subclasses must define these alias: ClassVar[str] - core_fields: ClassVar[Tuple[Type[Field], ...]] + core_fields: ClassVar[tuple[type[Field], ...]] help: ClassVar[str | Callable[[], str]] removal_version: ClassVar[str | None] = None @@ -410,7 +399,7 @@ def _get_field_aliases_to_field_types( @final @property - def field_types(self) -> KeysView[Type[Field]]: + def field_types(self) -> KeysView[type[Field]]: return self.field_values.keys() @distinct_union_type_per_subclass @@ -436,7 +425,7 @@ def __str__(self) -> str: def __hash__(self) -> int: return hash((self.__class__, self.address, self.residence_dir, self.field_values)) - def __eq__(self, other: Union[Target, Any]) -> bool: + def __eq__(self, other: Target | Any) -> bool: if not isinstance(other, Target): return NotImplemented return (self.__class__, self.address, self.residence_dir, self.field_values) == ( @@ -472,8 +461,8 @@ def _find_plugin_fields(cls, union_membership: UnionMembership) -> tuple[type[Fi @final @classmethod def _find_registered_field_subclass( - cls, requested_field: Type[_F], *, registered_fields: Iterable[Type[Field]] - ) -> Optional[Type[_F]]: + cls, requested_field: type[_F], *, registered_fields: Iterable[type[Field]] + ) -> type[_F] | None: """Check if the Target has registered a subclass of the requested Field. This is necessary to allow targets to override the functionality of common fields. For @@ -492,7 +481,7 @@ def _find_registered_field_subclass( return subclass @final - def _maybe_get(self, field: Type[_F]) -> Optional[_F]: + def _maybe_get(self, field: type[_F]) -> _F | None: result = self.field_values.get(field, None) if result is not None: return cast(_F, result) @@ -504,7 +493,7 @@ def _maybe_get(self, field: Type[_F]) -> Optional[_F]: return None @final - def __getitem__(self, field: Type[_F]) -> _F: + def __getitem__(self, field: type[_F]) -> _F: """Get the requested `Field` instance belonging to this target. If the `Field` is not registered on this `Target` type, this method will raise a @@ -525,7 +514,7 @@ def __getitem__(self, field: Type[_F]) -> _F: ) @final - def get(self, field: Type[_F], *, default_raw_value: Optional[Any] = None) -> _F: + def get(self, field: type[_F], *, default_raw_value: Any | None = None) -> _F: """Get the requested `Field` instance belonging to this target. This will return an instance of the requested field type, e.g. an instance of @@ -551,7 +540,7 @@ def get(self, field: Type[_F], *, default_raw_value: Optional[Any] = None) -> _F @final @classmethod def _has_fields( - cls, fields: Iterable[Type[Field]], *, registered_fields: AbstractSet[Type[Field]] + cls, fields: Iterable[type[Field]], *, registered_fields: AbstractSet[type[Field]] ) -> bool: unrecognized_fields = [field for field in fields if field not in registered_fields] if not unrecognized_fields: @@ -565,7 +554,7 @@ def _has_fields( return True @final - def has_field(self, field: Type[Field]) -> bool: + def has_field(self, field: type[Field]) -> bool: """Check that this target has registered the requested field. This works with subclasses of `Field`. For example, if you subclass `Tags` to define a @@ -575,7 +564,7 @@ def has_field(self, field: Type[Field]) -> bool: return self.has_fields([field]) @final - def has_fields(self, fields: Iterable[Type[Field]]) -> bool: + def has_fields(self, fields: Iterable[type[Field]]) -> bool: """Check that this target has registered all of the requested fields. This works with subclasses of `Field`. For example, if you subclass `Tags` to define a @@ -589,7 +578,7 @@ def has_fields(self, fields: Iterable[Type[Field]]) -> bool: @memoized_method def class_field_types( cls, union_membership: UnionMembership | None - ) -> FrozenOrderedSet[Type[Field]]: + ) -> FrozenOrderedSet[type[Field]]: """Return all registered Fields belonging to this target type. You can also use the instance property `tgt.field_types` to avoid having to pass the @@ -602,7 +591,7 @@ def class_field_types( @final @classmethod - def class_has_field(cls, field: Type[Field], union_membership: UnionMembership) -> bool: + def class_has_field(cls, field: type[Field], union_membership: UnionMembership) -> bool: """Behaves like `Target.has_field()`, but works as a classmethod rather than an instance method.""" return cls.class_has_fields([field], union_membership) @@ -610,7 +599,7 @@ def class_has_field(cls, field: Type[Field], union_membership: UnionMembership) @final @classmethod def class_has_fields( - cls, fields: Iterable[Type[Field]], union_membership: UnionMembership + cls, fields: Iterable[type[Field]], union_membership: UnionMembership ) -> bool: """Behaves like `Target.has_fields()`, but works as a classmethod rather than an instance method.""" @@ -618,7 +607,7 @@ def class_has_fields( @final @classmethod - def class_get_field(cls, field: Type[_F], union_membership: UnionMembership) -> Type[_F]: + def class_get_field(cls, field: type[_F], union_membership: UnionMembership) -> type[_F]: """Get the requested Field type registered with this target type. This will error if the field is not registered, so you should call Target.class_has_field() @@ -642,7 +631,7 @@ def class_get_field(cls, field: Type[_F], union_membership: UnionMembership) -> return result @classmethod - def register_plugin_field(cls, field: Type[Field]) -> UnionRule: + def register_plugin_field(cls, field: type[Field]) -> UnionRule: """Register a new field on the target type. In the `rules()` register.py entry-point, include @@ -839,7 +828,7 @@ def __init__(self, members: Iterable[Target], dependencies: Iterable[CoarsenedTa def debug_hint(self) -> str: return str(self) - def metadata(self) -> Dict[str, Any]: + def metadata(self) -> dict[str, Any]: return {"addresses": [t.address.spec for t in self.members]} @property @@ -851,12 +840,12 @@ def bullet_list(self) -> str: """The addresses and type aliases of all members of the cycle.""" return bullet_list(sorted(f"{t.address.spec}\t({type(t).alias})" for t in self.members)) - def closure(self, visited: Set[CoarsenedTarget] | None = None) -> Iterator[Target]: + def closure(self, visited: set[CoarsenedTarget] | None = None) -> Iterator[Target]: """All Targets reachable from this root.""" return (t for ct in self.coarsened_closure(visited) for t in ct.members) def coarsened_closure( - self, visited: Set[CoarsenedTarget] | None = None + self, visited: set[CoarsenedTarget] | None = None ) -> Iterator[CoarsenedTarget]: """All CoarsenedTargets reachable from this root.""" @@ -920,12 +909,12 @@ def by_address(self) -> dict[Address, CoarsenedTarget]: def closure(self) -> Iterator[Target]: """All Targets reachable from these CoarsenedTarget roots.""" - visited: Set[CoarsenedTarget] = set() + visited: set[CoarsenedTarget] = set() return (t for root in self for t in root.closure(visited)) def coarsened_closure(self) -> Iterator[CoarsenedTarget]: """All CoarsenedTargets reachable from these CoarsenedTarget roots.""" - visited: Set[CoarsenedTarget] = set() + visited: set[CoarsenedTarget] = set() return (ct for root in self for ct in root.coarsened_closure(visited)) def __eq__(self, other: Any) -> bool: @@ -944,7 +933,7 @@ def __hash__(self): class CoarsenedTargetsRequest: """A request to get CoarsenedTargets for input roots.""" - roots: Tuple[Address, ...] + roots: tuple[Address, ...] expanded_targets: bool should_traverse_deps_predicate: ShouldTraverseDepsPredicate @@ -968,7 +957,7 @@ class TransitiveTargets: and in `dependencies`. """ - roots: Tuple[Target, ...] + roots: tuple[Target, ...] dependencies: FrozenOrderedSet[Target] @memoized_property @@ -985,7 +974,7 @@ class TransitiveTargetsRequest: TransitiveTargetsRequest([addr1, addr2]))`. """ - roots: Tuple[Address, ...] + roots: tuple[Address, ...] should_traverse_deps_predicate: ShouldTraverseDepsPredicate def __init__( @@ -1000,13 +989,13 @@ def __init__( @dataclass(frozen=True) class RegisteredTargetTypes: - aliases_to_types: FrozenDict[str, Type[Target]] + aliases_to_types: FrozenDict[str, type[Target]] - def __init__(self, aliases_to_types: Mapping[str, Type[Target]]) -> None: + def __init__(self, aliases_to_types: Mapping[str, type[Target]]) -> None: object.__setattr__(self, "aliases_to_types", FrozenDict(aliases_to_types)) @classmethod - def create(cls, target_types: Iterable[Type[Target]]) -> RegisteredTargetTypes: + def create(cls, target_types: Iterable[type[Target]]) -> RegisteredTargetTypes: result = {} for target_type in sorted(target_types, key=lambda tt: tt.alias): result[target_type.alias] = target_type @@ -1067,7 +1056,7 @@ class TargetGenerator(Target): # Fields should be copied from the generator to the generated when their semantic meaning is # the same for both Target types, and when it is valuable for them to be introspected on # either the generator or generated target (such as by `peek`, or in `filter`). - copied_fields: ClassVar[Tuple[Type[Field], ...]] + copied_fields: ClassVar[tuple[type[Field], ...]] # Fields which are specified to instances of the generator Target, but which are propagated # to generated Targets rather than being stored on the generator Target. @@ -1078,7 +1067,7 @@ class TargetGenerator(Target): # it can also be the case that a Field only makes sense semantically when it is applied to # the generated Target (for example, for an individual file), and the generator Target is just # acting as a convenient place for them to be specified. - moved_fields: ClassVar[Tuple[Type[Field], ...]] + moved_fields: ClassVar[tuple[type[Field], ...]] @distinct_union_type_per_subclass class MovedPluginField: @@ -1100,7 +1089,7 @@ def validate(self) -> None: ) @classmethod - def register_plugin_field(cls, field: Type[Field], *, as_moved_field=False) -> UnionRule: + def register_plugin_field(cls, field: type[Field], *, as_moved_field=False) -> UnionRule: if as_moved_field: return UnionRule(cls.MovedPluginField, field) else: @@ -1259,7 +1248,7 @@ def __init__(self, generator: Target, generated_targets: Iterable[Target]) -> No class TargetTypesToGenerateTargetsRequests( - FrozenDict[Type[TargetGenerator], Type[GenerateTargetsRequest]] + FrozenDict[type[TargetGenerator], type[GenerateTargetsRequest]] ): def is_generator(self, tgt: Target) -> bool: """Does this target type generate other targets?""" @@ -1388,8 +1377,8 @@ def gen_tgt(address: Address, full_fp: str, generated_target_fields: dict[str, A # FieldSet # ----------------------------------------------------------------------------------------------- def _get_field_set_fields_from_target( - field_set: Type[FieldSet], target: Target -) -> Dict[str, Field]: + field_set: type[FieldSet], target: Target +) -> dict[str, Field]: return { dataclass_field_name: ( target[field_cls] if field_cls in field_set.required_fields else target.get(field_cls) @@ -1442,7 +1431,7 @@ class methods: print(field_set.sources) """ - required_fields: ClassVar[Tuple[Type[Field], ...]] + required_fields: ClassVar[tuple[type[Field], ...]] address: Address @@ -1467,8 +1456,8 @@ def is_applicable(cls, tgt: Target) -> bool: @final @classmethod def applicable_target_types( - cls, target_types: Iterable[Type[Target]], union_membership: UnionMembership - ) -> Tuple[Type[Target], ...]: + cls, target_types: Iterable[type[Target]], union_membership: UnionMembership + ) -> tuple[type[Target], ...]: return tuple( tgt_type for tgt_type in target_types @@ -1477,12 +1466,12 @@ def applicable_target_types( @final @classmethod - def create(cls: Type[_FS], tgt: Target) -> _FS: + def create(cls: type[_FS], tgt: Target) -> _FS: return cls(address=tgt.address, **_get_field_set_fields_from_target(cls, tgt)) @final @memoized_classproperty - def fields(cls) -> FrozenDict[str, Type[Field]]: + def fields(cls) -> FrozenDict[str, type[Field]]: return FrozenDict( ( (name, field_type) @@ -1494,7 +1483,7 @@ def fields(cls) -> FrozenDict[str, Type[Field]]: def debug_hint(self) -> str: return self.address.spec - def metadata(self) -> Dict[str, Any]: + def metadata(self) -> dict[str, Any]: return {"address": self.address.spec} def __repr__(self) -> str: @@ -1505,7 +1494,7 @@ def __repr__(self) -> str: @dataclass(frozen=True) class TargetRootsToFieldSets(Generic[_FS]): - mapping: FrozenDict[Target, Tuple[_FS, ...]] + mapping: FrozenDict[Target, tuple[_FS, ...]] def __init__(self, mapping: Mapping[Target, Iterable[_FS]]) -> None: object.__setattr__( @@ -1515,7 +1504,7 @@ def __init__(self, mapping: Mapping[Target, Iterable[_FS]]) -> None: ) @memoized_property - def field_sets(self) -> Tuple[_FS, ...]: + def field_sets(self) -> tuple[_FS, ...]: return tuple( itertools.chain.from_iterable( field_sets_per_target for field_sets_per_target in self.mapping.values() @@ -1523,7 +1512,7 @@ def field_sets(self) -> Tuple[_FS, ...]: ) @memoized_property - def targets(self) -> Tuple[Target, ...]: + def targets(self) -> tuple[Target, ...]: return tuple(self.mapping.keys()) @@ -1533,7 +1522,7 @@ class NoApplicableTargetsBehavior(Enum): error = "error" -def parse_shard_spec(shard_spec: str, origin: str = "") -> Tuple[int, int]: +def parse_shard_spec(shard_spec: str, origin: str = "") -> tuple[int, int]: def invalid(): origin_str = f" from {origin}" if origin else "" return ValueError( @@ -1562,7 +1551,7 @@ def get_shard(key: str, num_shards: int) -> int: @dataclass(frozen=True) class TargetRootsToFieldSetsRequest(Generic[_FS]): - field_set_superclass: Type[_FS] + field_set_superclass: type[_FS] goal_description: str no_applicable_targets_behavior: NoApplicableTargetsBehavior shard: int @@ -1570,7 +1559,7 @@ class TargetRootsToFieldSetsRequest(Generic[_FS]): def __init__( self, - field_set_superclass: Type[_FS], + field_set_superclass: type[_FS], *, goal_description: str, no_applicable_targets_behavior: NoApplicableTargetsBehavior, @@ -1590,22 +1579,22 @@ def is_in_shard(self, key: str) -> bool: @dataclass(frozen=True) class FieldSetsPerTarget(Generic[_FS]): # One tuple of FieldSet instances per input target. - collection: Tuple[Tuple[_FS, ...], ...] + collection: tuple[tuple[_FS, ...], ...] def __init__(self, collection: Iterable[Iterable[_FS]]): object.__setattr__(self, "collection", tuple(tuple(iterable) for iterable in collection)) @memoized_property - def field_sets(self) -> Tuple[_FS, ...]: + def field_sets(self) -> tuple[_FS, ...]: return tuple(itertools.chain.from_iterable(self.collection)) @dataclass(frozen=True) class FieldSetsPerTargetRequest(Generic[_FS]): - field_set_superclass: Type[_FS] - targets: Tuple[Target, ...] + field_set_superclass: type[_FS] + targets: tuple[Target, ...] - def __init__(self, field_set_superclass: Type[_FS], targets: Iterable[Target]): + def __init__(self, field_set_superclass: type[_FS], targets: Iterable[Target]): object.__setattr__(self, "field_set_superclass", field_set_superclass) object.__setattr__(self, "targets", tuple(targets)) @@ -1673,7 +1662,7 @@ def __init__( self, address: Address, field_alias: str, - raw_value: Optional[Any], + raw_value: Any | None, *, expected_type: str, description_of_origin: str | None = None, @@ -1692,7 +1681,7 @@ def __init__( self, address: Address, field_alias: str, - raw_value: Optional[Any], + raw_value: Any | None, *, expected_type: str, at_index: int, @@ -1727,7 +1716,7 @@ def __init__( self, address: Address, field_alias: str, - raw_value: Optional[Any], + raw_value: Any | None, *, valid_choices: Iterable[Any], description_of_origin: str | None = None, @@ -1790,13 +1779,13 @@ def compute_value( return super().compute_value(raw_value, address=address) """ - expected_type: ClassVar[Type[T]] # type: ignore[misc] + expected_type: ClassVar[type[T]] # type: ignore[misc] expected_type_description: ClassVar[str] - value: Optional[T] - default: ClassVar[Optional[T]] = None # type: ignore[misc] + value: T | None + default: ClassVar[T | None] = None # type: ignore[misc] @classmethod - def compute_value(cls, raw_value: Optional[Any], address: Address) -> Optional[T]: + def compute_value(cls, raw_value: Any | None, address: Address) -> T | None: value_or_default = super().compute_value(raw_value, address) if value_or_default is not None and not isinstance(value_or_default, cls.expected_type): raise InvalidFieldTypeException( @@ -1835,7 +1824,7 @@ class TriBoolField(ScalarField[bool]): expected_type_description = "a boolean or None" @classmethod - def compute_value(cls, raw_value: Optional[bool], address: Address) -> Optional[bool]: + def compute_value(cls, raw_value: bool | None, address: Address) -> bool | None: return super().compute_value(raw_value, address) @@ -1869,7 +1858,7 @@ class IntField(ScalarField[int]): valid_numbers: ClassVar[ValidNumbers] = ValidNumbers.all @classmethod - def compute_value(cls, raw_value: Optional[int], address: Address) -> Optional[int]: + def compute_value(cls, raw_value: int | None, address: Address) -> int | None: value_or_default = super().compute_value(raw_value, address) cls.valid_numbers.validate(value_or_default, cls.alias, address) return value_or_default @@ -1881,7 +1870,7 @@ class FloatField(ScalarField[float]): valid_numbers: ClassVar[ValidNumbers] = ValidNumbers.all @classmethod - def compute_value(cls, raw_value: Optional[float], address: Address) -> Optional[float]: + def compute_value(cls, raw_value: float | None, address: Address) -> float | None: value_or_default = super().compute_value(raw_value, address) cls.valid_numbers.validate(value_or_default, cls.alias, address) return value_or_default @@ -1896,10 +1885,10 @@ class StringField(ScalarField[str]): expected_type = str expected_type_description = "a string" - valid_choices: ClassVar[Optional[Union[Type[Enum], Tuple[str, ...]]]] = None + valid_choices: ClassVar[type[Enum] | tuple[str, ...] | None] = None @classmethod - def compute_value(cls, raw_value: Optional[str], address: Address) -> Optional[str]: + def compute_value(cls, raw_value: str | None, address: Address) -> str | None: value_or_default = super().compute_value(raw_value, address) if value_or_default is not None and cls.valid_choices is not None: _validate_choices( @@ -1927,15 +1916,15 @@ def compute_value( return super().compute_value(raw_value, address=address) """ - expected_element_type: ClassVar[Type] + expected_element_type: ClassVar[type] expected_type_description: ClassVar[str] - value: Optional[Tuple[T, ...]] - default: ClassVar[Optional[Tuple[T, ...]]] = None # type: ignore[misc] + value: tuple[T, ...] | None + default: ClassVar[tuple[T, ...] | None] = None # type: ignore[misc] @classmethod def compute_value( - cls, raw_value: Optional[Iterable[Any]], address: Address - ) -> Optional[Tuple[T, ...]]: + cls, raw_value: Iterable[Any] | None, address: Address + ) -> tuple[T, ...] | None: value_or_default = super().compute_value(raw_value, address) if value_or_default is None: return None @@ -1955,18 +1944,18 @@ class TupleSequenceField(Generic[T], Field): # this cannot be a SequenceField as compute_value's use of ensure_list # does not work with expected_element_type=tuple when the value itself # is already a tuple. - expected_element_type: ClassVar[Type] + expected_element_type: ClassVar[type] expected_element_count: ClassVar[int] # -1 for unlimited expected_type_description: ClassVar[str] expected_element_type_description: ClassVar[str] - value: Optional[Tuple[Tuple[T, ...], ...]] - default: ClassVar[Optional[Tuple[Tuple[T, ...], ...]]] = None # type: ignore[misc] + value: tuple[tuple[T, ...], ...] | None + default: ClassVar[tuple[tuple[T, ...], ...] | None] = None # type: ignore[misc] @classmethod def compute_value( - cls, raw_value: Optional[Iterable[Iterable[T]]], address: Address - ) -> Optional[tuple[tuple[T, ...], ...]]: + cls, raw_value: Iterable[Iterable[T]] | None, address: Address + ) -> tuple[tuple[T, ...], ...] | None: value_or_default = super().compute_value(raw_value, address) if value_or_default is None: return value_or_default @@ -2010,12 +1999,12 @@ def invalid_member_exception( class StringSequenceField(SequenceField[str]): expected_element_type = str expected_type_description = "an iterable of strings (e.g. a list of strings)" - valid_choices: ClassVar[Optional[Union[Type[Enum], Tuple[str, ...]]]] = None + valid_choices: ClassVar[type[Enum] | tuple[str, ...] | None] = None @classmethod def compute_value( - cls, raw_value: Optional[Iterable[str]], address: Address - ) -> Optional[Tuple[str, ...]]: + cls, raw_value: Iterable[str] | None, address: Address + ) -> tuple[str, ...] | None: value_or_default = super().compute_value(raw_value, address) if value_or_default and cls.valid_choices is not None: _validate_choices(address, cls.alias, value_or_default, valid_choices=cls.valid_choices) @@ -2023,13 +2012,13 @@ def compute_value( class DictStringToStringField(Field): - value: Optional[FrozenDict[str, str]] - default: ClassVar[Optional[FrozenDict[str, str]]] = None + value: FrozenDict[str, str] | None + default: ClassVar[FrozenDict[str, str] | None] = None @classmethod def compute_value( - cls, raw_value: Optional[Dict[str, str]], address: Address - ) -> Optional[FrozenDict[str, str]]: + cls, raw_value: dict[str, str] | None, address: Address + ) -> FrozenDict[str, str] | None: value_or_default = super().compute_value(raw_value, address) if value_or_default is None: return None @@ -2044,13 +2033,13 @@ def compute_value( class ListOfDictStringToStringField(Field): - value: Optional[Tuple[FrozenDict[str, str]]] - default: ClassVar[Optional[list[FrozenDict[str, str]]]] = None + value: tuple[FrozenDict[str, str]] | None + default: ClassVar[list[FrozenDict[str, str]] | None] = None @classmethod def compute_value( - cls, raw_value: Optional[list[Dict[str, str]]], address: Address - ) -> Optional[Tuple[FrozenDict[str, str], ...]]: + cls, raw_value: list[dict[str, str]] | None, address: Address + ) -> tuple[FrozenDict[str, str], ...] | None: value_or_default = super().compute_value(raw_value, address) if value_or_default is None: return None @@ -2077,13 +2066,13 @@ def compute_value( class NestedDictStringToStringField(Field): - value: Optional[FrozenDict[str, FrozenDict[str, str]]] - default: ClassVar[Optional[FrozenDict[str, FrozenDict[str, str]]]] = None + value: FrozenDict[str, FrozenDict[str, str]] | None + default: ClassVar[FrozenDict[str, FrozenDict[str, str]] | None] = None @classmethod def compute_value( - cls, raw_value: Optional[Dict[str, Dict[str, str]]], address: Address - ) -> Optional[FrozenDict[str, FrozenDict[str, str]]]: + cls, raw_value: dict[str, dict[str, str]] | None, address: Address + ) -> FrozenDict[str, FrozenDict[str, str]] | None: value_or_default = super().compute_value(raw_value, address) if value_or_default is None: return None @@ -2106,13 +2095,13 @@ def compute_value( class DictStringToStringSequenceField(Field): - value: Optional[FrozenDict[str, Tuple[str, ...]]] - default: ClassVar[Optional[FrozenDict[str, Tuple[str, ...]]]] = None + value: FrozenDict[str, tuple[str, ...]] | None + default: ClassVar[FrozenDict[str, tuple[str, ...]] | None] = None @classmethod def compute_value( - cls, raw_value: Optional[Dict[str, Iterable[str]]], address: Address - ) -> Optional[FrozenDict[str, Tuple[str, ...]]]: + cls, raw_value: dict[str, Iterable[str]] | None, address: Address + ) -> FrozenDict[str, tuple[str, ...]] | None: value_or_default = super().compute_value(raw_value, address) if value_or_default is None: return None @@ -2140,7 +2129,7 @@ def _validate_choices( field_alias: str, values: Iterable[Any], *, - valid_choices: Union[Type[Enum], Tuple[Any, ...]], + valid_choices: type[Enum] | tuple[Any, ...], ) -> None: _valid_choices = set( valid_choices @@ -2363,8 +2352,8 @@ def globs(self) -> tuple[str, ...]: @classmethod def compute_value( - cls, raw_value: Optional[Iterable[str]], address: Address - ) -> Optional[Tuple[str, ...]]: + cls, raw_value: Iterable[str] | None, address: Address + ) -> tuple[str, ...] | None: value = super().compute_value(raw_value, address) invalid_globs = [glob for glob in (value or ()) if glob.startswith("../") or "/../" in glob] if invalid_globs: @@ -2417,7 +2406,7 @@ class OptionalSingleSourceField(SourcesField, StringField): expected_num_files: ClassVar[int | range] = range(0, 2) @classmethod - def compute_value(cls, raw_value: Optional[str], address: Address) -> Optional[str]: + def compute_value(cls, raw_value: str | None, address: Address) -> str | None: value_or_default = super().compute_value(raw_value, address) if value_or_default is None: return None @@ -2868,7 +2857,7 @@ def rules(): ] """ - infer_from: ClassVar[Type[FS]] # type: ignore[misc] + infer_from: ClassVar[type[FS]] # type: ignore[misc] field_set: FS @@ -2900,7 +2889,7 @@ class TransitivelyExcludeDependenciesRequest(Generic[FS], EngineAwareParameter): This mirrors the public facing "transitive exclude" dependency feature (i.e. `!!
`). """ - infer_from: ClassVar[Type[FS]] # type: ignore[misc] + infer_from: ClassVar[type[FS]] # type: ignore[misc] field_set: FS @@ -2917,7 +2906,7 @@ class ValidateDependenciesRequest(Generic[FS], ABC): An implementing rule should raise an exception if dependencies are invalid. """ - field_set_type: ClassVar[Type[FS]] # type: ignore[misc] + field_set_type: ClassVar[type[FS]] # type: ignore[misc] field_set: FS dependencies: Addresses @@ -3051,9 +3040,9 @@ class OverridesField(AsyncFieldMixin, Field): @classmethod def compute_value( cls, - raw_value: Optional[Dict[Union[str, Tuple[str, ...]], Dict[str, Any]]], + raw_value: dict[str | tuple[str, ...], dict[str, Any]] | None, address: Address, - ) -> Optional[FrozenDict[Tuple[str, ...], FrozenDict[str, ImmutableValue]]]: + ) -> FrozenDict[tuple[str, ...], FrozenDict[str, ImmutableValue]] | None: value_or_default = super().compute_value(raw_value, address) if value_or_default is None: return None diff --git a/src/python/pants/engine/target_test.py b/src/python/pants/engine/target_test.py index f443c826cbf..73f20bba942 100644 --- a/src/python/pants/engine/target_test.py +++ b/src/python/pants/engine/target_test.py @@ -4,9 +4,10 @@ import re import string from collections import namedtuple +from collections.abc import Iterable, Sequence from dataclasses import FrozenInstanceError, dataclass from enum import Enum -from typing import Any, ClassVar, Dict, Iterable, List, Optional, Sequence, Set, Tuple, cast +from typing import Any, ClassVar, cast import pytest @@ -66,11 +67,11 @@ class FortranExtensions(Field): alias = "fortran_extensions" - value: Tuple[str, ...] + value: tuple[str, ...] default = () @classmethod - def compute_value(cls, raw_value: Optional[Iterable[str]], address: Address) -> Tuple[str, ...]: + def compute_value(cls, raw_value: Iterable[str] | None, address: Address) -> tuple[str, ...]: value_or_default = super().compute_value(raw_value, address) # Add some arbitrary validation to test that hydration/validation works properly. bad_extensions = [ @@ -340,8 +341,8 @@ class CustomFortranExtensions(FortranExtensions): @classmethod def compute_value( - cls, raw_value: Optional[Iterable[str]], address: Address - ) -> Tuple[str, ...]: + cls, raw_value: Iterable[str] | None, address: Address + ) -> tuple[str, ...]: # Ensure that we avoid certain problematic extensions and always use some defaults. specified_extensions = super().compute_value(raw_value, address) banned = [ @@ -484,7 +485,7 @@ def test_target_residence_dir() -> None: def test_coarsened_target_equality() -> None: a, b = (FortranTarget({}, Address(name)) for name in string.ascii_lowercase[:2]) - def ct(members: List[Target], dependencies: List[CoarsenedTarget] = []): + def ct(members: list[Target], dependencies: list[CoarsenedTarget] = []): return CoarsenedTarget(members, dependencies) assert ct([]) == ct([]) @@ -509,7 +510,7 @@ def test_coarsened_target_closure() -> None: all_targets = [FortranTarget({}, Address(name)) for name in string.ascii_lowercase[:5]] a, b, c, d, e = all_targets - def ct(members: List[Target], dependencies: List[CoarsenedTarget] = []) -> CoarsenedTarget: + def ct(members: list[Target], dependencies: list[CoarsenedTarget] = []) -> CoarsenedTarget: return CoarsenedTarget(members, dependencies) def assert_closure(cts: Sequence[CoarsenedTarget], expected: Sequence[Target]) -> None: @@ -698,8 +699,8 @@ class Example(ScalarField): @classmethod def compute_value( - cls, raw_value: Optional[CustomObject], address: Address - ) -> Optional[CustomObject]: + cls, raw_value: CustomObject | None, address: Address + ) -> CustomObject | None: return super().compute_value(raw_value, address) addr = Address("", target_name="example") @@ -786,8 +787,8 @@ class Example(SequenceField): @classmethod def compute_value( - cls, raw_value: Optional[Iterable[CustomObject]], address: Address - ) -> Optional[Tuple[CustomObject, ...]]: + cls, raw_value: Iterable[CustomObject] | None, address: Address + ) -> tuple[CustomObject, ...] | None: return super().compute_value(raw_value, address) addr = Address("", target_name="example") @@ -968,7 +969,7 @@ class Example(DictStringToStringSequenceField): addr = Address("", target_name="example") - def assert_flexible_constructor(raw_value: Dict[str, Iterable[str]]) -> None: + def assert_flexible_constructor(raw_value: dict[str, Iterable[str]]) -> None: assert Example(raw_value, addr).value == FrozenDict( {k: tuple(v) for k, v in raw_value.items()} ) @@ -1256,7 +1257,7 @@ def test_explicitly_provided_dependencies_remaining_after_disambiguation() -> No ignores=FrozenOrderedSet([addr, generated_addr]), ) - def assert_disambiguated_via_ignores(ambiguous: List[Address], expected: Set[Address]) -> None: + def assert_disambiguated_via_ignores(ambiguous: list[Address], expected: set[Address]) -> None: assert ( epd.remaining_after_disambiguation(tuple(ambiguous), owners_must_be_ancestors=False) == expected @@ -1301,12 +1302,12 @@ def assert_disambiguated_via_ignores(ambiguous: List[Address], expected: Set[Add def test_explicitly_provided_dependencies_disambiguated() -> None: def get_disambiguated( - ambiguous: List[Address], + ambiguous: list[Address], *, - ignores: Optional[List[Address]] = None, - includes: Optional[List[Address]] = None, + ignores: list[Address] | None = None, + includes: list[Address] | None = None, owners_must_be_ancestors: bool = False, - ) -> Optional[Address]: + ) -> Address | None: epd = ExplicitlyProvidedDependencies( address=Address("dir", target_name="input_tgt"), includes=FrozenOrderedSet(includes or []), @@ -1361,10 +1362,10 @@ def test_explicitly_provided_dependencies_maybe_warn_of_ambiguous_dependency_inf caplog, ) -> None: def maybe_warn( - ambiguous: List[Address], + ambiguous: list[Address], *, - ignores: Optional[List[Address]] = None, - includes: Optional[List[Address]] = None, + ignores: list[Address] | None = None, + includes: list[Address] | None = None, owners_must_be_ancestors: bool = False, ) -> None: caplog.clear() @@ -1491,7 +1492,7 @@ def test_overrides_field_normalization() -> None: assert OverridesField.flatten_paths( addr, [ - (paths, globs, cast(Dict[str, Any], overrides)) + (paths, globs, cast(dict[str, Any], overrides)) for (paths, overrides), globs in zip( [ (Paths(("dir/foo.ext",), ()), tgt1_override), diff --git a/src/python/pants/engine/unions.py b/src/python/pants/engine/unions.py index 695588ccee5..793fbec93cd 100644 --- a/src/python/pants/engine/unions.py +++ b/src/python/pants/engine/unions.py @@ -4,8 +4,9 @@ from __future__ import annotations from collections import defaultdict +from collections.abc import Callable, Iterable, Mapping from dataclasses import dataclass -from typing import Any, Callable, DefaultDict, Generic, Iterable, Mapping, TypeVar, cast, overload +from typing import Any, DefaultDict, Generic, TypeVar, cast, overload from pants.util.frozendict import FrozenDict from pants.util.memo import memoized_method diff --git a/src/python/pants/goal/migrate_call_by_name.py b/src/python/pants/goal/migrate_call_by_name.py index 48ed3623039..f1938688429 100644 --- a/src/python/pants/goal/migrate_call_by_name.py +++ b/src/python/pants/goal/migrate_call_by_name.py @@ -6,10 +6,11 @@ import importlib.util import json import logging +from collections.abc import Callable, Iterable from dataclasses import dataclass from functools import partial from pathlib import Path, PurePath -from typing import Callable, Iterable, TypedDict +from typing import TypedDict import libcst as cst import libcst.helpers as h diff --git a/src/python/pants/goal/migrate_call_by_name_test.py b/src/python/pants/goal/migrate_call_by_name_test.py index 3187701d2fe..bbee3874d8c 100644 --- a/src/python/pants/goal/migrate_call_by_name_test.py +++ b/src/python/pants/goal/migrate_call_by_name_test.py @@ -3,9 +3,10 @@ from __future__ import annotations +from collections.abc import Iterable from copy import deepcopy from pathlib import PurePath -from typing import Final, Iterable +from typing import Final import libcst as cst import pytest diff --git a/src/python/pants/goal/stats_aggregator.py b/src/python/pants/goal/stats_aggregator.py index 618a51c5694..5633f547b96 100644 --- a/src/python/pants/goal/stats_aggregator.py +++ b/src/python/pants/goal/stats_aggregator.py @@ -11,7 +11,7 @@ from dataclasses import dataclass from enum import Enum from pathlib import Path -from typing import Optional, TypedDict +from typing import TypedDict from pants.engine.internals.scheduler import Workunit from pants.engine.rules import collect_rules, rule @@ -114,7 +114,7 @@ class StatsAggregatorSubsystem(Subsystem): ) -def _log_or_write_to_file_plain(output_file: Optional[str], lines: list[str]) -> None: +def _log_or_write_to_file_plain(output_file: str | None, lines: list[str]) -> None: """Send text to the stdout or write to the output file (plain text).""" if lines: text = "\n".join(lines) @@ -126,7 +126,7 @@ def _log_or_write_to_file_plain(output_file: Optional[str], lines: list[str]) -> logger.info(text) -def _log_or_write_to_file_json(output_file: Optional[str], stats_object: StatsObject) -> None: +def _log_or_write_to_file_json(output_file: str | None, stats_object: StatsObject) -> None: """Send JSON Lines single line object to the stdout or write to the file.""" if not stats_object: return @@ -147,7 +147,7 @@ def __init__( *, log: bool, memory: bool, - output_file: Optional[str], + output_file: str | None, has_histogram_module: bool, format: StatsOutputFormat, ) -> None: diff --git a/src/python/pants/help/help_formatter_test.py b/src/python/pants/help/help_formatter_test.py index be9605a3886..cff83d44e36 100644 --- a/src/python/pants/help/help_formatter_test.py +++ b/src/python/pants/help/help_formatter_test.py @@ -3,7 +3,6 @@ from __future__ import annotations from dataclasses import replace -from typing import Tuple from pants.help.help_formatter import HelpFormatter from pants.help.help_info_extracter import HelpInfoExtracter, OptionHelpInfo @@ -58,7 +57,7 @@ def test_format_help_choices(self) -> None: assert default_line.lstrip() == "default: kiwi" @classmethod - def _get_registrar_and_parser(cls) -> Tuple[OptionRegistrar, NativeOptionParser]: + def _get_registrar_and_parser(cls) -> tuple[OptionRegistrar, NativeOptionParser]: return OptionRegistrar( scope=GlobalOptions.options_scope, ), NativeOptionParser( diff --git a/src/python/pants/help/help_info_extracter.py b/src/python/pants/help/help_info_extracter.py index 83ecc7f1de8..accf9d5d993 100644 --- a/src/python/pants/help/help_info_extracter.py +++ b/src/python/pants/help/help_info_extracter.py @@ -11,25 +11,13 @@ import json import re from collections import defaultdict, namedtuple +from collections.abc import Callable, Iterator, Sequence from dataclasses import dataclass from enum import Enum from functools import reduce from itertools import chain from pathlib import Path -from typing import ( - Any, - Callable, - DefaultDict, - Iterator, - Optional, - Sequence, - Tuple, - Type, - TypeVar, - Union, - cast, - get_type_hints, -) +from typing import Any, DefaultDict, TypeVar, Union, cast, get_type_hints import pkg_resources @@ -146,7 +134,7 @@ class OptionScopeHelpInfo: description: str provider: str is_goal: bool # True iff the scope belongs to a GoalSubsystem. - deprecated_scope: Optional[str] + deprecated_scope: str | None basic: tuple[OptionHelpInfo, ...] advanced: tuple[OptionHelpInfo, ...] deprecated: tuple[OptionHelpInfo, ...] @@ -470,7 +458,7 @@ def asdict(self) -> dict[str, Any]: } -ConsumedScopesMapper = Callable[[str], Tuple[str, ...]] +ConsumedScopesMapper = Callable[[str], tuple[str, ...]] class HelpInfoExtracter: @@ -529,7 +517,7 @@ def load() -> GoalHelpInfo: build_configuration.subsystem_to_providers.get(subsystem_cls), subsystem_cls.__module__, ) - goal_subsystem_cls = cast(Type[GoalSubsystem], subsystem_cls) + goal_subsystem_cls = cast(type[GoalSubsystem], subsystem_cls) return GoalHelpInfo( goal_subsystem_cls.name, scope_info.description, @@ -1008,7 +996,7 @@ def get_option_scope_help_info( native_parser: NativeOptionParser, is_goal: bool, provider: str = "", - deprecated_scope: Optional[str] = None, + deprecated_scope: str | None = None, ) -> OptionScopeHelpInfo: """Returns an OptionScopeHelpInfo for the options parsed by the given parser.""" diff --git a/src/python/pants/help/help_info_extracter_test.py b/src/python/pants/help/help_info_extracter_test.py index b7fde394594..7438588f871 100644 --- a/src/python/pants/help/help_info_extracter_test.py +++ b/src/python/pants/help/help_info_extracter_test.py @@ -1,8 +1,9 @@ # Copyright 2015 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). +from collections.abc import Iterable from enum import Enum -from typing import Any, Iterable, List, Optional, Tuple, Union +from typing import Any, Optional, Union from pants.base.build_environment import get_buildroot from pants.build_graph.build_configuration import BuildConfiguration @@ -134,7 +135,7 @@ def do_test(args, kwargs, expected_default_str): def test_compute_default(): - def do_test(expected_default: Optional[Any], **kwargs): + def do_test(expected_default: Any | None, **kwargs): assert expected_default == HelpInfoExtracter.compute_default(**kwargs) do_test(False, type=bool, default=False) @@ -286,7 +287,7 @@ def rule_info_test(foo: Foo) -> Target: # type: ignore[empty-body] """This rule is for testing info extraction only.""" ... - def fake_consumed_scopes_mapper(scope: str) -> Tuple[str, ...]: + def fake_consumed_scopes_mapper(scope: str) -> tuple[str, ...]: return ("somescope", f"used_by_{scope or 'GLOBAL_SCOPE'}") bc_builder = BuildConfiguration.Builder() @@ -810,6 +811,6 @@ class ExampleCls: f"{__name__}.{test_pretty_print_type_hint.__name__}..{ExampleCls.__name__}" ) assert ( - pretty_print_type_hint(Union[Iterable[List[ExampleCls]], Optional[float], Any]) + pretty_print_type_hint(Union[Iterable[list[ExampleCls]], Optional[float], Any]) == f"Iterable[List[{example_cls_repr}]] | float | None | Any" ) diff --git a/src/python/pants/help/help_printer.py b/src/python/pants/help/help_printer.py index c80c5750bf0..9e6225f9f3f 100644 --- a/src/python/pants/help/help_printer.py +++ b/src/python/pants/help/help_printer.py @@ -6,9 +6,10 @@ import re import textwrap from abc import ABC +from collections.abc import Callable, Iterable from dataclasses import dataclass from itertools import cycle -from typing import Callable, Dict, Iterable, List, Literal, Optional, Set, Tuple, cast +from typing import Literal, cast from pants.base.build_environment import pants_version from pants.help.help_formatter import HelpFormatter @@ -119,7 +120,7 @@ def _print_title(self, title_text: str) -> None: title = self.maybe_green(f"{title_text}\n{'-' * len(title_text)}") print(f"\n{title}\n") - def _print_table(self, table: Dict[str, Optional[str]]) -> None: + def _print_table(self, table: dict[str, str | None]) -> None: longest_key = max(len(key) for key, value in table.items() if value is not None) for key, value in table.items(): if value is None: @@ -133,10 +134,10 @@ def _print_table(self, table: Dict[str, Optional[str]]) -> None: ), ) - def _get_thing_help_table(self) -> Dict[str, Callable[[str, bool], None]]: + def _get_thing_help_table(self) -> dict[str, Callable[[str, bool], None]]: def _help_table( things: Iterable[str], help_printer: Callable[[str, bool], None] - ) -> Dict[str, Callable[[str, bool], None]]: + ) -> dict[str, Callable[[str, bool], None]]: return dict(zip(things, cycle((help_printer,)))) top_level_help_items = _help_table(self._reserved_names, self._print_top_level_help) @@ -159,11 +160,11 @@ def _help_table( @staticmethod def _disambiguate_things( things: Iterable[str], all_things: Iterable[str] - ) -> Tuple[Set[str], Set[str]]: + ) -> tuple[set[str], set[str]]: """Returns two sets of strings, one with disambiguated things and the second with unresolvable things.""" - disambiguated: Set[str] = set() - unknown: Set[str] = set() + disambiguated: set[str] = set() + unknown: set[str] = set() for thing in things: # Look for typos and close matches first. @@ -173,7 +174,7 @@ def _disambiguate_things( continue # For api types and rules, see if we get a match, by ignoring the leading module path. - found_things: List[str] = [] + found_things: list[str] = [] suffix = f".{thing}" for known_thing in all_things: if known_thing.endswith(suffix): @@ -259,7 +260,7 @@ def _print_top_level_help(self, thing: str, show_advanced: bool) -> None: self._print_all_symbols(show_advanced) def _print_all_goals(self) -> None: - goal_descriptions: Dict[str, str] = {} + goal_descriptions: dict[str, str] = {} for goal_info in self._all_help_info.name_to_goal_info.values(): if goal_info.is_implemented: @@ -291,7 +292,7 @@ def format_goal(name: str, descr: str) -> str: def _print_all_subsystems(self) -> None: self._print_title("Subsystems") - subsystem_description: Dict[str, str] = {} + subsystem_description: dict[str, str] = {} for help_info in self._all_help_info.non_deprecated_option_scope_help_infos(): if not help_info.is_goal and help_info.scope: subsystem_description[help_info.scope] = first_paragraph(help_info.description) @@ -340,7 +341,7 @@ def _print_all_tools(self) -> None: def _print_all_api_types(self) -> None: self._print_title("Plugin API Types") - api_type_descriptions: Dict[str, Tuple[str, str]] = {} + api_type_descriptions: dict[str, tuple[str, str]] = {} indent_api_summary = 0 for api_info in self._all_help_info.name_to_api_type_info.values(): name = api_info.name diff --git a/src/python/pants/help/help_tools.py b/src/python/pants/help/help_tools.py index a202b5b32a0..dda03ccc984 100644 --- a/src/python/pants/help/help_tools.py +++ b/src/python/pants/help/help_tools.py @@ -2,11 +2,12 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). from __future__ import annotations +from collections.abc import Generator, Iterable from dataclasses import dataclass from functools import partial from itertools import chain from textwrap import wrap -from typing import Generator, Iterable, cast +from typing import cast from pants.help.help_info_extracter import AllHelpInfo, OptionScopeHelpInfo from pants.help.maybe_color import MaybeColor diff --git a/src/python/pants/help/maybe_color.py b/src/python/pants/help/maybe_color.py index ee96a4287a1..a09132b9532 100644 --- a/src/python/pants/help/maybe_color.py +++ b/src/python/pants/help/maybe_color.py @@ -1,7 +1,6 @@ # Copyright 2020 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). -from typing import List from colors import color as ansicolor from colors import cyan, green, magenta, red, yellow @@ -28,7 +27,7 @@ def noop(x, **_): self.maybe_magenta = magenta if color else noop self.maybe_yellow = yellow if color else noop - def _format_did_you_mean_matches(self, did_you_mean: List[str]) -> str: + def _format_did_you_mean_matches(self, did_you_mean: list[str]) -> str: if len(did_you_mean) == 1: formatted_candidates = self.maybe_cyan(did_you_mean[0]) elif len(did_you_mean) == 2: diff --git a/src/python/pants/init/engine_initializer.py b/src/python/pants/init/engine_initializer.py index b00aaf1f492..e0e945421d8 100644 --- a/src/python/pants/init/engine_initializer.py +++ b/src/python/pants/init/engine_initializer.py @@ -4,9 +4,10 @@ from __future__ import annotations import logging +from collections.abc import Iterable, Mapping from dataclasses import dataclass from pathlib import Path -from typing import Any, ClassVar, Iterable, Mapping, cast +from typing import Any, ClassVar, cast from pants.base.build_environment import get_buildroot from pants.base.build_root import BuildRoot diff --git a/src/python/pants/init/extension_loader.py b/src/python/pants/init/extension_loader.py index 5a71f2028fe..d77692ef799 100644 --- a/src/python/pants/init/extension_loader.py +++ b/src/python/pants/init/extension_loader.py @@ -4,7 +4,6 @@ import importlib import logging import traceback -from typing import Dict, List, Optional from pkg_resources import Requirement, WorkingSet @@ -29,10 +28,10 @@ class PluginLoadOrderError(PluginLoadingError): def load_backends_and_plugins( - plugins: List[str], + plugins: list[str], working_set: WorkingSet, - backends: List[str], - bc_builder: Optional[BuildConfiguration.Builder] = None, + backends: list[str], + bc_builder: BuildConfiguration.Builder | None = None, ) -> BuildConfiguration: """Load named plugins and source backends. @@ -50,7 +49,7 @@ def load_backends_and_plugins( def load_plugins( build_configuration: BuildConfiguration.Builder, - plugins: List[str], + plugins: list[str], working_set: WorkingSet, ) -> None: """Load named plugins from the current working_set into the supplied build_configuration. @@ -76,7 +75,7 @@ def load_plugins( eg ['widgetpublish', 'widgetgen==1.2']. :param working_set: A pkg_resources.WorkingSet to load plugins from. """ - loaded: Dict = {} + loaded: dict = {} for plugin in plugins or []: req = Requirement.parse(plugin) dist = working_set.find(req) @@ -115,7 +114,7 @@ def load_plugins( def load_build_configuration_from_source( - build_configuration: BuildConfiguration.Builder, backends: List[str] + build_configuration: BuildConfiguration.Builder, backends: list[str] ) -> None: """Installs pants backend packages to provide BUILD file symbols and cli goals. diff --git a/src/python/pants/init/load_backends_integration_test.py b/src/python/pants/init/load_backends_integration_test.py index ff7dcbb4a69..316aed3472a 100644 --- a/src/python/pants/init/load_backends_integration_test.py +++ b/src/python/pants/init/load_backends_integration_test.py @@ -2,14 +2,13 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). from pathlib import Path -from typing import List import pytest from pants.testutil.pants_integration_test import run_pants -def discover_backends() -> List[str]: +def discover_backends() -> list[str]: register_pys = Path().glob("src/python/**/register.py") backends = { str(register_py.parent).replace("src/python/", "").replace("/", ".") @@ -20,7 +19,7 @@ def discover_backends() -> List[str]: return sorted(backends - always_activated) -def assert_backends_load(backends: List[str]) -> None: +def assert_backends_load(backends: list[str]) -> None: run_pants( ["--no-verify-config", "help-all"], config={"GLOBAL": {"backend_packages": backends}} ).assert_success(f"Failed to load: {backends}") diff --git a/src/python/pants/init/logging.py b/src/python/pants/init/logging.py index 50dcc5777fc..ab535ad4315 100644 --- a/src/python/pants/init/logging.py +++ b/src/python/pants/init/logging.py @@ -7,11 +7,11 @@ import locale import logging import sys +from collections.abc import Iterator from contextlib import contextmanager from io import BufferedReader, TextIOWrapper from logging import Formatter, Handler, LogRecord from pathlib import PurePath -from typing import Iterator import pants.util.logging as pants_logging from pants.engine.internals import native_engine diff --git a/src/python/pants/init/options_initializer.py b/src/python/pants/init/options_initializer.py index 3276c1b0014..71c45468c78 100644 --- a/src/python/pants/init/options_initializer.py +++ b/src/python/pants/init/options_initializer.py @@ -7,9 +7,9 @@ import importlib import logging import sys +from collections.abc import Iterator from contextlib import contextmanager from pathlib import Path -from typing import Iterator, List import pkg_resources @@ -66,7 +66,7 @@ def _initialize_build_configuration( ) -def _collect_backends_requirements(backends: List[str]) -> List[str]: +def _collect_backends_requirements(backends: list[str]) -> list[str]: """Collects backend package dependencies, in case those are declared in an adjacent requirements.txt. Ignores any loading errors, assuming those will be later on handled by the backends loader. diff --git a/src/python/pants/init/plugin_resolver.py b/src/python/pants/init/plugin_resolver.py index db0e61d206c..8476b4ec532 100644 --- a/src/python/pants/init/plugin_resolver.py +++ b/src/python/pants/init/plugin_resolver.py @@ -6,8 +6,9 @@ import logging import site import sys +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable, Optional, cast +from typing import cast from pkg_resources import Requirement, WorkingSet from pkg_resources import working_set as global_working_set @@ -118,8 +119,8 @@ class PluginResolver: def __init__( self, scheduler: BootstrapScheduler, - interpreter_constraints: Optional[InterpreterConstraints] = None, - working_set: Optional[WorkingSet] = None, + interpreter_constraints: InterpreterConstraints | None = None, + working_set: WorkingSet | None = None, ) -> None: self._scheduler = scheduler self._working_set = working_set or global_working_set diff --git a/src/python/pants/jvm/classpath.py b/src/python/pants/jvm/classpath.py index d7c8f08921e..58b6d993b1b 100644 --- a/src/python/pants/jvm/classpath.py +++ b/src/python/pants/jvm/classpath.py @@ -4,8 +4,8 @@ from __future__ import annotations import logging +from collections.abc import Iterator from dataclasses import dataclass -from typing import Iterator from pants.core.util_rules import system_binaries from pants.core.util_rules.system_binaries import UnzipBinary diff --git a/src/python/pants/jvm/compile.py b/src/python/pants/jvm/compile.py index 9920fd8488c..3cba5dcc52f 100644 --- a/src/python/pants/jvm/compile.py +++ b/src/python/pants/jvm/compile.py @@ -7,9 +7,10 @@ import os from abc import ABCMeta from collections import defaultdict, deque +from collections.abc import Iterable, Iterator, Sequence from dataclasses import dataclass from enum import Enum, auto -from typing import ClassVar, Iterable, Iterator, Sequence +from typing import ClassVar from pants.core.target_types import ( FilesGeneratingSourcesField, diff --git a/src/python/pants/jvm/compile_test.py b/src/python/pants/jvm/compile_test.py index 9645fe255b9..7faa36f8797 100644 --- a/src/python/pants/jvm/compile_test.py +++ b/src/python/pants/jvm/compile_test.py @@ -11,8 +11,9 @@ from __future__ import annotations +from collections.abc import Sequence from textwrap import dedent -from typing import Sequence, Type, cast +from typing import cast import chevron import pytest @@ -262,7 +263,7 @@ def classify( all_members = [CompileJavaSourceRequest, CompileScalaSourceRequest, CoursierFetchRequest] generators = FrozenDict( { - CompileJavaSourceRequest: frozenset([cast(Type[SourcesField], ProtobufSourceField)]), + CompileJavaSourceRequest: frozenset([cast(type[SourcesField], ProtobufSourceField)]), CompileScalaSourceRequest: frozenset(), } ) diff --git a/src/python/pants/jvm/dependency_inference/artifact_mapper.py b/src/python/pants/jvm/dependency_inference/artifact_mapper.py index 68e3a0acb85..69ec5c17c0b 100644 --- a/src/python/pants/jvm/dependency_inference/artifact_mapper.py +++ b/src/python/pants/jvm/dependency_inference/artifact_mapper.py @@ -3,8 +3,9 @@ from __future__ import annotations from collections import defaultdict +from collections.abc import Iterable, Iterator from dataclasses import dataclass -from typing import Any, DefaultDict, Iterable, Iterator, Tuple +from typing import Any, DefaultDict from pants.backend.java.subsystems.java_infer import JavaInferSubsystem from pants.build_graph.address import Address @@ -44,7 +45,7 @@ def from_coord_str(cls, coord: str) -> UnversionedCoordinate: class AvailableThirdPartyArtifacts( FrozenDict[ - Tuple[_ResolveName, UnversionedCoordinate], Tuple[Tuple[Address, ...], Tuple[str, ...]] + tuple[_ResolveName, UnversionedCoordinate], tuple[tuple[Address, ...], tuple[str, ...]] ] ): """Maps coordinates and resolve names to target `Address`es and declared packages.""" @@ -104,7 +105,7 @@ def frozen(self) -> FrozenTrieNode: return FrozenTrieNode(self) -FrozenTrieNodeItem = Tuple[str, bool, FrozenDict[SymbolNamespace, FrozenOrderedSet[Address]], bool] +FrozenTrieNodeItem = tuple[str, bool, FrozenDict[SymbolNamespace, FrozenOrderedSet[Address]], bool] @dataclass(frozen=True) diff --git a/src/python/pants/jvm/goals/lockfile.py b/src/python/pants/jvm/goals/lockfile.py index 4b44e01d3c5..905ca923198 100644 --- a/src/python/pants/jvm/goals/lockfile.py +++ b/src/python/pants/jvm/goals/lockfile.py @@ -4,8 +4,8 @@ from __future__ import annotations from collections import defaultdict +from collections.abc import Mapping from dataclasses import dataclass -from typing import Mapping from pants.core.goals.generate_lockfiles import ( DEFAULT_TOOL_LOCKFILE, diff --git a/src/python/pants/jvm/jar_tool/jar_tool.py b/src/python/pants/jvm/jar_tool/jar_tool.py index 0f351b7f187..25e190733e1 100644 --- a/src/python/pants/jvm/jar_tool/jar_tool.py +++ b/src/python/pants/jvm/jar_tool/jar_tool.py @@ -4,9 +4,9 @@ from __future__ import annotations import os +from collections.abc import Iterable, Mapping from dataclasses import dataclass from enum import Enum, unique -from typing import Iterable, Mapping import pkg_resources diff --git a/src/python/pants/jvm/jdk_rules.py b/src/python/pants/jvm/jdk_rules.py index 3d4619b9ff4..3ee945df09f 100644 --- a/src/python/pants/jvm/jdk_rules.py +++ b/src/python/pants/jvm/jdk_rules.py @@ -9,9 +9,10 @@ import re import shlex import textwrap +from collections.abc import Iterable, Mapping from dataclasses import dataclass from enum import Enum -from typing import ClassVar, Iterable, Mapping +from typing import ClassVar from pants.core.util_rules.environments import EnvironmentTarget from pants.core.util_rules.system_binaries import BashBinary, LnBinary diff --git a/src/python/pants/jvm/package/deploy_jar_test.py b/src/python/pants/jvm/package/deploy_jar_test.py index 00f539e5086..53503baabe5 100644 --- a/src/python/pants/jvm/package/deploy_jar_test.py +++ b/src/python/pants/jvm/package/deploy_jar_test.py @@ -3,8 +3,8 @@ from __future__ import annotations +from collections.abc import Iterable from textwrap import dedent -from typing import Iterable import pytest diff --git a/src/python/pants/jvm/package/war.py b/src/python/pants/jvm/package/war.py index 31c96a849f1..dd477288f99 100644 --- a/src/python/pants/jvm/package/war.py +++ b/src/python/pants/jvm/package/war.py @@ -5,9 +5,9 @@ import logging import textwrap +from collections.abc import Iterable from dataclasses import dataclass from pathlib import PurePath -from typing import Iterable from pants.build_graph.address import Address from pants.core.goals.package import ( diff --git a/src/python/pants/jvm/resolve/common.py b/src/python/pants/jvm/resolve/common.py index aa818114b15..8d98c19bad2 100644 --- a/src/python/pants/jvm/resolve/common.py +++ b/src/python/pants/jvm/resolve/common.py @@ -4,8 +4,8 @@ from __future__ import annotations import dataclasses +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from urllib.parse import quote_plus as url_quote_plus from pants.engine.collection import DeduplicatedCollection diff --git a/src/python/pants/jvm/resolve/coursier_fetch.py b/src/python/pants/jvm/resolve/coursier_fetch.py index 5fabfe80f9a..3f0fbbe9aae 100644 --- a/src/python/pants/jvm/resolve/coursier_fetch.py +++ b/src/python/pants/jvm/resolve/coursier_fetch.py @@ -10,9 +10,10 @@ import logging import os from collections import defaultdict +from collections.abc import Iterable, Iterator from dataclasses import dataclass from itertools import chain -from typing import TYPE_CHECKING, Any, Iterable, Iterator, List, Tuple +from typing import TYPE_CHECKING, Any import toml @@ -329,9 +330,9 @@ async def prepare_coursier_resolve_info( ) -> CoursierResolveInfo: # Transform requirements that correspond to local JAR files into coordinates with `file:/` # URLs, and put the files in the place specified by the URLs. - no_jars: List[ArtifactRequirement] = [] - jars: List[Tuple[ArtifactRequirement, JvmArtifactJarSourceField]] = [] - extra_args: List[str] = [] + no_jars: list[ArtifactRequirement] = [] + jars: list[tuple[ArtifactRequirement, JvmArtifactJarSourceField]] = [] + extra_args: list[str] = [] LOCAL_EXCLUDE_FILE = "PANTS_RESOLVE_EXCLUDES" diff --git a/src/python/pants/jvm/resolve/coursier_fetch_filter_test.py b/src/python/pants/jvm/resolve/coursier_fetch_filter_test.py index a2091fd3f63..d9b62f6d563 100644 --- a/src/python/pants/jvm/resolve/coursier_fetch_filter_test.py +++ b/src/python/pants/jvm/resolve/coursier_fetch_filter_test.py @@ -3,7 +3,8 @@ from __future__ import annotations -from typing import DefaultDict, Sequence +from collections.abc import Sequence +from typing import DefaultDict from unittest import mock import pytest diff --git a/src/python/pants/jvm/resolve/coursier_setup.py b/src/python/pants/jvm/resolve/coursier_setup.py index 58275777523..c656b07d9bb 100644 --- a/src/python/pants/jvm/resolve/coursier_setup.py +++ b/src/python/pants/jvm/resolve/coursier_setup.py @@ -6,9 +6,10 @@ import os import shlex import textwrap +from collections.abc import Iterable from dataclasses import dataclass from hashlib import sha256 -from typing import ClassVar, Iterable, Tuple +from typing import ClassVar from pants.core.goals.resolves import ExportableTool from pants.core.util_rules import external_tool @@ -239,10 +240,10 @@ def immutable_input_digests(self) -> dict[str, Digest]: @dataclass(frozen=True) class CoursierFetchProcess: - args: Tuple[str, ...] + args: tuple[str, ...] input_digest: Digest - output_directories: Tuple[str, ...] - output_files: Tuple[str, ...] + output_directories: tuple[str, ...] + output_files: tuple[str, ...] description: str diff --git a/src/python/pants/jvm/resolve/lockfile_metadata.py b/src/python/pants/jvm/resolve/lockfile_metadata.py index 4e812f62ade..2cea0fd1ffd 100644 --- a/src/python/pants/jvm/resolve/lockfile_metadata.py +++ b/src/python/pants/jvm/resolve/lockfile_metadata.py @@ -3,9 +3,10 @@ from __future__ import annotations +from collections.abc import Iterable from dataclasses import dataclass from enum import Enum -from typing import Any, Iterable, cast +from typing import Any, cast from pants.core.util_rules.lockfile_metadata import ( LockfileMetadata, diff --git a/src/python/pants/jvm/run.py b/src/python/pants/jvm/run.py index 0de6f656a69..bbe384c87d6 100644 --- a/src/python/pants/jvm/run.py +++ b/src/python/pants/jvm/run.py @@ -5,7 +5,7 @@ import logging import re -from typing import Iterable, Optional, Tuple +from collections.abc import Iterable from pants.core.goals.run import RunRequest from pants.core.util_rules.system_binaries import UnzipBinary @@ -50,7 +50,7 @@ async def _find_main( async def _find_main_by_manifest( unzip: UnzipBinary, input_digest: Digest, jarfile: str -) -> Optional[str]: +) -> str | None: # jvm only allows `-cp` or `-jar` to be specified, and `-jar` takes precedence. So, even for a # JAR with a valid `Main-Class` in the manifest, we need to peek inside the manifest and # extract `main` ourself. @@ -84,7 +84,7 @@ async def _find_main_by_manifest( async def _find_main_by_javap( unzip: UnzipBinary, jdk: JdkEnvironment, input_digest: Digest, jarfile: str -) -> Tuple[str, ...]: +) -> tuple[str, ...]: # Finds the `main` class by inspecting all of the classes inside the specified JAR # to find one with a JVM main method. diff --git a/src/python/pants/jvm/shading/rules.py b/src/python/pants/jvm/shading/rules.py index 7ec62dfeff4..02866d30302 100644 --- a/src/python/pants/jvm/shading/rules.py +++ b/src/python/pants/jvm/shading/rules.py @@ -5,9 +5,9 @@ import logging import os +from collections.abc import Iterable from dataclasses import dataclass from pathlib import PurePath -from typing import Iterable from pants.engine.engine_aware import EngineAwareParameter from pants.engine.fs import ( diff --git a/src/python/pants/jvm/strip_jar/strip_jar.py b/src/python/pants/jvm/strip_jar/strip_jar.py index d6435e86d70..07b49fe8952 100644 --- a/src/python/pants/jvm/strip_jar/strip_jar.py +++ b/src/python/pants/jvm/strip_jar/strip_jar.py @@ -2,7 +2,6 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). from dataclasses import dataclass -from typing import Tuple import pkg_resources @@ -33,7 +32,7 @@ class StripJarTool(JvmToolBase): @dataclass(frozen=True) class StripJarRequest: digest: Digest - filenames: Tuple[str, ...] + filenames: tuple[str, ...] @dataclass(frozen=True) diff --git a/src/python/pants/jvm/target_types.py b/src/python/pants/jvm/target_types.py index c696eacbf65..21c7cb9533b 100644 --- a/src/python/pants/jvm/target_types.py +++ b/src/python/pants/jvm/target_types.py @@ -7,8 +7,9 @@ import re import xml.etree.ElementTree as ET from abc import ABC, ABCMeta, abstractmethod +from collections.abc import Callable, Iterable, Iterator from dataclasses import dataclass -from typing import Callable, ClassVar, Iterable, Iterator, Optional, Tuple, Type, Union +from typing import ClassVar from pants.build_graph.build_file_aliases import BuildFileAliases from pants.core.goals.generate_lockfiles import UnrecognizedResolveNamesError @@ -130,7 +131,7 @@ class JvmRunnableSourceFieldSet(RunFieldSet): main_class: JvmMainClassNameField @classmethod - def jvm_rules(cls) -> Iterable[Union[Rule, UnionRule]]: + def jvm_rules(cls) -> Iterable[Rule | UnionRule]: yield from _jvm_source_run_request_rule(cls) yield from cls.rules() @@ -222,7 +223,7 @@ class JvmArtifactJarSourceField(OptionalSingleSourceField): ) @classmethod - def compute_value(cls, raw_value: Optional[str], address: Address) -> Optional[str]: + def compute_value(cls, raw_value: str | None, address: Address) -> str | None: value_or_default = super().compute_value(raw_value, address) if value_or_default and value_or_default.startswith("file:"): raise InvalidFieldException( @@ -346,8 +347,8 @@ class JvmArtifactExclusionsField(SequenceField[JvmArtifactExclusion]): @classmethod def compute_value( - cls, raw_value: Optional[Iterable[JvmArtifactExclusion]], address: Address - ) -> Optional[Tuple[JvmArtifactExclusion, ...]]: + cls, raw_value: Iterable[JvmArtifactExclusion] | None, address: Address + ) -> tuple[JvmArtifactExclusion, ...] | None: computed_value = super().compute_value(raw_value, address) if computed_value: @@ -462,7 +463,7 @@ class JvmArtifactsPackageMappingField(DictStringToStringSequenceField): """ ) value: FrozenDict[str, tuple[str, ...]] - default: ClassVar[Optional[FrozenDict[str, tuple[str, ...]]]] = FrozenDict() + default: ClassVar[FrozenDict[str, tuple[str, ...]] | None] = FrozenDict() @classmethod def compute_value( # type: ignore[override] @@ -722,7 +723,7 @@ def validate(self) -> set[str]: return JvmShadingRule._validate_field(self.pattern, name="pattern", invalid_chars="/") -JVM_SHADING_RULE_TYPES: list[Type[JvmShadingRule]] = [ +JVM_SHADING_RULE_TYPES: list[type[JvmShadingRule]] = [ JvmShadingRelocateRule, JvmShadingRenameRule, JvmShadingZapRule, @@ -770,8 +771,8 @@ class JvmShadingRulesField(SequenceField[JvmShadingRule], metaclass=ABCMeta): @classmethod def compute_value( - cls, raw_value: Optional[Iterable[JvmShadingRule]], address: Address - ) -> Optional[Tuple[JvmShadingRule, ...]]: + cls, raw_value: Iterable[JvmShadingRule] | None, address: Address + ) -> tuple[JvmShadingRule, ...] | None: computed_value = super().compute_value(raw_value, address) if computed_value: @@ -856,8 +857,8 @@ class DeployJarDuplicatePolicyField(SequenceField[DeployJarDuplicateRule]): @classmethod def compute_value( - cls, raw_value: Optional[Iterable[DeployJarDuplicateRule]], address: Address - ) -> Optional[Tuple[DeployJarDuplicateRule, ...]]: + cls, raw_value: Iterable[DeployJarDuplicateRule] | None, address: Address + ) -> tuple[DeployJarDuplicateRule, ...] | None: value = super().compute_value(raw_value, address) if value: errors = [] diff --git a/src/python/pants/jvm/test/junit_test.py b/src/python/pants/jvm/test/junit_test.py index 458313112d0..e862873e24c 100644 --- a/src/python/pants/jvm/test/junit_test.py +++ b/src/python/pants/jvm/test/junit_test.py @@ -4,8 +4,8 @@ from __future__ import annotations import re +from collections.abc import Iterable from textwrap import dedent -from typing import Iterable import pytest diff --git a/src/python/pants/jvm/test/testutil.py b/src/python/pants/jvm/test/testutil.py index 57fdaa6d9d5..a07f0b721ab 100644 --- a/src/python/pants/jvm/test/testutil.py +++ b/src/python/pants/jvm/test/testutil.py @@ -2,7 +2,7 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). from __future__ import annotations -from typing import Iterable, Mapping +from collections.abc import Iterable, Mapping from pants.core.goals.test import TestResult from pants.engine.internals.native_engine import Address diff --git a/src/python/pants/option/custom_types.py b/src/python/pants/option/custom_types.py index c3769841d20..610994d12cd 100644 --- a/src/python/pants/option/custom_types.py +++ b/src/python/pants/option/custom_types.py @@ -7,8 +7,9 @@ import os import re import shlex +from collections.abc import Iterable, Sequence from enum import Enum -from typing import Iterable, Pattern, Sequence +from re import Pattern from pants.option.errors import ParseError from pants.util.eval import parse_expression diff --git a/src/python/pants/option/custom_types_test.py b/src/python/pants/option/custom_types_test.py index 6e41a7bde30..a3416a873b5 100644 --- a/src/python/pants/option/custom_types_test.py +++ b/src/python/pants/option/custom_types_test.py @@ -2,7 +2,7 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). from textwrap import dedent -from typing import Dict, List, Union +from typing import Union import pytest @@ -16,8 +16,8 @@ from pants.option.errors import ParseError ValidPrimitives = Union[int, str] -ParsedList = List[ValidPrimitives] -ParsedDict = Dict[str, Union[ValidPrimitives, ParsedList]] +ParsedList = list[ValidPrimitives] +ParsedDict = dict[str, Union[ValidPrimitives, ParsedList]] def test_memory_size() -> None: @@ -70,7 +70,7 @@ def assert_list_parsed(s: str, *, expected: ParsedList) -> None: assert expected == ListValueComponent.create(s).val @staticmethod - def assert_split_list(s: str, *, expected: List[str]) -> None: + def assert_split_list(s: str, *, expected: list[str]) -> None: assert expected == ListValueComponent._split_modifier_expr(s) def test_unset_bool(self): diff --git a/src/python/pants/option/errors.py b/src/python/pants/option/errors.py index f161c0664ce..62cca7b5362 100644 --- a/src/python/pants/option/errors.py +++ b/src/python/pants/option/errors.py @@ -1,7 +1,6 @@ # Copyright 2014 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). -from typing import Tuple from pants.option.scope import GLOBAL_SCOPE from pants.util.strutil import softwrap @@ -112,7 +111,7 @@ class MutuallyExclusiveOptionError(ParseError): class UnknownFlagsError(ParseError): """Indicates that unknown command-line flags were encountered in some scope.""" - def __init__(self, flags: Tuple[str, ...], arg_scope: str): + def __init__(self, flags: tuple[str, ...], arg_scope: str): self.flags = flags self.arg_scope = arg_scope scope = f"scope {self.arg_scope}" if self.arg_scope else "global scope" diff --git a/src/python/pants/option/global_options.py b/src/python/pants/option/global_options.py index 752a398d8b7..98568cc4e1a 100644 --- a/src/python/pants/option/global_options.py +++ b/src/python/pants/option/global_options.py @@ -9,13 +9,12 @@ import re import sys import tempfile +from collections.abc import Callable from dataclasses import dataclass from datetime import datetime, timedelta from enum import Enum from pathlib import Path, PurePath -from typing import Any, Callable, Type, TypeVar, cast - -from typing_extensions import assert_never +from typing import Any, Type, TypeVar, assert_never, cast from pants.base.build_environment import ( get_buildroot, diff --git a/src/python/pants/option/native_options.py b/src/python/pants/option/native_options.py index 50292feb437..0b95cba4b50 100644 --- a/src/python/pants/option/native_options.py +++ b/src/python/pants/option/native_options.py @@ -6,9 +6,10 @@ import inspect import logging import shlex +from collections.abc import Mapping, Sequence from enum import Enum from pathlib import Path -from typing import Any, Mapping, Optional, Sequence, Tuple +from typing import Any from pants.base.build_environment import get_buildroot from pants.engine.fs import FileContent @@ -58,9 +59,9 @@ class NativeOptionParser: def __init__( self, - args: Optional[Sequence[str]], + args: Sequence[str] | None, env: Mapping[str, str], - config_sources: Optional[Sequence[FileContent]], + config_sources: Sequence[FileContent] | None, allow_pantsrc: bool, include_derivation: bool, known_scopes_to_flags: dict[str, frozenset[str]], @@ -126,7 +127,7 @@ def with_derivation(self) -> NativeOptionParser: known_goals=self._known_goals, ) - def get_value(self, *, scope: str, option_info: OptionInfo) -> Tuple[Any, Rank]: + def get_value(self, *, scope: str, option_info: OptionInfo) -> tuple[Any, Rank]: val, rank, _ = self._get_value_and_derivation(scope, option_info) return (val, rank) @@ -134,7 +135,7 @@ def get_derivation( self, scope: str, option_info: OptionInfo, - ) -> list[Tuple[Any, Rank, Optional[str]]]: + ) -> list[tuple[Any, Rank, str | None]]: _, _, derivation = self._get_value_and_derivation(scope, option_info) return derivation @@ -142,7 +143,7 @@ def _get_value_and_derivation( self, scope: str, option_info: OptionInfo, - ) -> Tuple[Any, Rank, list[Tuple[Any, Rank, Optional[str]]]]: + ) -> tuple[Any, Rank, list[tuple[Any, Rank, str | None]]]: return self._get( scope=scope, dest=parse_dest(option_info), @@ -165,7 +166,7 @@ def _get( member_type=None, choices=None, passthrough=False, - ) -> Tuple[Any, Rank, list[Tuple[Any, Rank, Optional[str]]]]: + ) -> tuple[Any, Rank, list[tuple[Any, Rank, str | None]]]: def scope_str() -> str: return "global scope" if scope == GLOBAL_SCOPE else f"scope '{scope}'" diff --git a/src/python/pants/option/option_types.py b/src/python/pants/option/option_types.py index 1a5dbd90446..8326b76928b 100644 --- a/src/python/pants/option/option_types.py +++ b/src/python/pants/option/option_types.py @@ -4,9 +4,10 @@ from __future__ import annotations import inspect +from collections.abc import Callable, Iterator from dataclasses import dataclass from enum import Enum -from typing import Any, Callable, Generic, Iterator, TypeVar, Union, cast, overload +from typing import Any, Generic, TypeVar, Union, cast, overload from pants.option import custom_types from pants.util.docutil import bin_name diff --git a/src/python/pants/option/option_value_container.py b/src/python/pants/option/option_value_container.py index 5af725962ea..b825c0bca1f 100644 --- a/src/python/pants/option/option_value_container.py +++ b/src/python/pants/option/option_value_container.py @@ -4,8 +4,8 @@ from __future__ import annotations import copy +from collections.abc import Iterator from dataclasses import dataclass -from typing import Iterator from pants.option.ranked_value import Rank, RankedValue, Value diff --git a/src/python/pants/option/options.py b/src/python/pants/option/options.py index 6cd00aa4fec..6ab59b6e8e6 100644 --- a/src/python/pants/option/options.py +++ b/src/python/pants/option/options.py @@ -6,8 +6,9 @@ import dataclasses import logging from collections import defaultdict +from collections.abc import Iterable, Mapping, Sequence from enum import Enum -from typing import Any, Iterable, Mapping, Sequence +from typing import Any from pants.base.deprecated import warn_or_error from pants.engine.fs import FileContent diff --git a/src/python/pants/option/options_bootstrapper.py b/src/python/pants/option/options_bootstrapper.py index efa7e936111..e131fc4ed1f 100644 --- a/src/python/pants/option/options_bootstrapper.py +++ b/src/python/pants/option/options_bootstrapper.py @@ -3,8 +3,9 @@ from __future__ import annotations +from collections.abc import Iterable, Mapping, Sequence from dataclasses import dataclass -from typing import TYPE_CHECKING, Iterable, Mapping, Sequence +from typing import TYPE_CHECKING from pants.base.build_environment import pants_version from pants.base.exceptions import BuildConfigurationError diff --git a/src/python/pants/option/options_test.py b/src/python/pants/option/options_test.py index 27a5a246020..9a3ab7a4813 100644 --- a/src/python/pants/option/options_test.py +++ b/src/python/pants/option/options_test.py @@ -6,12 +6,13 @@ import json import shlex import unittest.mock +from collections.abc import Callable from contextlib import contextmanager from enum import Enum from functools import partial from pathlib import Path from textwrap import dedent -from typing import Any, Callable, Dict, List, cast +from typing import Any, cast import pytest import toml @@ -449,7 +450,7 @@ def register(opts: Options) -> None: def _create_config( config: dict[str, dict[str, str]] | None = None, config2: dict[str, dict[str, str]] | None = None, -) -> List[FileContent]: +) -> list[FileContent]: return [ FileContent("test_config.toml", toml.dumps(config or {}).encode()), FileContent("test_config2.toml", toml.dumps(config2 or {}).encode()), @@ -1478,7 +1479,7 @@ def test_pants_global_with_default() -> None: # This cast shouldn't be necessary - likely a bug in MyPy. Once this gets fixed, MyPy will # tell us that we can remove the cast. config = cast( - Dict[str, Dict[str, Any]], + dict[str, dict[str, Any]], {"DEFAULT": {"num": "99"}, "GLOBAL": {"store_true_flag": True}}, ) global_options = _parse(config=config).for_global_scope() diff --git a/src/python/pants/option/ranked_value.py b/src/python/pants/option/ranked_value.py index 677cdafa00f..b5538f8e26b 100644 --- a/src/python/pants/option/ranked_value.py +++ b/src/python/pants/option/ranked_value.py @@ -3,10 +3,11 @@ from __future__ import annotations +from collections.abc import Iterator from dataclasses import dataclass from enum import Enum from functools import total_ordering -from typing import Any, Dict, Iterator, List, Optional, Tuple, Union +from typing import Any, Optional, Union # NB: Must mirror the Rank enum in src/rust/engine/options/src/lib.rs. @@ -33,7 +34,7 @@ def __lt__(self, other: Any) -> bool: return NotImplemented return self._rank < other._rank - def description(self) -> Optional[str]: + def description(self) -> str | None: """The source descriptions used to display option value derivation to users.""" # These specific strings are for compatibility with the legacy parser's tests. # We may revisit them once that is gone. @@ -46,8 +47,8 @@ def description(self) -> Optional[str]: return None -Value = Union[str, int, float, None, Dict, Enum, List] -ValueAndDetails = Tuple[Optional[Value], Optional[str]] +Value = Union[str, int, float, None, dict, Enum, list] +ValueAndDetails = tuple[Optional[Value], Optional[str]] @dataclass(frozen=True) diff --git a/src/python/pants/option/registrar.py b/src/python/pants/option/registrar.py index 8251fed992f..f6ade6017f3 100644 --- a/src/python/pants/option/registrar.py +++ b/src/python/pants/option/registrar.py @@ -7,9 +7,10 @@ import inspect import logging import typing +from collections.abc import Iterator, Mapping from dataclasses import dataclass from enum import Enum -from typing import Any, Iterator, Mapping +from typing import Any from pants.base.deprecated import validate_deprecation_semver from pants.option.custom_types import ( diff --git a/src/python/pants/option/scope.py b/src/python/pants/option/scope.py index 7945a15406e..ee328f1ab40 100644 --- a/src/python/pants/option/scope.py +++ b/src/python/pants/option/scope.py @@ -2,7 +2,7 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). from dataclasses import dataclass -from typing import Optional, Tuple, Type, cast +from typing import Optional, cast from pants.option.option_value_container import OptionValueContainer @@ -26,12 +26,12 @@ class ScopeInfo: """Information about a scope.""" scope: str - subsystem_cls: Optional[Type] = None + subsystem_cls: type | None = None # A ScopeInfo may have a deprecated_scope (from its associated subsystem_cls), which represents # a previous/deprecated name for a current/non-deprecated ScopeInfo. It may also be directly # deprecated via this `removal_version`, which allows for the deprecation of an entire scope. - removal_version: Optional[str] = None - removal_hint: Optional[str] = None + removal_version: str | None = None + removal_hint: str | None = None # Command line goal scope flag. is_goal: bool = False @@ -47,20 +47,20 @@ def description(self) -> str: return cast(str, self._subsystem_cls_attr("help")) @property - def deprecated_scope(self) -> Optional[str]: + def deprecated_scope(self) -> str | None: return cast(Optional[str], self._subsystem_cls_attr("deprecated_options_scope")) @property - def deprecated_scope_removal_version(self) -> Optional[str]: + def deprecated_scope_removal_version(self) -> str | None: return cast( Optional[str], self._subsystem_cls_attr("deprecated_options_scope_removal_version"), ) @property - def scope_aliases(self) -> Tuple[str, ...]: + def scope_aliases(self) -> tuple[str, ...]: """BuiltinGoal subsystems may define aliases.""" - return cast(Tuple[str, ...], self._subsystem_cls_attr("aliases", ())) + return cast(tuple[str, ...], self._subsystem_cls_attr("aliases", ())) def _subsystem_cls_attr(self, name: str, default=None): return getattr(self.subsystem_cls, name, default) if self.subsystem_cls else default diff --git a/src/python/pants/option/subsystem.py b/src/python/pants/option/subsystem.py index a8e731cab24..10053d169d6 100644 --- a/src/python/pants/option/subsystem.py +++ b/src/python/pants/option/subsystem.py @@ -7,7 +7,8 @@ import inspect import re from abc import ABCMeta -from typing import TYPE_CHECKING, Any, Callable, ClassVar, Iterable, Sequence, TypeVar, cast +from collections.abc import Callable, Iterable, Sequence +from typing import TYPE_CHECKING, Any, ClassVar, TypeVar, cast from pants.engine.env_vars import EnvironmentVars, EnvironmentVarsRequest from pants.engine.internals.selectors import AwaitableConstraints, Get diff --git a/src/python/pants/pantsd/pants_daemon_core.py b/src/python/pants/pantsd/pants_daemon_core.py index f7a03c3716a..6c20a124d1b 100644 --- a/src/python/pants/pantsd/pants_daemon_core.py +++ b/src/python/pants/pantsd/pants_daemon_core.py @@ -5,8 +5,9 @@ import logging import threading +from collections.abc import Iterator from contextlib import contextmanager -from typing import Iterator, Protocol +from typing import Protocol from pants.build_graph.build_configuration import BuildConfiguration from pants.engine.env_vars import CompleteEnvironmentVars diff --git a/src/python/pants/pantsd/process_manager.py b/src/python/pants/pantsd/process_manager.py index ca1defc0449..1c28933cd72 100644 --- a/src/python/pants/pantsd/process_manager.py +++ b/src/python/pants/pantsd/process_manager.py @@ -10,8 +10,9 @@ import time import traceback from abc import ABCMeta +from collections.abc import Callable from hashlib import sha256 -from typing import Callable, cast +from typing import cast import psutil diff --git a/src/python/pants/pantsd/service/pants_service.py b/src/python/pants/pantsd/service/pants_service.py index eab505ee7c7..8908161ed76 100644 --- a/src/python/pants/pantsd/service/pants_service.py +++ b/src/python/pants/pantsd/service/pants_service.py @@ -5,8 +5,8 @@ import threading import time from abc import ABC, abstractmethod +from collections.abc import KeysView from dataclasses import dataclass -from typing import Dict, KeysView, Tuple logger = logging.getLogger(__name__) @@ -34,7 +34,7 @@ def __init__(self): self.name = self.__class__.__name__ self._state = _ServiceState() - def setup(self, services: Tuple["PantsService", ...]): + def setup(self, services: tuple["PantsService", ...]): """Called before `run` to allow for service->service or other side-effecting setup.""" self.services = services @@ -199,9 +199,9 @@ class PantsServices: JOIN_TIMEOUT_SECONDS = 1 - _service_threads: Dict[PantsService, threading.Thread] + _service_threads: dict[PantsService, threading.Thread] - def __init__(self, services: Tuple[PantsService, ...] = ()) -> None: + def __init__(self, services: tuple[PantsService, ...] = ()) -> None: object.__setattr__(self, "_service_threads", self._start(services)) @classmethod @@ -212,7 +212,7 @@ def _make_thread(cls, service): return t @classmethod - def _start(cls, services: Tuple[PantsService, ...]) -> Dict[PantsService, threading.Thread]: + def _start(cls, services: tuple[PantsService, ...]) -> dict[PantsService, threading.Thread]: """Launch a thread per service.""" for service in services: diff --git a/src/python/pants/pantsd/service/scheduler_service.py b/src/python/pants/pantsd/service/scheduler_service.py index 4f3e4805c48..471fba19e1c 100644 --- a/src/python/pants/pantsd/service/scheduler_service.py +++ b/src/python/pants/pantsd/service/scheduler_service.py @@ -3,7 +3,7 @@ import logging import time -from typing import Optional, Tuple, cast +from typing import cast import psutil @@ -33,7 +33,7 @@ def __init__( *, graph_scheduler: GraphScheduler, build_root: str, - invalidation_globs: Tuple[str, ...], + invalidation_globs: tuple[str, ...], pidfile: str, pid: int, max_memory_usage_in_bytes: int, @@ -62,7 +62,7 @@ def __init__( self._logger = logging.getLogger(__name__) # NB: We declare these as a single field so that they can be changed atomically. - self._invalidation_globs_and_snapshot: Tuple[Tuple[str, ...], Optional[Snapshot]] = ( + self._invalidation_globs_and_snapshot: tuple[tuple[str, ...], Snapshot | None] = ( invalidation_globs, None, ) @@ -71,7 +71,7 @@ def __init__( self._pid = pid self._max_memory_usage_in_bytes = max_memory_usage_in_bytes - def _get_snapshot(self, globs: Tuple[str, ...], poll: bool) -> Optional[Snapshot]: + def _get_snapshot(self, globs: tuple[str, ...], poll: bool) -> Snapshot | None: """Returns a Snapshot of the input globs. If poll=True, will wait for up to INVALIDATION_POLL_INTERVAL for the globs to have changed, diff --git a/src/python/pants/source/filespec_test.py b/src/python/pants/source/filespec_test.py index 48e4fa71a71..c43aa8941ec 100644 --- a/src/python/pants/source/filespec_test.py +++ b/src/python/pants/source/filespec_test.py @@ -1,7 +1,6 @@ # Copyright 2017 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). -from typing import Tuple import pytest @@ -16,7 +15,7 @@ def rule_runner() -> RuleRunner: def assert_rule_match( - rule_runner: RuleRunner, glob: str, paths: Tuple[str, ...], *, should_match: bool + rule_runner: RuleRunner, glob: str, paths: tuple[str, ...], *, should_match: bool ) -> None: # Confirm in-memory behavior. matched_filespec = tuple(FilespecMatcher([glob], ()).matches(paths)) @@ -63,7 +62,7 @@ def assert_rule_match( ("a/b/c.py", ("a/b/c.py",)), ], ) -def test_valid_matches(rule_runner: RuleRunner, glob: str, paths: Tuple[str, ...]) -> None: +def test_valid_matches(rule_runner: RuleRunner, glob: str, paths: tuple[str, ...]) -> None: assert_rule_match(rule_runner, glob, paths, should_match=True) @@ -96,5 +95,5 @@ def test_valid_matches(rule_runner: RuleRunner, glob: str, paths: Tuple[str, ... ("**/BUILD", ("src/rust/build.rs",)), ], ) -def test_invalid_matches(rule_runner: RuleRunner, glob: str, paths: Tuple[str, ...]) -> None: +def test_invalid_matches(rule_runner: RuleRunner, glob: str, paths: tuple[str, ...]) -> None: assert_rule_match(rule_runner, glob, paths, should_match=False) diff --git a/src/python/pants/source/source_root.py b/src/python/pants/source/source_root.py index 94038dbfe52..479ff539dfe 100644 --- a/src/python/pants/source/source_root.py +++ b/src/python/pants/source/source_root.py @@ -6,9 +6,9 @@ import itertools import logging import os +from collections.abc import Iterable from dataclasses import dataclass from pathlib import PurePath -from typing import Iterable from pants.build_graph.address import Address from pants.engine.collection import DeduplicatedCollection diff --git a/src/python/pants/source/source_root_test.py b/src/python/pants/source/source_root_test.py index 3f2d46b0cce..7b0ecbbe31e 100644 --- a/src/python/pants/source/source_root_test.py +++ b/src/python/pants/source/source_root_test.py @@ -2,8 +2,8 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). import os +from collections.abc import Iterable from pathlib import PurePath -from typing import Iterable, Optional import pytest @@ -27,9 +27,9 @@ def _find_root( path: str, patterns: Iterable[str], - marker_filenames: Optional[Iterable[str]] = None, - existing_marker_files: Optional[Iterable[str]] = None, -) -> Optional[str]: + marker_filenames: Iterable[str] | None = None, + existing_marker_files: Iterable[str] | None = None, +) -> str | None: source_root_config = create_subsystem( SourceRootConfig, root_patterns=list(patterns), diff --git a/src/python/pants/testutil/option_util.py b/src/python/pants/testutil/option_util.py index 10fe32e9e1b..ce865fa4c81 100644 --- a/src/python/pants/testutil/option_util.py +++ b/src/python/pants/testutil/option_util.py @@ -3,7 +3,8 @@ from __future__ import annotations -from typing import Iterable, Mapping, TypeVar +from collections.abc import Iterable, Mapping +from typing import TypeVar from pants.engine.goal import GoalSubsystem from pants.option.option_value_container import OptionValueContainer, OptionValueContainerBuilder diff --git a/src/python/pants/testutil/pants_integration_test.py b/src/python/pants/testutil/pants_integration_test.py index c1889b92844..292e549b28b 100644 --- a/src/python/pants/testutil/pants_integration_test.py +++ b/src/python/pants/testutil/pants_integration_test.py @@ -7,9 +7,10 @@ import os import subprocess import sys +from collections.abc import Iterator, Mapping from contextlib import contextmanager from dataclasses import dataclass -from typing import Any, Iterator, List, Mapping, Union, cast +from typing import Any, Union, cast import pytest import toml @@ -24,7 +25,7 @@ from pants.util.strutil import ensure_binary # NB: If `shell=True`, it's a single `str`. -Command = Union[str, List[str]] +Command = Union[str, list[str]] # Sometimes we mix strings and bytes as keys and/or values, but in most # cases we pass strict str->str, and we want both to typecheck. @@ -143,7 +144,7 @@ def run_pants_with_workdir_without_waiting( # Only allow-listed entries will be included in the environment if hermetic=True. Note that # the env will already be fairly hermetic thanks to the v2 engine; this provides an # additional layer of hermiticity. - env: dict[Union[str, bytes], Union[str, bytes]] + env: dict[str | bytes, str | bytes] if hermetic: # With an empty environment, we would generally get the true underlying system default # encoding, which is unlikely to be what we want (it's generally ASCII, still). So we diff --git a/src/python/pants/testutil/process_util.py b/src/python/pants/testutil/process_util.py index a5a03b60878..5ee2b78c070 100644 --- a/src/python/pants/testutil/process_util.py +++ b/src/python/pants/testutil/process_util.py @@ -3,7 +3,7 @@ from __future__ import annotations -from typing import Callable +from collections.abc import Callable from pants.engine.process import Process diff --git a/src/python/pants/testutil/python_interpreter_selection.py b/src/python/pants/testutil/python_interpreter_selection.py index edb6b82adbe..39c3736b04e 100644 --- a/src/python/pants/testutil/python_interpreter_selection.py +++ b/src/python/pants/testutil/python_interpreter_selection.py @@ -5,8 +5,8 @@ import os import subprocess +from collections.abc import Iterable from functools import lru_cache -from typing import Iterable from unittest import skipIf import _pytest.mark.structures diff --git a/src/python/pants/testutil/python_rule_runner.py b/src/python/pants/testutil/python_rule_runner.py index 9c75420cdf2..61c64ad923b 100644 --- a/src/python/pants/testutil/python_rule_runner.py +++ b/src/python/pants/testutil/python_rule_runner.py @@ -3,7 +3,7 @@ from __future__ import annotations -from typing import Iterable, Mapping +from collections.abc import Iterable, Mapping from pants.option.options_bootstrapper import OptionsBootstrapper from pants.testutil.rule_runner import RuleRunner diff --git a/src/python/pants/testutil/rule_runner.py b/src/python/pants/testutil/rule_runner.py index cc08207f206..1eb5dcb109b 100644 --- a/src/python/pants/testutil/rule_runner.py +++ b/src/python/pants/testutil/rule_runner.py @@ -9,29 +9,14 @@ import os import re import sys +from collections.abc import Callable, Coroutine, Generator, Iterable, Iterator, Mapping, Sequence from contextlib import contextmanager from dataclasses import dataclass from io import StringIO from pathlib import Path, PurePath from pprint import pformat from tempfile import mkdtemp -from typing import ( - Any, - Callable, - Coroutine, - Generator, - Generic, - Iterable, - Iterator, - Literal, - Mapping, - Sequence, - Type, - TypeVar, - Union, - cast, - overload, -) +from typing import Any, Generic, Literal, TypeVar, cast, overload from pants.base.build_environment import get_buildroot from pants.base.build_root import BuildRoot @@ -638,7 +623,7 @@ def run_interactive_process(self, request: InteractiveProcess) -> InteractivePro ), ) - def do_not_use_mock(self, output_type: Type, input_types: Iterable[type]) -> MockGet: + def do_not_use_mock(self, output_type: type, input_types: Iterable[type]) -> MockGet: """Returns a `MockGet` whose behavior is to run the actual rule using this `RuleRunner`""" return MockGet( output_type=output_type, @@ -668,7 +653,7 @@ class MockGet(Generic[_O]): @dataclass(frozen=True) class MockRequestExceptionComparable: - category: Union[Literal["Get"], Literal["Effect"], str] + category: Literal["Get"] | Literal["Effect"] | str output_type: str | None input_types: tuple[str, ...] @@ -678,13 +663,13 @@ def __str__(self): def _compare_expected_mocks( - expected: Sequence[Union[Get, Effect, AwaitableConstraints]], - actual: Sequence[Union[MockGet, MockEffect]], + expected: Sequence[Get | Effect | AwaitableConstraints], + actual: Sequence[MockGet | MockEffect], ) -> str: """Try to be helpful with identifying the problem with supplied mocks.""" def as_comparable( - o: Union[Get, Effect, MockGet, MockEffect, AwaitableConstraints, type] + o: Get | Effect | MockGet | MockEffect | AwaitableConstraints | type, ) -> MockRequestExceptionComparable: if isinstance(o, MockGet) or isinstance(o, Get): category = "Get" diff --git a/src/python/pants/util/collections.py b/src/python/pants/util/collections.py index b1ca606db49..4694b5ea23d 100644 --- a/src/python/pants/util/collections.py +++ b/src/python/pants/util/collections.py @@ -7,8 +7,9 @@ import collections.abc import gc import math +from collections.abc import Callable, Iterable, Iterator, MutableMapping from sys import getsizeof -from typing import Any, Callable, Iterable, Iterator, MutableMapping, TypeVar +from typing import Any, TypeVar from pants.engine.internals import native_engine from pants.util.strutil import softwrap diff --git a/src/python/pants/util/contextutil.py b/src/python/pants/util/contextutil.py index bccbcfb09fe..4b8080e3aca 100644 --- a/src/python/pants/util/contextutil.py +++ b/src/python/pants/util/contextutil.py @@ -10,11 +10,12 @@ import tempfile import threading import zipfile +from collections.abc import Callable, Iterator, Mapping from contextlib import contextmanager from pathlib import Path from queue import Queue from socketserver import TCPServer -from typing import IO, Any, Callable, Iterator, Mapping +from typing import IO, Any from pants.util.dirutil import safe_delete diff --git a/src/python/pants/util/contextutil_test.py b/src/python/pants/util/contextutil_test.py index 1ed46342e37..ca4dc626f20 100644 --- a/src/python/pants/util/contextutil_test.py +++ b/src/python/pants/util/contextutil_test.py @@ -6,8 +6,8 @@ import subprocess import sys import zipfile +from collections.abc import Iterator from contextlib import contextmanager -from typing import Iterator import pytest diff --git a/src/python/pants/util/cstutil.py b/src/python/pants/util/cstutil.py index 384ec6901e5..c04c5262bac 100644 --- a/src/python/pants/util/cstutil.py +++ b/src/python/pants/util/cstutil.py @@ -5,7 +5,6 @@ import importlib.util import logging -from typing import Union import libcst as cst import libcst.matchers as m @@ -30,7 +29,7 @@ def make_importfrom_attr(module: str) -> cst.Attribute | cst.Name: return cst.Attribute(value=make_importfrom_attr(partial_module), attr=cst.Name(parts[-1])) -def make_importfrom_attr_matcher(module: str) -> Union[m.Attribute, m.Name]: +def make_importfrom_attr_matcher(module: str) -> m.Attribute | m.Name: """Generates a cst matcher.Attribute or matcher.Name from a module string.""" parts = module.split(".") if len(parts) == 1: diff --git a/src/python/pants/util/dirutil.py b/src/python/pants/util/dirutil.py index 7e9a2b7e72a..5d87358afbe 100644 --- a/src/python/pants/util/dirutil.py +++ b/src/python/pants/util/dirutil.py @@ -12,9 +12,10 @@ import threading import uuid from collections import defaultdict +from collections.abc import Callable, Iterable, Iterator, Sequence from contextlib import contextmanager from pathlib import Path -from typing import Any, Callable, DefaultDict, Iterable, Iterator, Literal, Sequence, overload +from typing import Any, DefaultDict, Literal, overload from pants.util.strutil import ensure_text diff --git a/src/python/pants/util/dirutil_test.py b/src/python/pants/util/dirutil_test.py index 2b472ceb6a0..25d6667e543 100644 --- a/src/python/pants/util/dirutil_test.py +++ b/src/python/pants/util/dirutil_test.py @@ -7,9 +7,9 @@ import os import unittest import unittest.mock +from collections.abc import Iterator from contextlib import contextmanager from dataclasses import dataclass -from typing import Iterator import pytest diff --git a/src/python/pants/util/enums.py b/src/python/pants/util/enums.py index 9b414292c93..37d0f9922cb 100644 --- a/src/python/pants/util/enums.py +++ b/src/python/pants/util/enums.py @@ -1,8 +1,9 @@ # Copyright 2019 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). +from collections.abc import Mapping from enum import Enum -from typing import FrozenSet, Mapping, TypeVar +from typing import TypeVar class EnumMatchError(ValueError): @@ -24,7 +25,7 @@ class UnrecognizedMatchError(EnumMatchError): def match(enum_instance: _E, enum_values_to_results: Mapping[_E, _V]) -> _V: # TODO: consider memoizing the result of this entire method, as well as the value of # `all_instances` for a given enum class! - all_instances: FrozenSet[_E] = frozenset(type(enum_instance)) + all_instances: frozenset[_E] = frozenset(type(enum_instance)) unrecognized_values = [value for value in enum_values_to_results if value not in all_instances] missing_values = [value for value in all_instances if value not in enum_values_to_results] if unrecognized_values: diff --git a/src/python/pants/util/filtering_test.py b/src/python/pants/util/filtering_test.py index 900ec2c58f9..c76a3a82185 100644 --- a/src/python/pants/util/filtering_test.py +++ b/src/python/pants/util/filtering_test.py @@ -1,7 +1,7 @@ # Copyright 2015 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). -from typing import Callable +from collections.abc import Callable from pants.util.filtering import and_filters, create_filter, create_filters diff --git a/src/python/pants/util/frozendict.py b/src/python/pants/util/frozendict.py index a50bb7e5341..cc592c12b5a 100644 --- a/src/python/pants/util/frozendict.py +++ b/src/python/pants/util/frozendict.py @@ -3,7 +3,8 @@ from __future__ import annotations -from typing import Any, Callable, Iterable, Iterator, Mapping, TypeVar, cast, overload +from collections.abc import Callable, Iterable, Iterator, Mapping +from typing import Any, TypeVar, cast, overload from pants.util.memo import memoized_method from pants.util.strutil import softwrap diff --git a/src/python/pants/util/memo.py b/src/python/pants/util/memo.py index 9054e4ef9ba..37ce68cb78e 100644 --- a/src/python/pants/util/memo.py +++ b/src/python/pants/util/memo.py @@ -3,8 +3,9 @@ import functools import inspect +from collections.abc import Callable from contextlib import contextmanager -from typing import Any, Callable, Optional, TypeVar +from typing import Any, TypeVar from pants.util.meta import T, classproperty @@ -61,7 +62,7 @@ def per_instance(*args, **kwargs): return equal_args(*instance_and_rest, **kwargs) -def memoized(func: Optional[F] = None, key_factory=equal_args, cache_factory=dict) -> F: +def memoized(func: F | None = None, key_factory=equal_args, cache_factory=dict) -> F: """Memoizes the results of a function call. By default, exactly one result is memoized for each unique combination of function arguments. @@ -146,7 +147,7 @@ def clear(): return memoize # type: ignore[return-value] -def memoized_method(func: Optional[F] = None, key_factory=per_instance, cache_factory=dict) -> F: +def memoized_method(func: F | None = None, key_factory=per_instance, cache_factory=dict) -> F: """A convenience wrapper for memoizing instance methods. Typically you'd expect a memoized instance method to hold a cached value per class instance; @@ -183,7 +184,7 @@ def memoized_method(func: Optional[F] = None, key_factory=per_instance, cache_fa def memoized_property( - func: Optional[Callable[..., T]] = None, key_factory=per_instance, cache_factory=dict + func: Callable[..., T] | None = None, key_factory=per_instance, cache_factory=dict ) -> T: """A convenience wrapper for memoizing properties. @@ -254,16 +255,14 @@ def memoized_property( # TODO[13244]: fix type hint issue when using @memoized_classmethod and friends -def memoized_classmethod( - func: Optional[F] = None, key_factory=per_instance, cache_factory=dict -) -> F: +def memoized_classmethod(func: F | None = None, key_factory=per_instance, cache_factory=dict) -> F: return classmethod( # type: ignore[return-value] memoized_method(func, key_factory=key_factory, cache_factory=cache_factory) ) def memoized_classproperty( - func: Optional[Callable[..., T]] = None, key_factory=per_instance, cache_factory=dict + func: Callable[..., T] | None = None, key_factory=per_instance, cache_factory=dict ) -> T: return classproperty( memoized_classmethod(func, key_factory=key_factory, cache_factory=cache_factory) @@ -271,7 +270,7 @@ def memoized_classproperty( def testable_memoized_property( - func: Optional[Callable[..., T]] = None, key_factory=per_instance, cache_factory=dict + func: Callable[..., T] | None = None, key_factory=per_instance, cache_factory=dict ) -> T: """A variant of `memoized_property` that allows for setting of properties (for tests, etc).""" getter = memoized_method(func=func, key_factory=key_factory, cache_factory=cache_factory) diff --git a/src/python/pants/util/meta.py b/src/python/pants/util/meta.py index 5625fc40393..e59a46064c6 100644 --- a/src/python/pants/util/meta.py +++ b/src/python/pants/util/meta.py @@ -2,10 +2,11 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). from abc import ABC, abstractmethod -from typing import Any, Callable, Optional, Type, TypeVar, Union +from collections.abc import Callable +from typing import Any, TypeVar T = TypeVar("T") -C = TypeVar("C", bound=Type) +C = TypeVar("C", bound=type) class SingletonMetaclass(type): @@ -32,12 +33,12 @@ class _ClassPropertyDescriptor: # definition beyond declaring a @classproperty. It seems overriding __set__ and __delete__ would # require defining a metaclass or overriding __setattr__/__delattr__ (see # https://stackoverflow.com/questions/5189699/how-to-make-a-class-property). - def __init__(self, fget: Union[classmethod, staticmethod], doc: Optional[str]) -> None: + def __init__(self, fget: classmethod | staticmethod, doc: str | None) -> None: self.fget = fget self.__doc__ = doc # See https://docs.python.org/3/howto/descriptor.html for more details. - def __get__(self, obj: T, objtype: Optional[Type[T]] = None) -> Any: + def __get__(self, obj: T, objtype: type[T] | None = None) -> Any: if objtype is None: objtype = type(obj) # Get the callable field for this object, which may be a property. @@ -122,10 +123,10 @@ class _ClassDecoratorWithSentinelAttribute(ABC): """ @abstractmethod - def __call__(self, cls: Type) -> Type: ... + def __call__(self, cls: type) -> type: ... - def define_instance_of(self, obj: Type, **kwargs) -> Type: + def define_instance_of(self, obj: type, **kwargs) -> type: return type(obj.__name__, (obj,), {"_decorated_type_checkable_type": type(self), **kwargs}) - def is_instance(self, obj: Type) -> bool: + def is_instance(self, obj: type) -> bool: return getattr(obj, "_decorated_type_checkable_type", None) is type(self) diff --git a/src/python/pants/util/ordered_set.py b/src/python/pants/util/ordered_set.py index ba2d7abfff1..b2421addb8f 100644 --- a/src/python/pants/util/ordered_set.py +++ b/src/python/pants/util/ordered_set.py @@ -15,7 +15,8 @@ from __future__ import annotations import itertools -from typing import AbstractSet, Any, Hashable, Iterable, Iterator, MutableSet, Set, TypeVar, cast +from collections.abc import Hashable, Iterable, Iterator, MutableSet +from typing import AbstractSet, Any, TypeVar, cast T = TypeVar("T") T_co = TypeVar("T_co", covariant=True) @@ -190,7 +191,7 @@ def symmetric_difference_update(self, other: Iterable[T]) -> None: """Update this OrderedSet to remove items from another set, then add items from the other set that were not present in this set.""" items_to_add = [item for item in other if item not in self] - items_to_remove = cast(Set[T], set(other)) + items_to_remove = cast(set[T], set(other)) self._items = {item: None for item in self._items.keys() if item not in items_to_remove} for item in items_to_add: self._items[item] = None diff --git a/src/python/pants/util/ordered_set_test.py b/src/python/pants/util/ordered_set_test.py index 7a40df3fc4d..5b98989eb0d 100644 --- a/src/python/pants/util/ordered_set_test.py +++ b/src/python/pants/util/ordered_set_test.py @@ -3,8 +3,9 @@ import itertools import random +from collections.abc import Iterator, Sequence from copy import copy -from typing import AbstractSet, Iterator, Sequence, Tuple, Type, Union +from typing import AbstractSet, Union import pytest @@ -12,7 +13,7 @@ from pants.util.strutil import softwrap OrderedSetInstance = Union[OrderedSet, FrozenOrderedSet] -OrderedSetCls = Union[Type[OrderedSet], Type[FrozenOrderedSet]] +OrderedSetCls = Union[type[OrderedSet], type[FrozenOrderedSet]] @pytest.mark.parametrize("cls", [OrderedSet, FrozenOrderedSet]) @@ -179,9 +180,9 @@ def test_clear() -> None: def assert_results_are_the_same( - results: Union[Sequence[AbstractSet], Sequence[bool]], + results: Sequence[AbstractSet] | Sequence[bool], *, - sets: Tuple[OrderedSetInstance, OrderedSetInstance], + sets: tuple[OrderedSetInstance, OrderedSetInstance], ) -> None: """Check that all results have the same value, but are different items.""" assert all( @@ -200,7 +201,7 @@ def assert_results_are_the_same( def generate_testdata( cls: OrderedSetCls, -) -> Iterator[Tuple[OrderedSetInstance, OrderedSetInstance]]: +) -> Iterator[tuple[OrderedSetInstance, OrderedSetInstance]]: data1 = cls([5, 3, 1, 4]) data2 = cls([1, 4]) yield data1, data2 diff --git a/src/python/pants/util/requirements.py b/src/python/pants/util/requirements.py index 6270f98084f..c31b41a281f 100644 --- a/src/python/pants/util/requirements.py +++ b/src/python/pants/util/requirements.py @@ -1,6 +1,6 @@ # Copyright 2023 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). -from typing import Iterator +from collections.abc import Iterator from pants.util.pip_requirement import PipRequirement diff --git a/src/python/pants/util/strutil.py b/src/python/pants/util/strutil.py index f16225c5b15..e7c60eb52fb 100644 --- a/src/python/pants/util/strutil.py +++ b/src/python/pants/util/strutil.py @@ -10,8 +10,9 @@ import shlex import textwrap from collections import abc +from collections.abc import Callable, Iterable, Mapping from logging import Logger -from typing import Any, Callable, Iterable, Mapping, TypeVar +from typing import Any, TypeVar import colors from typing_extensions import ParamSpec diff --git a/src/python/pants/util/value_interpolation.py b/src/python/pants/util/value_interpolation.py index ed1dd074fab..706f79771b1 100644 --- a/src/python/pants/util/value_interpolation.py +++ b/src/python/pants/util/value_interpolation.py @@ -3,8 +3,9 @@ from __future__ import annotations +from collections.abc import Mapping from dataclasses import dataclass -from typing import ClassVar, Mapping, TypeVar, Union +from typing import ClassVar, TypeVar, Union from pants.engine.addresses import Address from pants.util.frozendict import FrozenDict diff --git a/src/python/pants/vcs/changed.py b/src/python/pants/vcs/changed.py index 07bd62a3b11..b4907f39f4c 100644 --- a/src/python/pants/vcs/changed.py +++ b/src/python/pants/vcs/changed.py @@ -3,9 +3,9 @@ from __future__ import annotations +from collections.abc import Iterable from dataclasses import dataclass from enum import Enum -from typing import Iterable from pants.backend.project_info import dependents from pants.backend.project_info.dependents import Dependents, DependentsRequest diff --git a/src/python/pants/vcs/changed_integration_test.py b/src/python/pants/vcs/changed_integration_test.py index 3e3d98eed42..f22cb20ca78 100644 --- a/src/python/pants/vcs/changed_integration_test.py +++ b/src/python/pants/vcs/changed_integration_test.py @@ -4,9 +4,9 @@ from __future__ import annotations import subprocess +from collections.abc import Iterator from pathlib import Path from textwrap import dedent -from typing import Iterator import pytest diff --git a/src/python/pants/vcs/git.py b/src/python/pants/vcs/git.py index 0b4c896a570..e98295b0f15 100644 --- a/src/python/pants/vcs/git.py +++ b/src/python/pants/vcs/git.py @@ -8,12 +8,13 @@ import os import re from collections import defaultdict +from collections.abc import Iterable from dataclasses import dataclass from functools import cached_property from io import StringIO from os import PathLike from pathlib import Path, PurePath -from typing import Any, DefaultDict, Iterable +from typing import Any, DefaultDict from pants.core.util_rules.system_binaries import GitBinary, GitBinaryException, MaybeGitBinary from pants.engine.engine_aware import EngineAwareReturnType diff --git a/src/python/pants/vcs/git_test.py b/src/python/pants/vcs/git_test.py index 843e4e85930..e59f532dddb 100644 --- a/src/python/pants/vcs/git_test.py +++ b/src/python/pants/vcs/git_test.py @@ -6,10 +6,11 @@ import os import re import subprocess +from collections.abc import Callable, Iterator from functools import partial from pathlib import Path, PurePath from textwrap import dedent -from typing import Any, Callable, Iterator +from typing import Any import pytest diff --git a/src/python/pants/vcs/hunk.py b/src/python/pants/vcs/hunk.py index 7d25a08def3..faa6505a8fa 100644 --- a/src/python/pants/vcs/hunk.py +++ b/src/python/pants/vcs/hunk.py @@ -1,7 +1,6 @@ # Copyright 2024 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). from dataclasses import dataclass -from typing import Optional from pants.engine.collection import Collection @@ -49,5 +48,5 @@ class Hunk: In the special case when file is deleted right = None. """ - left: Optional[TextBlock] - right: Optional[TextBlock] + left: TextBlock | None + right: TextBlock | None diff --git a/src/python/pants_release/generate_github_workflows.py b/src/python/pants_release/generate_github_workflows.py index 37c9f6b27ae..ca703cd491a 100644 --- a/src/python/pants_release/generate_github_workflows.py +++ b/src/python/pants_release/generate_github_workflows.py @@ -7,11 +7,12 @@ import difflib import os import re +from collections.abc import Sequence from dataclasses import dataclass, field from enum import Enum, ReprEnum from pathlib import Path from textwrap import dedent # noqa: PNT20 -from typing import Any, Dict, Sequence, cast +from typing import Any, cast import toml import yaml @@ -52,9 +53,9 @@ def action(name: str) -> str: ) -Step = Dict[str, Any] -Jobs = Dict[str, Any] -Env = Dict[str, str] +Step = dict[str, Any] +Jobs = dict[str, Any] +Env = dict[str, str] class Platform(Enum): diff --git a/src/python/pants_release/release.py b/src/python/pants_release/release.py index 2eaffaf509a..2d1afb46574 100644 --- a/src/python/pants_release/release.py +++ b/src/python/pants_release/release.py @@ -12,6 +12,7 @@ import subprocess import sys import venv +from collections.abc import Callable, Iterable, Iterator, Sequence from configparser import ConfigParser from contextlib import contextmanager from dataclasses import dataclass @@ -20,7 +21,7 @@ from functools import total_ordering from math import ceil from pathlib import Path -from typing import Any, Callable, Iterable, Iterator, Sequence, cast +from typing import Any, cast import requests from packaging.version import Version From ea9413ab00169516dd6cb335c99dd4120d7d2003 Mon Sep 17 00:00:00 2001 From: sj Date: Mon, 3 Feb 2025 09:29:17 -0500 Subject: [PATCH 05/10] Removed TYPE_CHECKING - as pyupgrade made it a no-op - Not sure why it was still there, but we'll see what CI thinks about this --- src/python/pants/util/filtering.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/python/pants/util/filtering.py b/src/python/pants/util/filtering.py index db9a1195a72..e615f38ffe0 100644 --- a/src/python/pants/util/filtering.py +++ b/src/python/pants/util/filtering.py @@ -4,17 +4,15 @@ from __future__ import annotations import operator -from typing import TYPE_CHECKING, Callable, Iterable, Tuple, TypeVar - -if TYPE_CHECKING: - from pants.engine.target import Target +from collections.abc import Callable, Iterable +from typing import TypeVar _T = TypeVar("_T") Filter = Callable[[_T], bool] TargetFilter = Callable[["Target"], bool] -def _extract_modifier(modified_param: str) -> Tuple[Callable[[bool], bool], str]: +def _extract_modifier(modified_param: str) -> tuple[Callable[[bool], bool], str]: if modified_param.startswith("-"): return operator.not_, modified_param[1:] From fa0cfc73a99d44c7ead6d5e1df2ad0d8b06612f2 Mon Sep 17 00:00:00 2001 From: sj Date: Mon, 3 Feb 2025 11:00:03 -0500 Subject: [PATCH 06/10] Upgrade Python syntax on build-support and test-projects (NodeJS backend might be broken, as it causes this to fail on my machine) - Updated help pretty printer to strip "collections.abc" from help --- .../bin/generate_builtin_lockfiles.py | 5 +-- build-support/bin/generate_completions.py | 2 +- build-support/bin/generate_json_schema.py | 5 +-- build-support/bin/terraform_tool_versions.py | 19 +++++----- build-support/flake8/await_in_loop.py | 2 +- build-support/flake8/dedent_use_checker.py | 2 +- .../convert_source_to_sources.py | 11 +++--- .../fix_deprecated_globs_usage.py | 36 +++++++++---------- .../fix_deprecated_globs_usage_test.py | 8 ++--- .../migrate_to_toml_config.py | 5 ++- src/python/pants/help/help_info_extracter.py | 2 +- .../python/python_constant/target_types.py | 10 +++--- .../src/python/workunit_logger/register.py | 3 +- .../vcs_test/changed_integration_test.py | 2 +- 14 files changed, 56 insertions(+), 56 deletions(-) diff --git a/build-support/bin/generate_builtin_lockfiles.py b/build-support/bin/generate_builtin_lockfiles.py index 83ceaf5ee66..6f15778dd28 100644 --- a/build-support/bin/generate_builtin_lockfiles.py +++ b/build-support/bin/generate_builtin_lockfiles.py @@ -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 @@ -72,7 +73,7 @@ @dataclass class Tool(Generic[ToolBaseT]): - cls: Type[ToolBaseT] + cls: type[ToolBaseT] backend: str @property diff --git a/build-support/bin/generate_completions.py b/build-support/bin/generate_completions.py index 97f79aeb9da..13de7bcf049 100644 --- a/build-support/bin/generate_completions.py +++ b/build-support/bin/generate_completions.py @@ -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 diff --git a/build-support/bin/generate_json_schema.py b/build-support/bin/generate_json_schema.py index 6466bb11908..9e285075dd9 100644 --- a/build-support/bin/generate_json_schema.py +++ b/build-support/bin/generate_json_schema.py @@ -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 @@ -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 diff --git a/build-support/bin/terraform_tool_versions.py b/build-support/bin/terraform_tool_versions.py index 426e1166c24..ee248126b80 100644 --- a/build-support/bin/terraform_tool_versions.py +++ b/build-support/bin/terraform_tool_versions.py @@ -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 @@ -69,7 +70,7 @@ class Link: link: str -Links = List[Link] +Links = list[Link] def get_tf_page(url) -> BeautifulSoup: @@ -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) @@ -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" @@ -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" @@ -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) diff --git a/build-support/flake8/await_in_loop.py b/build-support/flake8/await_in_loop.py index 22ff9297ed1..38fd83c9209 100644 --- a/build-support/flake8/await_in_loop.py +++ b/build-support/flake8/await_in_loop.py @@ -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]]: diff --git a/build-support/flake8/dedent_use_checker.py b/build-support/flake8/dedent_use_checker.py index 8fca2183b18..7303534300d 100644 --- a/build-support/flake8/dedent_use_checker.py +++ b/build-support/flake8/dedent_use_checker.py @@ -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]]: diff --git a/build-support/migration-support/convert_source_to_sources.py b/build-support/migration-support/convert_source_to_sources.py index 623963bfc7f..cba78d4d362 100755 --- a/build-support/migration-support/convert_source_to_sources.py +++ b/build-support/migration-support/convert_source_to_sources.py @@ -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: @@ -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: @@ -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() @@ -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" diff --git a/build-support/migration-support/fix_deprecated_globs_usage.py b/build-support/migration-support/fix_deprecated_globs_usage.py index 44c488c6165..20c4521d66d 100755 --- a/build-support/migration-support/fix_deprecated_globs_usage.py +++ b/build-support/migration-support/fix_deprecated_globs_usage.py @@ -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) @@ -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: @@ -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("**"): @@ -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. @@ -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 @@ -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] @@ -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): @@ -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" diff --git a/build-support/migration-support/fix_deprecated_globs_usage_test.py b/build-support/migration-support/fix_deprecated_globs_usage_test.py index 43d841901f4..07654074b4f 100644 --- a/build-support/migration-support/fix_deprecated_globs_usage_test.py +++ b/build-support/migration-support/fix_deprecated_globs_usage_test.py @@ -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) @@ -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 diff --git a/build-support/migration-support/migrate_to_toml_config.py b/build-support/migration-support/migrate_to_toml_config.py index 0a28b32b065..892169c87fe 100755 --- a/build-support/migration-support/migrate_to_toml_config.py +++ b/build-support/migration-support/migrate_to_toml_config.py @@ -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}.") @@ -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() diff --git a/src/python/pants/help/help_info_extracter.py b/src/python/pants/help/help_info_extracter.py index accf9d5d993..fee63a52685 100644 --- a/src/python/pants/help/help_info_extracter.py +++ b/src/python/pants/help/help_info_extracter.py @@ -184,7 +184,7 @@ def pretty_print_type_hint(hint: Any) -> str: hint_str = hint.__name__ else: hint_str = str(hint) - return hint_str.replace("typing.", "").replace("NoneType", "None") + return hint_str.replace("collections.abc.", "").replace("typing.", "").replace("NoneType", "None") @dataclass(frozen=True) diff --git a/testprojects/pants-plugins/src/python/python_constant/target_types.py b/testprojects/pants-plugins/src/python/python_constant/target_types.py index 3fdcdc47458..0141aa727c1 100644 --- a/testprojects/pants-plugins/src/python/python_constant/target_types.py +++ b/testprojects/pants-plugins/src/python/python_constant/target_types.py @@ -4,7 +4,7 @@ import logging from collections import defaultdict from dataclasses import dataclass -from typing import Any, DefaultDict, List, Set, Tuple, cast +from typing import Any, DefaultDict, cast from pants.backend.python.dependency_inference.module_mapper import ( FirstPartyPythonModuleMapping, @@ -186,7 +186,7 @@ class ImportVisitor(ast.NodeVisitor): def __init__(self, search_for_modules: set[str]) -> None: super().__init__() self._search_for = search_for_modules - self._found: Set[Var] = set() + self._found: set[Var] = set() def visit_ImportFrom(self, node: ast.ImportFrom) -> Any: if node.module not in self._search_for: @@ -216,7 +216,7 @@ async def get_python_constant_targets(targets: AllTargets) -> AllPythonConstantT ) -class BackwardMapping(FrozenDict[ResolveName, FrozenDict[str, Tuple[str, ...]]]): +class BackwardMapping(FrozenDict[ResolveName, FrozenDict[str, tuple[str, ...]]]): pass @@ -236,7 +236,7 @@ async def get_backward_mapping( ) search_for = {file for path in paths for file in path.files} - result: DefaultDict[str, DefaultDict[str, List[str]]] = defaultdict(lambda: defaultdict(list)) + result: DefaultDict[str, DefaultDict[str, list[str]]] = defaultdict(lambda: defaultdict(list)) for resolve, m in mapping.resolves_to_modules_to_providers.items(): for module, module_providers in m.items(): for module_provider in module_providers: @@ -290,7 +290,7 @@ async def infer_python_dependencies_on_python_constants( vars = ImportVisitor.search_for_vars(content, interesting_modules) logger.debug("vars %s", vars) - filenames_to_python_constant_targets: DefaultDict[str, List[PythonConstantTarget]] = ( + filenames_to_python_constant_targets: DefaultDict[str, list[PythonConstantTarget]] = ( defaultdict(list) ) for path, target in zip(paths, python_constant_targets): diff --git a/testprojects/pants-plugins/src/python/workunit_logger/register.py b/testprojects/pants-plugins/src/python/workunit_logger/register.py index f9afe296a98..bc09b6ea66c 100644 --- a/testprojects/pants-plugins/src/python/workunit_logger/register.py +++ b/testprojects/pants-plugins/src/python/workunit_logger/register.py @@ -4,7 +4,6 @@ import logging import time from dataclasses import dataclass -from typing import Tuple from pants.engine.internals.scheduler import Workunit from pants.engine.rules import collect_rules, rule @@ -46,7 +45,7 @@ def can_finish_async(self) -> bool: def __call__( self, *, - completed_workunits: Tuple[Workunit, ...], + completed_workunits: tuple[Workunit, ...], finished: bool, context: StreamingWorkunitContext, **kwargs diff --git a/testprojects/src/python/vcs_test/changed_integration_test.py b/testprojects/src/python/vcs_test/changed_integration_test.py index 69b972af142..0e3b67a1ab8 100644 --- a/testprojects/src/python/vcs_test/changed_integration_test.py +++ b/testprojects/src/python/vcs_test/changed_integration_test.py @@ -3,9 +3,9 @@ from __future__ import annotations import subprocess +from collections.abc import Iterator from pathlib import Path from textwrap import dedent -from typing import Iterator import pytest From b0b7442d401e0e93f6af1af9c65407325a160a5c Mon Sep 17 00:00:00 2001 From: sj Date: Mon, 3 Feb 2025 11:26:17 -0500 Subject: [PATCH 07/10] Fixed a test that renamed "List" to "list" --- src/python/pants/help/help_info_extracter_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python/pants/help/help_info_extracter_test.py b/src/python/pants/help/help_info_extracter_test.py index 7438588f871..91e22ef97ab 100644 --- a/src/python/pants/help/help_info_extracter_test.py +++ b/src/python/pants/help/help_info_extracter_test.py @@ -812,5 +812,5 @@ class ExampleCls: ) assert ( pretty_print_type_hint(Union[Iterable[list[ExampleCls]], Optional[float], Any]) - == f"Iterable[List[{example_cls_repr}]] | float | None | Any" + == f"Iterable[list[{example_cls_repr}]] | float | None | Any" ) From 1fe162a6ddb4683ed4f1e9898fadca8db0d58798 Mon Sep 17 00:00:00 2001 From: sj Date: Mon, 3 Feb 2025 13:33:11 -0500 Subject: [PATCH 08/10] Revert hcl2_parser to fix py3.8 tests --- src/python/pants/backend/terraform/BUILD | 7 ++++++- src/python/pants/backend/terraform/hcl2_parser.py | 3 ++- src/python/pants/help/help_info_extracter.py | 4 +++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/python/pants/backend/terraform/BUILD b/src/python/pants/backend/terraform/BUILD index babba93b79a..d3c11532cd0 100644 --- a/src/python/pants/backend/terraform/BUILD +++ b/src/python/pants/backend/terraform/BUILD @@ -9,7 +9,12 @@ python_sources( dependencies=[":hcl2_parser", ":lockfile"], ) -python_sources(name="hcl2_parser", sources=["hcl2_parser.py"]) +python_sources( + name="hcl2_parser", + sources=["hcl2_parser.py"], + # Skip pyupgrade to avoid breaking tests running Python 3.8 + skip_pyupgrade=True, +) resource(name="lockfile", source="hcl2.lock") diff --git a/src/python/pants/backend/terraform/hcl2_parser.py b/src/python/pants/backend/terraform/hcl2_parser.py index 187c175d604..06dd38bb789 100644 --- a/src/python/pants/backend/terraform/hcl2_parser.py +++ b/src/python/pants/backend/terraform/hcl2_parser.py @@ -3,6 +3,7 @@ import sys from pathlib import PurePath +from typing import Set # # Note: This file is used as a pex entry point in the execution sandbox. @@ -26,7 +27,7 @@ def resolve_pure_path(base: PurePath, relative_path: PurePath) -> PurePath: return PurePath(*parts) -def extract_module_source_paths(path: PurePath, raw_content: bytes) -> set[str]: +def extract_module_source_paths(path: PurePath, raw_content: bytes) -> Set[str]: # Import here so we can still test this file with pytest (since `hcl2` is not present in # normal Pants venv.) import hcl2 # type: ignore[import-not-found] # pants: no-infer-dep diff --git a/src/python/pants/help/help_info_extracter.py b/src/python/pants/help/help_info_extracter.py index fee63a52685..c08baac9349 100644 --- a/src/python/pants/help/help_info_extracter.py +++ b/src/python/pants/help/help_info_extracter.py @@ -184,7 +184,9 @@ def pretty_print_type_hint(hint: Any) -> str: hint_str = hint.__name__ else: hint_str = str(hint) - return hint_str.replace("collections.abc.", "").replace("typing.", "").replace("NoneType", "None") + return ( + hint_str.replace("collections.abc.", "").replace("typing.", "").replace("NoneType", "None") + ) @dataclass(frozen=True) From d514fad81188dbc16fc50d56670f1523c82b01a3 Mon Sep 17 00:00:00 2001 From: sj Date: Mon, 3 Feb 2025 15:09:11 -0500 Subject: [PATCH 09/10] Making mypy happy by converting some of the generic Type that pyupgraded to type - over to type[Any] --- src/python/pants/engine/internals/specs_rules_test.py | 3 ++- src/python/pants/engine/rules.py | 4 ++-- src/python/pants/option/scope.py | 4 ++-- src/python/pants/util/filtering.py | 6 +++++- src/python/pants/util/meta.py | 2 +- 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/python/pants/engine/internals/specs_rules_test.py b/src/python/pants/engine/internals/specs_rules_test.py index d0f8e6222c5..803fa4636e4 100644 --- a/src/python/pants/engine/internals/specs_rules_test.py +++ b/src/python/pants/engine/internals/specs_rules_test.py @@ -6,6 +6,7 @@ from collections.abc import Iterable from dataclasses import dataclass from textwrap import dedent +from typing import Any import pytest @@ -877,7 +878,7 @@ class FieldSetSubclass2(FieldSetSuperclass): invalid_spec = AddressLiteralSpec("", "invalid") def find_valid_field_sets( - superclass: type, + superclass: type[Any], specs: Iterable[Spec], *, no_applicable_behavior: NoApplicableTargetsBehavior = NoApplicableTargetsBehavior.ignore, diff --git a/src/python/pants/engine/rules.py b/src/python/pants/engine/rules.py index 72a5e6a43c2..792d9077e47 100644 --- a/src/python/pants/engine/rules.py +++ b/src/python/pants/engine/rules.py @@ -152,10 +152,10 @@ class DuplicateRuleError(TypeError): def _ensure_type_annotation( *, - type_annotation: type | None, + type_annotation: type[Any] | None, name: str, raise_type: type[InvalidTypeAnnotation], -) -> type: +) -> type[Any]: if type_annotation is None: raise raise_type(f"{name} is missing a type annotation.") if not isinstance(type_annotation, type): diff --git a/src/python/pants/option/scope.py b/src/python/pants/option/scope.py index ee328f1ab40..454bc3466c9 100644 --- a/src/python/pants/option/scope.py +++ b/src/python/pants/option/scope.py @@ -2,7 +2,7 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). from dataclasses import dataclass -from typing import Optional, cast +from typing import Any, Optional, cast from pants.option.option_value_container import OptionValueContainer @@ -26,7 +26,7 @@ class ScopeInfo: """Information about a scope.""" scope: str - subsystem_cls: type | None = None + subsystem_cls: type[Any] | None = None # A ScopeInfo may have a deprecated_scope (from its associated subsystem_cls), which represents # a previous/deprecated name for a current/non-deprecated ScopeInfo. It may also be directly # deprecated via this `removal_version`, which allows for the deprecation of an entire scope. diff --git a/src/python/pants/util/filtering.py b/src/python/pants/util/filtering.py index e615f38ffe0..a5d42f4b6df 100644 --- a/src/python/pants/util/filtering.py +++ b/src/python/pants/util/filtering.py @@ -5,7 +5,11 @@ import operator from collections.abc import Callable, Iterable -from typing import TypeVar +from typing import TYPE_CHECKING, TypeVar + +if TYPE_CHECKING: + from pants.engine.target import Target + _T = TypeVar("_T") Filter = Callable[[_T], bool] diff --git a/src/python/pants/util/meta.py b/src/python/pants/util/meta.py index e59a46064c6..3eda35fea3e 100644 --- a/src/python/pants/util/meta.py +++ b/src/python/pants/util/meta.py @@ -6,7 +6,7 @@ from typing import Any, TypeVar T = TypeVar("T") -C = TypeVar("C", bound=type) +C = TypeVar("C", bound=type[Any]) class SingletonMetaclass(type): From 2bb85898eb76d5100d995f62dbb02cd56990e62a Mon Sep 17 00:00:00 2001 From: sj Date: Mon, 3 Feb 2025 15:56:40 -0500 Subject: [PATCH 10/10] Forcing pyupgrade to retain the Target import and not break mypy --- src/python/pants/util/filtering.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/python/pants/util/filtering.py b/src/python/pants/util/filtering.py index a5d42f4b6df..c31dc982751 100644 --- a/src/python/pants/util/filtering.py +++ b/src/python/pants/util/filtering.py @@ -10,6 +10,9 @@ if TYPE_CHECKING: from pants.engine.target import Target + # Working around pyupgrade erasing this import, breaking mypy + _ = Target + _T = TypeVar("_T") Filter = Callable[[_T], bool]