From 75205fdcb9203ca6793479918ff866e1e310b538 Mon Sep 17 00:00:00 2001 From: Eric Arellano Date: Tue, 28 Jul 2020 11:08:13 -0700 Subject: [PATCH 1/2] Deprecate `Subsystem.get_options()` in favor of `Subsystem.options` [ci skip-build-wheels] [ci skip-rust] [ci skip-build-wheels] --- src/python/pants/auth/basic_auth.py | 4 +- src/python/pants/auth/cookies.py | 2 +- .../python/awslambda_python_rules.py | 14 +++--- .../pants/backend/codegen/protobuf/protoc.py | 3 +- .../native/subsystems/binaries/binutils.py | 2 +- .../backend/native/subsystems/binaries/gcc.py | 4 +- .../native/subsystems/binaries/llvm.py | 4 +- .../backend/native/subsystems/libc_dev.py | 6 +-- .../native/subsystems/xcode_cli_tools.py | 2 +- src/python/pants/backend/project_info/cloc.py | 6 ++- .../python/dependency_inference/rules.py | 20 +++++++-- .../pants/backend/python/lint/bandit/rules.py | 25 ++++++----- .../backend/python/lint/bandit/subsystem.py | 13 ++++++ .../pants/backend/python/lint/black/rules.py | 29 ++++++------- .../backend/python/lint/black/subsystem.py | 14 ++++++ .../backend/python/lint/docformatter/rules.py | 20 ++++----- .../python/lint/docformatter/subsystem.py | 10 +++++ .../pants/backend/python/lint/flake8/rules.py | 23 +++++----- .../backend/python/lint/flake8/subsystem.py | 14 ++++++ .../pants/backend/python/lint/isort/rules.py | 25 +++++------ .../backend/python/lint/isort/subsystem.py | 15 +++++++ .../pants/backend/python/lint/pylint/rules.py | 13 +++--- .../pants/backend/python/rules/coverage.py | 31 ++++++------- .../backend/python/rules/download_pex_bin.py | 29 ++++++------- .../backend/python/rules/hermetic_pex.py | 8 ++-- src/python/pants/backend/python/rules/pex.py | 12 +++--- .../backend/python/rules/pex_from_targets.py | 4 +- .../backend/python/rules/pytest_runner.py | 6 +-- src/python/pants/backend/python/rules/repl.py | 4 +- .../backend/python/rules/run_setup_py.py | 12 +++--- .../python/subsystems/python_native_code.py | 25 ++++------- .../python/subsystems/python_tool_base.py | 23 +++++++--- .../subsystems/subprocess_environment.py | 35 ++++++--------- .../backend/python/typecheck/mypy/rules.py | 12 +++--- src/python/pants/binaries/binary_util.py | 2 +- .../pants/core/util_rules/external_tool.py | 43 +++++++++++-------- .../core/util_rules/external_tool_test.py | 5 +-- src/python/pants/core/util_rules/pants_bin.py | 2 +- .../pants/engine/internals/options_parsing.py | 2 +- src/python/pants/goal/run_tracker.py | 20 ++++----- src/python/pants/notes/1.17.x.rst | 2 +- src/python/pants/process/subprocess.py | 3 +- src/python/pants/python/python_setup.py | 24 ++++++----- src/python/pants/subsystem/subsystem.py | 4 ++ .../pants_test/init/test_plugin_resolver.py | 4 -- 45 files changed, 320 insertions(+), 260 deletions(-) diff --git a/src/python/pants/auth/basic_auth.py b/src/python/pants/auth/basic_auth.py index 47905d61f7c..5b650e61615 100644 --- a/src/python/pants/auth/basic_auth.py +++ b/src/python/pants/auth/basic_auth.py @@ -87,14 +87,14 @@ def authenticate( if not provider: raise BasicAuthException("No basic auth provider specified.") - provider_config = self.get_options().providers.get(provider) + provider_config = self.options.providers.get(provider) if not provider_config: raise BasicAuthException(f"No config found for provider {provider}.") url = provider_config.get("url") if not url: raise BasicAuthException(f"No url found in config for provider {provider}.") - if not self.get_options().allow_insecure_urls and not url.startswith("https://"): + if not self.options.allow_insecure_urls and not url.startswith("https://"): raise BasicAuthException(f"Auth url for provider {provider} is not secure: {url}.") auth = requests.auth.HTTPBasicAuth(creds.username, creds.password) if creds else None diff --git a/src/python/pants/auth/cookies.py b/src/python/pants/auth/cookies.py index 9ca43957290..61b3f78bde0 100644 --- a/src/python/pants/auth/cookies.py +++ b/src/python/pants/auth/cookies.py @@ -53,7 +53,7 @@ def get_cookie_jar(self): def _get_cookie_file(self): # We expanduser to make it easy for the user to config the cookies into their homedir. - return os.path.realpath(os.path.expanduser(self.get_options().path)) + return os.path.realpath(os.path.expanduser(self.options.path)) @memoized_property def _lock(self): diff --git a/src/python/pants/backend/awslambda/python/awslambda_python_rules.py b/src/python/pants/backend/awslambda/python/awslambda_python_rules.py index daf391f71c0..f5bbf2ab7ee 100644 --- a/src/python/pants/backend/awslambda/python/awslambda_python_rules.py +++ b/src/python/pants/backend/awslambda/python/awslambda_python_rules.py @@ -26,7 +26,7 @@ TwoStepPexFromTargetsRequest, ) from pants.backend.python.subsystems import python_native_code, subprocess_environment -from pants.backend.python.subsystems.subprocess_environment import SubprocessEncodingEnvironment +from pants.backend.python.subsystems.subprocess_environment import SubprocessEnvironment from pants.core.util_rules import strip_source_roots from pants.engine.fs import Digest, MergeDigests from pants.engine.process import Process, ProcessResult @@ -54,7 +54,7 @@ async def create_python_awslambda( field_set: PythonAwsLambdaFieldSet, lambdex_setup: LambdexSetup, python_setup: PythonSetup, - subprocess_encoding_environment: SubprocessEncodingEnvironment, + subprocess_environment: SubprocessEnvironment, ) -> CreatedAWSLambda: # Lambdas typically use the .zip suffix, so we use that instead of .pex. pex_filename = f"{field_set.address.target_name}.zip" @@ -93,7 +93,7 @@ async def create_python_awslambda( lambdex_args = ("build", "-e", field_set.handler.value, pex_filename) process = lambdex_setup.requirements_pex.create_process( python_setup=python_setup, - subprocess_encoding_environment=subprocess_encoding_environment, + subprocess_environment=subprocess_environment, pex_path="./lambdex.pex", pex_args=lambdex_args, input_digest=input_digest, @@ -117,11 +117,9 @@ async def setup_lambdex(lambdex: Lambdex) -> LambdexSetup: Pex, PexRequest( output_filename="lambdex.pex", - requirements=PexRequirements(lambdex.get_requirement_specs()), - interpreter_constraints=PexInterpreterConstraints( - lambdex.default_interpreter_constraints - ), - entry_point=lambdex.get_entry_point(), + requirements=PexRequirements(lambdex.all_requirements), + interpreter_constraints=PexInterpreterConstraints(lambdex.interpreter_constraints), + entry_point=lambdex.entry_point, ), ) return LambdexSetup(requirements_pex=requirements_pex,) diff --git a/src/python/pants/backend/codegen/protobuf/protoc.py b/src/python/pants/backend/codegen/protobuf/protoc.py index 77ff6cae998..e135c7d1159 100644 --- a/src/python/pants/backend/codegen/protobuf/protoc.py +++ b/src/python/pants/backend/codegen/protobuf/protoc.py @@ -36,11 +36,10 @@ def register_options(cls, register): ) def generate_url(self, plat: Platform) -> str: - version = self.options.version plat_str = match(plat, {Platform.darwin: "osx", Platform.linux: "linux"}) return ( f"https://github.com/protocolbuffers/protobuf/releases/download/" - f"v{version}/protoc-{version}-{plat_str}-x86_64.zip" + f"v{self.version}/protoc-{self.version}-{plat_str}-x86_64.zip" ) def generate_exe(self, plat: Platform) -> str: diff --git a/src/python/pants/backend/native/subsystems/binaries/binutils.py b/src/python/pants/backend/native/subsystems/binaries/binutils.py index 7b6dea60a61..ea45a9c67bb 100644 --- a/src/python/pants/backend/native/subsystems/binaries/binutils.py +++ b/src/python/pants/backend/native/subsystems/binaries/binutils.py @@ -15,4 +15,4 @@ class Binutils(ExternalTool): def generate_url(self, plat: Platform) -> str: if plat != Platform.linux: raise ExternalToolError() - return f"https://binaries.pantsbuild.org/bin/binutils/linux/x86_64/{self.options.version}/binutils.tar.gz" + return f"https://binaries.pantsbuild.org/bin/binutils/linux/x86_64/{self.version}/binutils.tar.gz" diff --git a/src/python/pants/backend/native/subsystems/binaries/gcc.py b/src/python/pants/backend/native/subsystems/binaries/gcc.py index 3f084a87f5f..239fc96f1a5 100644 --- a/src/python/pants/backend/native/subsystems/binaries/gcc.py +++ b/src/python/pants/backend/native/subsystems/binaries/gcc.py @@ -25,6 +25,4 @@ class GCC(ExternalTool): def generate_url(self, plat: Platform) -> str: plat_str = "mac/10.13" if plat == Platform.darwin else "linux/x86_64" - return ( - f"https://binaries.pantsbuild.org/bin/gcc/{plat_str}/{self.options.version}/gcc.tar.gz" - ) + return f"https://binaries.pantsbuild.org/bin/gcc/{plat_str}/{self.version}/gcc.tar.gz" diff --git a/src/python/pants/backend/native/subsystems/binaries/llvm.py b/src/python/pants/backend/native/subsystems/binaries/llvm.py index 3260477839f..837c392c95a 100644 --- a/src/python/pants/backend/native/subsystems/binaries/llvm.py +++ b/src/python/pants/backend/native/subsystems/binaries/llvm.py @@ -26,5 +26,5 @@ class LLVM(ExternalTool): def generate_url(self, plat: Platform) -> str: system_id = "apple-darwin" if plat == Platform.darwin else "linux-gnu-ubuntu-16.04" - archive_basename = f"clang+llvm-{self.options.version}-x86_64-{system_id}" - return f"https://releases.llvm.org/{self.options.version}/{archive_basename}.tar.xz" + archive_basename = f"clang+llvm-{self.version}-x86_64-{system_id}" + return f"https://releases.llvm.org/{self.version}/{archive_basename}.tar.xz" diff --git a/src/python/pants/backend/native/subsystems/libc_dev.py b/src/python/pants/backend/native/subsystems/libc_dev.py index f6ea0dc395c..466cb63013f 100644 --- a/src/python/pants/backend/native/subsystems/libc_dev.py +++ b/src/python/pants/backend/native/subsystems/libc_dev.py @@ -73,7 +73,7 @@ def register_options(cls, register): def _get_host_libc_from_host_compiler(self): """Locate the host's libc-dev installation using a specified host compiler's search dirs.""" - compiler_exe = self.get_options().host_compiler + compiler_exe = self.options.host_compiler # Implicitly, we are passing in the environment of the executing pants process to # `get_compiler_library_dirs()`. @@ -102,7 +102,7 @@ def _get_host_libc_from_host_compiler(self): def _host_libc(self): """Use the --libc-dir option if provided, otherwise invoke a host compiler to find libc dev.""" - libc_dir_option = self.get_options().libc_dir + libc_dir_option = self.options.libc_dir if libc_dir_option: maybe_libc_crti = os.path.join(libc_dir_option, self._LIBC_INIT_OBJECT_FILE) if os.path.isfile(maybe_libc_crti): @@ -118,4 +118,4 @@ def _host_libc(self): @memoized_method def get_libc_objects(self): - return [self._host_libc.crti_object] if self.get_options().enable_libc_search else [] + return [self._host_libc.crti_object] if self.options.enable_libc_search else [] diff --git a/src/python/pants/backend/native/subsystems/xcode_cli_tools.py b/src/python/pants/backend/native/subsystems/xcode_cli_tools.py index 5ffb8c26171..ede5bdba057 100644 --- a/src/python/pants/backend/native/subsystems/xcode_cli_tools.py +++ b/src/python/pants/backend/native/subsystems/xcode_cli_tools.py @@ -69,7 +69,7 @@ def register_options(cls, register): @memoized_property def _all_existing_install_prefixes(self): - return [pfx for pfx in self.get_options().install_prefixes if is_readable_dir(pfx)] + return [pfx for pfx in self.options.install_prefixes if is_readable_dir(pfx)] # NB: We use @memoized_method in this file for methods which may raise. @memoized_method diff --git a/src/python/pants/backend/project_info/cloc.py b/src/python/pants/backend/project_info/cloc.py index 1da819cc3e6..052e0633bd4 100644 --- a/src/python/pants/backend/project_info/cloc.py +++ b/src/python/pants/backend/project_info/cloc.py @@ -37,8 +37,10 @@ class ClocBinary(ExternalTool): ] def generate_url(self, plat: Platform) -> str: - version = self.get_options().version - return f"https://github.com/AlDanial/cloc/releases/download/{version}/cloc-{version}.pl" + return ( + f"https://github.com/AlDanial/cloc/releases/download/{self.version}/" + f"cloc-{self.version}.pl" + ) class CountLinesOfCodeSubsystem(GoalSubsystem): diff --git a/src/python/pants/backend/python/dependency_inference/rules.py b/src/python/pants/backend/python/dependency_inference/rules.py index 085ac182997..16f723bd39d 100644 --- a/src/python/pants/backend/python/dependency_inference/rules.py +++ b/src/python/pants/backend/python/dependency_inference/rules.py @@ -3,6 +3,7 @@ import itertools from pathlib import PurePath +from typing import cast from pants.backend.python.dependency_inference import module_mapper from pants.backend.python.dependency_inference.import_parser import find_python_imports @@ -38,7 +39,6 @@ class PythonInference(Subsystem): @classmethod def register_options(cls, register): super().register_options(register) - register( "--imports", default=False, @@ -65,6 +65,18 @@ def register_options(cls, register): ), ) + @property + def imports(self) -> bool: + return cast(bool, self.options.imports) + + @property + def inits(self) -> bool: + return cast(bool, self.options.inits) + + @property + def conftests(self) -> bool: + return cast(bool, self.options.conftests) + class InferPythonDependencies(InferDependenciesRequest): infer_from = PythonSources @@ -74,7 +86,7 @@ class InferPythonDependencies(InferDependenciesRequest): async def infer_python_dependencies( request: InferPythonDependencies, python_inference: PythonInference ) -> InferredDependencies: - if not python_inference.get_options().imports: + if not python_inference.imports: return InferredDependencies() stripped_sources = await Get( @@ -113,7 +125,7 @@ class InferInitDependencies(InferDependenciesRequest): async def infer_python_init_dependencies( request: InferInitDependencies, python_inference: PythonInference ) -> InferredDependencies: - if not python_inference.get_options().inits: + if not python_inference.inits: return InferredDependencies() # Locate __init__.py files not already in the Snapshot. @@ -139,7 +151,7 @@ class InferConftestDependencies(InferDependenciesRequest): async def infer_python_conftest_dependencies( request: InferConftestDependencies, python_inference: PythonInference, ) -> InferredDependencies: - if not python_inference.get_options().conftests: + if not python_inference.conftests: return InferredDependencies() # Locate conftest.py files not already in the Snapshot. diff --git a/src/python/pants/backend/python/lint/bandit/rules.py b/src/python/pants/backend/python/lint/bandit/rules.py index 48db3928dda..514e4a4b0fd 100644 --- a/src/python/pants/backend/python/lint/bandit/rules.py +++ b/src/python/pants/backend/python/lint/bandit/rules.py @@ -2,7 +2,7 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). from dataclasses import dataclass -from typing import Optional, Tuple +from typing import Tuple from pants.backend.python.lint.bandit.subsystem import Bandit from pants.backend.python.rules import download_pex_bin, pex @@ -13,7 +13,7 @@ PexRequirements, ) from pants.backend.python.subsystems import python_native_code, subprocess_environment -from pants.backend.python.subsystems.subprocess_environment import SubprocessEncodingEnvironment +from pants.backend.python.subsystems.subprocess_environment import SubprocessEnvironment from pants.backend.python.target_types import PythonInterpreterCompatibility, PythonSources from pants.core.goals.lint import LintRequest, LintResult, LintResults from pants.core.util_rules import determine_source_files, strip_source_roots @@ -52,9 +52,9 @@ class BanditPartition: def generate_args(*, specified_source_files: SourceFiles, bandit: Bandit) -> Tuple[str, ...]: args = [] - if bandit.options.config is not None: - args.append(f"--config={bandit.options.config}") - args.extend(bandit.options.args) + if bandit.config is not None: + args.append(f"--config={bandit.config}") + args.extend(bandit.args) args.extend(specified_source_files.files) return tuple(args) @@ -64,26 +64,25 @@ async def bandit_lint_partition( partition: BanditPartition, bandit: Bandit, python_setup: PythonSetup, - subprocess_encoding_environment: SubprocessEncodingEnvironment, + subprocess_environment: SubprocessEnvironment, ) -> LintResult: requirements_pex_request = Get( Pex, PexRequest( output_filename="bandit.pex", - requirements=PexRequirements(bandit.get_requirement_specs()), + requirements=PexRequirements(bandit.all_requirements), interpreter_constraints=( partition.interpreter_constraints - or PexInterpreterConstraints(bandit.default_interpreter_constraints) + or PexInterpreterConstraints(bandit.interpreter_constraints) ), - entry_point=bandit.get_entry_point(), + entry_point=bandit.entry_point, ), ) - config_path: Optional[str] = bandit.options.config config_digest_request = Get( Digest, PathGlobs( - globs=[config_path] if config_path else [], + globs=[bandit.config] if bandit.config else [], glob_match_error_behavior=GlobMatchErrorBehavior.error, description_of_origin="the option `--bandit-config`", ), @@ -117,7 +116,7 @@ async def bandit_lint_partition( process = requirements_pex.create_process( python_setup=python_setup, - subprocess_encoding_environment=subprocess_encoding_environment, + subprocess_environment=subprocess_environment, pex_path="./bandit.pex", pex_args=generate_args(specified_source_files=specified_source_files, bandit=bandit), input_digest=input_digest, @@ -133,7 +132,7 @@ async def bandit_lint_partition( async def bandit_lint( request: BanditRequest, bandit: Bandit, python_setup: PythonSetup ) -> LintResults: - if bandit.options.skip: + if bandit.skip: return LintResults() # NB: Bandit output depends upon which Python interpreter version it's run with diff --git a/src/python/pants/backend/python/lint/bandit/subsystem.py b/src/python/pants/backend/python/lint/bandit/subsystem.py index eb859e32a06..f0f60f872b1 100644 --- a/src/python/pants/backend/python/lint/bandit/subsystem.py +++ b/src/python/pants/backend/python/lint/bandit/subsystem.py @@ -1,6 +1,7 @@ # Copyright 2020 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). +from typing import Optional, Tuple, cast from pants.backend.python.subsystems.python_tool_base import PythonToolBase from pants.option.custom_types import file_option, shell_str @@ -41,3 +42,15 @@ def register_options(cls, register): advanced=True, help="Path to a Bandit YAML config file", ) + + @property + def skip(self) -> bool: + return cast(bool, self.options.skip) + + @property + def args(self) -> Tuple[str, ...]: + return tuple(self.options.args) + + @property + def config(self) -> Optional[str]: + return cast(Optional[str], self.options.config) diff --git a/src/python/pants/backend/python/lint/black/rules.py b/src/python/pants/backend/python/lint/black/rules.py index 1ffb6e4578d..998a4edb78e 100644 --- a/src/python/pants/backend/python/lint/black/rules.py +++ b/src/python/pants/backend/python/lint/black/rules.py @@ -4,7 +4,7 @@ import re from dataclasses import dataclass from pathlib import PurePath -from typing import Optional, Tuple +from typing import Tuple from pants.backend.python.lint.black.subsystem import Black from pants.backend.python.lint.python_fmt import PythonFmtRequest @@ -16,7 +16,7 @@ PexRequirements, ) from pants.backend.python.subsystems import python_native_code, subprocess_environment -from pants.backend.python.subsystems.subprocess_environment import SubprocessEncodingEnvironment +from pants.backend.python.subsystems.subprocess_environment import SubprocessEnvironment from pants.backend.python.target_types import PythonSources from pants.core.goals.fmt import FmtResult from pants.core.goals.lint import LintRequest, LintResult, LintResults @@ -65,9 +65,9 @@ def generate_args( args = [] if check_only: args.append("--check") - if black.options.config is not None: - args.extend(["--config", black.options.config]) - args.extend(black.options.args) + if black.config: + args.extend(["--config", black.config]) + args.extend(black.args) # NB: For some reason, Black's --exclude option only works on recursive invocations, meaning # calling Black on a directory(s) and letting it auto-discover files. However, we don't want # Black to run over everything recursively under the directory of our target, as Black should @@ -83,25 +83,22 @@ async def setup( setup_request: SetupRequest, black: Black, python_setup: PythonSetup, - subprocess_encoding_environment: SubprocessEncodingEnvironment, + subprocess_environment: SubprocessEnvironment, ) -> Setup: requirements_pex_request = Get( Pex, PexRequest( output_filename="black.pex", - requirements=PexRequirements(black.get_requirement_specs()), - interpreter_constraints=PexInterpreterConstraints( - black.default_interpreter_constraints - ), - entry_point=black.get_entry_point(), + requirements=PexRequirements(black.all_requirements), + interpreter_constraints=PexInterpreterConstraints(black.interpreter_constraints), + entry_point=black.entry_point, ), ) - config_path: Optional[str] = black.options.config config_digest_request = Get( Digest, PathGlobs( - globs=[config_path] if config_path else [], + globs=[black.config] if black.config else [], glob_match_error_behavior=GlobMatchErrorBehavior.error, description_of_origin="the option `--black-config`", ), @@ -141,7 +138,7 @@ async def setup( process = requirements_pex.create_process( python_setup=python_setup, - subprocess_encoding_environment=subprocess_encoding_environment, + subprocess_environment=subprocess_environment, pex_path="./black.pex", pex_args=generate_args( specified_source_files=specified_source_files, @@ -159,7 +156,7 @@ async def setup( @rule(desc="Format using Black") async def black_fmt(field_sets: BlackRequest, black: Black) -> FmtResult: - if black.options.skip: + if black.skip: return FmtResult.noop() setup = await Get(Setup, SetupRequest(field_sets, check_only=False)) result = await Get(ProcessResult, Process, setup.process) @@ -173,7 +170,7 @@ async def black_fmt(field_sets: BlackRequest, black: Black) -> FmtResult: @rule(desc="Lint using Black") async def black_lint(field_sets: BlackRequest, black: Black) -> LintResults: - if black.options.skip: + if black.skip: return LintResults() setup = await Get(Setup, SetupRequest(field_sets, check_only=True)) result = await Get(FallibleProcessResult, Process, setup.process) diff --git a/src/python/pants/backend/python/lint/black/subsystem.py b/src/python/pants/backend/python/lint/black/subsystem.py index 9ee09de41d0..3cfaf3026b1 100644 --- a/src/python/pants/backend/python/lint/black/subsystem.py +++ b/src/python/pants/backend/python/lint/black/subsystem.py @@ -1,6 +1,8 @@ # Copyright 2019 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). +from typing import Optional, Tuple, cast + from pants.backend.python.subsystems.python_tool_base import PythonToolBase from pants.option.custom_types import file_option, shell_str @@ -42,3 +44,15 @@ def register_options(cls, register): advanced=True, help="Path to Black's pyproject.toml config file", ) + + @property + def skip(self) -> bool: + return cast(bool, self.options.skip) + + @property + def args(self) -> Tuple[str, ...]: + return tuple(self.options.args) + + @property + def config(self) -> Optional[str]: + return cast(Optional[str], self.options.config) diff --git a/src/python/pants/backend/python/lint/docformatter/rules.py b/src/python/pants/backend/python/lint/docformatter/rules.py index 6cbbb7787c4..ba709580836 100644 --- a/src/python/pants/backend/python/lint/docformatter/rules.py +++ b/src/python/pants/backend/python/lint/docformatter/rules.py @@ -14,7 +14,7 @@ PexRequirements, ) from pants.backend.python.subsystems import python_native_code, subprocess_environment -from pants.backend.python.subsystems.subprocess_environment import SubprocessEncodingEnvironment +from pants.backend.python.subsystems.subprocess_environment import SubprocessEnvironment from pants.backend.python.target_types import PythonSources from pants.core.goals.fmt import FmtResult from pants.core.goals.lint import LintRequest, LintResult, LintResults @@ -62,7 +62,7 @@ def generate_args( ) -> Tuple[str, ...]: return ( "--check" if check_only else "--in-place", - *docformatter.options.args, + *docformatter.args, *specified_source_files.files, ) @@ -72,17 +72,15 @@ async def setup( setup_request: SetupRequest, docformatter: Docformatter, python_setup: PythonSetup, - subprocess_encoding_environment: SubprocessEncodingEnvironment, + subprocess_environment: SubprocessEnvironment, ) -> Setup: requirements_pex_request = Get( Pex, PexRequest( output_filename="docformatter.pex", - requirements=PexRequirements(docformatter.get_requirement_specs()), - interpreter_constraints=PexInterpreterConstraints( - docformatter.default_interpreter_constraints - ), - entry_point=docformatter.get_entry_point(), + requirements=PexRequirements(docformatter.all_requirements), + interpreter_constraints=PexInterpreterConstraints(docformatter.interpreter_constraints), + entry_point=docformatter.entry_point, ), ) @@ -119,7 +117,7 @@ async def setup( process = requirements_pex.create_process( python_setup=python_setup, - subprocess_encoding_environment=subprocess_encoding_environment, + subprocess_environment=subprocess_environment, pex_path="./docformatter.pex", pex_args=generate_args( specified_source_files=specified_source_files, @@ -138,7 +136,7 @@ async def setup( @rule(desc="Format Python docstrings with docformatter") async def docformatter_fmt(request: DocformatterRequest, docformatter: Docformatter) -> FmtResult: - if docformatter.options.skip: + if docformatter.skip: return FmtResult.noop() setup = await Get(Setup, SetupRequest(request, check_only=False)) result = await Get(ProcessResult, Process, setup.process) @@ -151,7 +149,7 @@ async def docformatter_fmt(request: DocformatterRequest, docformatter: Docformat async def docformatter_lint( request: DocformatterRequest, docformatter: Docformatter ) -> LintResults: - if docformatter.options.skip: + if docformatter.skip: return LintResults() setup = await Get(Setup, SetupRequest(request, check_only=True)) result = await Get(FallibleProcessResult, Process, setup.process) diff --git a/src/python/pants/backend/python/lint/docformatter/subsystem.py b/src/python/pants/backend/python/lint/docformatter/subsystem.py index c87f382cdfe..ca2f00a350e 100644 --- a/src/python/pants/backend/python/lint/docformatter/subsystem.py +++ b/src/python/pants/backend/python/lint/docformatter/subsystem.py @@ -1,6 +1,8 @@ # Copyright 2020 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). +from typing import Tuple, cast + from pants.backend.python.subsystems.python_tool_base import PythonToolBase from pants.option.custom_types import shell_str @@ -33,3 +35,11 @@ def register_options(cls, register): f'`--{cls.options_scope}-args="--wrap-summaries=100 --pre-summary-newline"`.' ), ) + + @property + def skip(self) -> bool: + return cast(bool, self.options.skip) + + @property + def args(self) -> Tuple[str, ...]: + return tuple(self.options.args) diff --git a/src/python/pants/backend/python/lint/flake8/rules.py b/src/python/pants/backend/python/lint/flake8/rules.py index 9b817161d79..576f3c67eee 100644 --- a/src/python/pants/backend/python/lint/flake8/rules.py +++ b/src/python/pants/backend/python/lint/flake8/rules.py @@ -13,7 +13,7 @@ PexRequirements, ) from pants.backend.python.subsystems import python_native_code, subprocess_environment -from pants.backend.python.subsystems.subprocess_environment import SubprocessEncodingEnvironment +from pants.backend.python.subsystems.subprocess_environment import SubprocessEnvironment from pants.backend.python.target_types import PythonInterpreterCompatibility, PythonSources from pants.core.goals.lint import ( LintRequest, @@ -67,11 +67,11 @@ def generate_args( *, specified_source_files: SourceFiles, flake8: Flake8, output_file: Optional[str] ) -> Tuple[str, ...]: args = [] - if flake8.options.config is not None: - args.append(f"--config={flake8.options.config}") + if flake8.config: + args.append(f"--config={flake8.config}") if output_file: args.append(f"--output-file={output_file}") - args.extend(flake8.options.args) + args.extend(flake8.args) args.extend(specified_source_files.files) return tuple(args) @@ -82,26 +82,25 @@ async def flake8_lint_partition( flake8: Flake8, lint_subsystem: LintSubsystem, python_setup: PythonSetup, - subprocess_encoding_environment: SubprocessEncodingEnvironment, + subprocess_environment: SubprocessEnvironment, ) -> LintResult: requirements_pex_request = Get( Pex, PexRequest( output_filename="flake8.pex", - requirements=PexRequirements(flake8.get_requirement_specs()), + requirements=PexRequirements(flake8.all_requirements), interpreter_constraints=( partition.interpreter_constraints - or PexInterpreterConstraints(flake8.default_interpreter_constraints) + or PexInterpreterConstraints(flake8.interpreter_constraints) ), - entry_point=flake8.get_entry_point(), + entry_point=flake8.entry_point, ), ) - config_path: Optional[str] = flake8.options.config config_digest_request = Get( Digest, PathGlobs( - globs=[config_path] if config_path else [], + globs=[flake8.config] if flake8.config else [], glob_match_error_behavior=GlobMatchErrorBehavior.error, description_of_origin="the option `--flake8-config`", ), @@ -142,7 +141,7 @@ async def flake8_lint_partition( ) process = requirements_pex.create_process( python_setup=python_setup, - subprocess_encoding_environment=subprocess_encoding_environment, + subprocess_environment=subprocess_environment, pex_path="./flake8.pex", pex_args=flake8_args, output_files=(report_path.name,) if report_path else None, @@ -171,7 +170,7 @@ async def flake8_lint_partition( async def flake8_lint( request: Flake8Request, flake8: Flake8, python_setup: PythonSetup ) -> LintResults: - if flake8.options.skip: + if flake8.skip: return LintResults() # NB: Flake8 output depends upon which Python interpreter version it's run with diff --git a/src/python/pants/backend/python/lint/flake8/subsystem.py b/src/python/pants/backend/python/lint/flake8/subsystem.py index 33458813c8f..dc880ff46ac 100644 --- a/src/python/pants/backend/python/lint/flake8/subsystem.py +++ b/src/python/pants/backend/python/lint/flake8/subsystem.py @@ -1,6 +1,8 @@ # Copyright 2019 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). +from typing import Optional, Tuple, cast + from pants.backend.python.subsystems.python_tool_base import PythonToolBase from pants.option.custom_types import file_option, shell_str @@ -39,3 +41,15 @@ def register_options(cls, register): advanced=True, help="Path to `.flake8` or alternative Flake8 config file", ) + + @property + def skip(self) -> bool: + return cast(bool, self.options.skip) + + @property + def args(self) -> Tuple[str, ...]: + return tuple(self.options.args) + + @property + def config(self) -> Optional[str]: + return cast(Optional[str], self.options.config) diff --git a/src/python/pants/backend/python/lint/isort/rules.py b/src/python/pants/backend/python/lint/isort/rules.py index 69b56ea273a..f26cf3749f8 100644 --- a/src/python/pants/backend/python/lint/isort/rules.py +++ b/src/python/pants/backend/python/lint/isort/rules.py @@ -2,7 +2,7 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). from dataclasses import dataclass -from typing import List, Optional, Tuple +from typing import Tuple from pants.backend.python.lint.isort.subsystem import Isort from pants.backend.python.lint.python_fmt import PythonFmtRequest @@ -14,7 +14,7 @@ PexRequirements, ) from pants.backend.python.subsystems import python_native_code, subprocess_environment -from pants.backend.python.subsystems.subprocess_environment import SubprocessEncodingEnvironment +from pants.backend.python.subsystems.subprocess_environment import SubprocessEnvironment from pants.backend.python.target_types import PythonSources from pants.core.goals.fmt import FmtResult from pants.core.goals.lint import LintRequest, LintResult, LintResults @@ -72,7 +72,7 @@ def generate_args( args = [] if check_only: args.append("--check-only") - args.extend(isort.options.args) + args.extend(isort.args) args.extend(specified_source_files.files) return tuple(args) @@ -82,25 +82,22 @@ async def setup( setup_request: SetupRequest, isort: Isort, python_setup: PythonSetup, - subprocess_encoding_environment: SubprocessEncodingEnvironment, + subprocess_environment: SubprocessEnvironment, ) -> Setup: requirements_pex_request = Get( Pex, PexRequest( output_filename="isort.pex", - requirements=PexRequirements(isort.get_requirement_specs()), - interpreter_constraints=PexInterpreterConstraints( - isort.default_interpreter_constraints - ), - entry_point=isort.get_entry_point(), + requirements=PexRequirements(isort.all_requirements), + interpreter_constraints=PexInterpreterConstraints(isort.interpreter_constraints), + entry_point=isort.entry_point, ), ) - config_path: Optional[List[str]] = isort.options.config config_digest_request = Get( Digest, PathGlobs( - globs=config_path or (), + globs=isort.config, glob_match_error_behavior=GlobMatchErrorBehavior.error, conjunction=GlobExpansionConjunction.all_match, description_of_origin="the option `--isort-config`", @@ -145,7 +142,7 @@ async def setup( process = requirements_pex.create_process( python_setup=python_setup, - subprocess_encoding_environment=subprocess_encoding_environment, + subprocess_environment=subprocess_environment, pex_path="./isort.pex", pex_args=generate_args( specified_source_files=specified_source_files, @@ -163,7 +160,7 @@ async def setup( @rule(desc="Format using isort") async def isort_fmt(request: IsortRequest, isort: Isort) -> FmtResult: - if isort.options.skip: + if isort.skip: return FmtResult.noop() setup = await Get(Setup, SetupRequest(request, check_only=False)) result = await Get(ProcessResult, Process, setup.process) @@ -177,7 +174,7 @@ async def isort_fmt(request: IsortRequest, isort: Isort) -> FmtResult: @rule(desc="Lint using isort") async def isort_lint(request: IsortRequest, isort: Isort) -> LintResults: - if isort.options.skip: + if isort.skip: return LintResults() setup = await Get(Setup, SetupRequest(request, check_only=True)) result = await Get(FallibleProcessResult, Process, setup.process) diff --git a/src/python/pants/backend/python/lint/isort/subsystem.py b/src/python/pants/backend/python/lint/isort/subsystem.py index 6cee160935e..8b876406325 100644 --- a/src/python/pants/backend/python/lint/isort/subsystem.py +++ b/src/python/pants/backend/python/lint/isort/subsystem.py @@ -1,6 +1,8 @@ # Copyright 2018 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). +from typing import Tuple, cast + from pants.backend.python.subsystems.python_tool_base import PythonToolBase from pants.option.custom_types import file_option, shell_str @@ -38,5 +40,18 @@ def register_options(cls, register): "--config", type=list, member_type=file_option, + advanced=True, help="Path to `isort.cfg` or alternative isort config file(s)", ) + + @property + def skip(self) -> bool: + return cast(bool, self.options.skip) + + @property + def args(self) -> Tuple[str, ...]: + return tuple(self.options.args) + + @property + def config(self) -> Tuple[str, ...]: + return tuple(self.options.config) diff --git a/src/python/pants/backend/python/lint/pylint/rules.py b/src/python/pants/backend/python/lint/pylint/rules.py index 86bec251069..c14587ed8bb 100644 --- a/src/python/pants/backend/python/lint/pylint/rules.py +++ b/src/python/pants/backend/python/lint/pylint/rules.py @@ -21,7 +21,7 @@ UnstrippedPythonSourcesRequest, ) from pants.backend.python.subsystems import python_native_code, subprocess_environment -from pants.backend.python.subsystems.subprocess_environment import SubprocessEncodingEnvironment +from pants.backend.python.subsystems.subprocess_environment import SubprocessEnvironment from pants.backend.python.target_types import ( PythonInterpreterCompatibility, PythonRequirementsField, @@ -112,7 +112,7 @@ async def pylint_lint_partition( partition: PylintPartition, pylint: Pylint, python_setup: PythonSetup, - subprocess_encoding_environment: SubprocessEncodingEnvironment, + subprocess_environment: SubprocessEnvironment, ) -> LintResult: # We build one PEX with Pylint requirements and another with all direct 3rd-party dependencies. # Splitting this into two PEXes gives us finer-grained caching. We then merge via `--pex-path`. @@ -130,9 +130,8 @@ async def pylint_lint_partition( Pex, PexRequest( output_filename="pylint.pex", - requirements=PexRequirements([*pylint.get_requirement_specs(), *plugin_requirements]), + requirements=PexRequirements([*pylint.all_requirements, *plugin_requirements]), interpreter_constraints=partition.interpreter_constraints, - entry_point=pylint.get_entry_point(), ), ) requirements_pex_request = Get( @@ -152,7 +151,7 @@ async def pylint_lint_partition( Pex, PexRequest( output_filename="pylint_runner.pex", - entry_point=pylint.get_entry_point(), + entry_point=pylint.entry_point, interpreter_constraints=partition.interpreter_constraints, additional_args=pylint_runner_pex_args, ), @@ -234,7 +233,7 @@ async def pylint_lint_partition( process = pylint_runner_pex.create_process( python_setup=python_setup, - subprocess_encoding_environment=subprocess_encoding_environment, + subprocess_environment=subprocess_environment, pex_path="./pylint_runner.pex", env={"PEX_EXTRA_SYS_PATH": ":".join(pythonpath)}, pex_args=generate_args(specified_source_files=specified_source_files, pylint=pylint), @@ -289,7 +288,7 @@ async def pylint_lint( *plugin_targets_compatibility_fields, ), python_setup, - ) or PexInterpreterConstraints(pylint.default_interpreter_constraints) + ) or PexInterpreterConstraints(pylint.interpreter_constraints) interpreter_constraints_to_target_setup[interpreter_constraints].add(target_setup) partitions = ( diff --git a/src/python/pants/backend/python/rules/coverage.py b/src/python/pants/backend/python/rules/coverage.py index 0ab068a3631..a24f1290dd9 100644 --- a/src/python/pants/backend/python/rules/coverage.py +++ b/src/python/pants/backend/python/rules/coverage.py @@ -5,7 +5,7 @@ from dataclasses import dataclass from io import StringIO from pathlib import PurePath -from typing import List, Optional, Sequence, Tuple +from typing import List, Optional, Sequence, Tuple, cast from pants.backend.python.rules.pex import ( Pex, @@ -18,7 +18,7 @@ UnstrippedPythonSourcesRequest, ) from pants.backend.python.subsystems.python_tool_base import PythonToolBase -from pants.backend.python.subsystems.subprocess_environment import SubprocessEncodingEnvironment +from pants.backend.python.subsystems.subprocess_environment import SubprocessEnvironment from pants.core.goals.test import ( ConsoleCoverageReport, CoverageData, @@ -129,6 +129,10 @@ def reports(self) -> Tuple[CoverageReportType, ...]: def output_dir(self) -> PurePath: return PurePath(self.options.output_dir) + @property + def config(self) -> Optional[str]: + return cast(Optional[str], self.options.config) + @dataclass(frozen=True) class PytestCoverageData(CoverageData): @@ -165,19 +169,18 @@ def _validate_and_update_config( @rule async def create_coverage_config(coverage: CoverageSubsystem) -> CoverageConfig: - config_path: Optional[str] = coverage.options.config coverage_config = configparser.ConfigParser() - if config_path: + if coverage.config: config_contents = await Get( DigestContents, PathGlobs( - globs=config_path, + globs=coverage.config, glob_match_error_behavior=GlobMatchErrorBehavior.error, description_of_origin=f"the option `--{coverage.options_scope}-config`", ), ) coverage_config.read_string(config_contents[0].content.decode()) - _validate_and_update_config(coverage_config, config_path) + _validate_and_update_config(coverage_config, coverage.config) config_stream = StringIO() coverage_config.write(config_stream) config_content = config_stream.getvalue() @@ -196,11 +199,9 @@ async def setup_coverage(coverage: CoverageSubsystem) -> CoverageSetup: Pex, PexRequest( output_filename="coverage.pex", - requirements=PexRequirements(coverage.get_requirement_specs()), - interpreter_constraints=PexInterpreterConstraints( - coverage.default_interpreter_constraints - ), - entry_point=coverage.get_entry_point(), + requirements=PexRequirements(coverage.all_requirements), + interpreter_constraints=PexInterpreterConstraints(coverage.interpreter_constraints), + entry_point=coverage.entry_point, ), ) return CoverageSetup(pex) @@ -216,7 +217,7 @@ async def merge_coverage_data( data_collection: PytestCoverageDataCollection, coverage_setup: CoverageSetup, python_setup: PythonSetup, - subprocess_encoding_environment: SubprocessEncodingEnvironment, + subprocess_environment: SubprocessEnvironment, ) -> MergedCoverageData: if len(data_collection) == 1: return MergedCoverageData(data_collection[0].digest) @@ -234,7 +235,7 @@ async def merge_coverage_data( output_files=(".coverage",), description=f"Merge {len(prefixes)} Pytest coverage reports.", python_setup=python_setup, - subprocess_encoding_environment=subprocess_encoding_environment, + subprocess_environment=subprocess_environment, ) result = await Get(ProcessResult, Process, process) return MergedCoverageData(result.output_digest) @@ -248,7 +249,7 @@ async def generate_coverage_reports( coverage_subsystem: CoverageSubsystem, transitive_targets: TransitiveTargets, python_setup: PythonSetup, - subprocess_encoding_environment: SubprocessEncodingEnvironment, + subprocess_environment: SubprocessEnvironment, ) -> CoverageReports: """Takes all Python test results and generates a single coverage report.""" sources = await Get( @@ -293,7 +294,7 @@ async def generate_coverage_reports( output_files=("coverage.xml",) if report_type == CoverageReportType.XML else None, description=f"Generate Pytest {report_type.report_name} coverage report.", python_setup=python_setup, - subprocess_encoding_environment=subprocess_encoding_environment, + subprocess_environment=subprocess_environment, ) ) results = await MultiGet(Get(ProcessResult, Process, process) for process in processes) diff --git a/src/python/pants/backend/python/rules/download_pex_bin.py b/src/python/pants/backend/python/rules/download_pex_bin.py index 7f9191f884a..06f2c97ec82 100644 --- a/src/python/pants/backend/python/rules/download_pex_bin.py +++ b/src/python/pants/backend/python/rules/download_pex_bin.py @@ -5,8 +5,8 @@ from typing import Any, Iterable, Mapping, Optional from pants.backend.python.rules.hermetic_pex import HermeticPex -from pants.backend.python.subsystems.python_native_code import PexBuildEnvironment -from pants.backend.python.subsystems.subprocess_environment import SubprocessEncodingEnvironment +from pants.backend.python.subsystems.python_native_code import PythonNativeCode +from pants.backend.python.subsystems.subprocess_environment import SubprocessEnvironment from pants.core.util_rules.external_tool import ( DownloadedExternalTool, ExternalTool, @@ -32,7 +32,7 @@ class PexBin(ExternalTool): ] def generate_url(self, plat: Platform) -> str: - return f"https://github.com/pantsbuild/pex/releases/download/{self.options.version}/pex" + return f"https://github.com/pantsbuild/pex/releases/download/{self.version}/pex" @dataclass(frozen=True) @@ -51,8 +51,8 @@ def digest(self) -> Digest: def create_process( # type: ignore[override] self, python_setup: PythonSetup, - subprocess_encoding_environment: SubprocessEncodingEnvironment, - pex_build_environment: PexBuildEnvironment, + subprocess_environment: SubprocessEnvironment, + python_native_code: PythonNativeCode, *, pex_args: Iterable[str], description: str, @@ -63,30 +63,29 @@ def create_process( # type: ignore[override] """Creates an Process that will run the pex CLI tool hermetically. :param python_setup: The parameters for selecting python interpreters to use when invoking - the pex tool. - :param subprocess_encoding_environment: The locale settings to use for the pex tool - invocation. - :param pex_build_environment: The build environment for the pex tool. + the pex tool. + :param subprocess_environment: The locale settings to use for the pex tool + invocation. + :param python_native_code: The build environment for the pex tool. :param pex_args: The arguments to pass to the pex CLI tool. :param description: A description of the process execution to be performed. :param input_digest: The directory digest that contain the PEX CLI tool itself and any - input files it needs to run against. By default, this is just the - files that contain the PEX CLI tool itself. To merge in additional - files, include `self.digest` in a `MergeDigests` request. + input files it needs to run against. By default, this is just the files that contain + the PEX CLI tool itself. To merge in additional files, include `self.digest` in a + `MergeDigests` request. :param env: The environment to run the PEX in. :param kwargs: Any additional :class:`Process` kwargs to pass through. """ pex_root_path = ".cache/pex_root" - env = dict(env) if env else {} - env.update(**pex_build_environment.invocation_environment_dict,) + env = {**(env or {}), **python_native_code.invocation_environment} if "--pex-root" in pex_args: raise ValueError("--pex-root flag not allowed. We set its value for you.") pex_args = ("--pex-root", pex_root_path) + tuple(pex_args) return super().create_process( python_setup=python_setup, - subprocess_encoding_environment=subprocess_encoding_environment, + subprocess_environment=subprocess_environment, pex_path=self.executable, pex_args=pex_args, description=description, diff --git a/src/python/pants/backend/python/rules/hermetic_pex.py b/src/python/pants/backend/python/rules/hermetic_pex.py index 9bc0dd1ca02..8d4681e7d83 100644 --- a/src/python/pants/backend/python/rules/hermetic_pex.py +++ b/src/python/pants/backend/python/rules/hermetic_pex.py @@ -3,7 +3,7 @@ from typing import Any, Iterable, Mapping, Optional -from pants.backend.python.subsystems.subprocess_environment import SubprocessEncodingEnvironment +from pants.backend.python.subsystems.subprocess_environment import SubprocessEnvironment from pants.engine.fs import Digest from pants.engine.process import Process from pants.python.python_setup import PythonSetup @@ -16,7 +16,7 @@ class HermeticPex: def create_process( self, python_setup: PythonSetup, - subprocess_encoding_environment: SubprocessEncodingEnvironment, + subprocess_environment: SubprocessEnvironment, *, pex_path: str, pex_args: Iterable[str], @@ -29,7 +29,7 @@ def create_process( :param python_setup: The parameters for selecting python interpreters to use when invoking the PEX. - :param subprocess_encoding_environment: The locale settings to use for the PEX invocation. + :param subprocess_environment: The locale settings to use for the PEX invocation. :param pex_path: The path within `input_files` of the PEX file (or directory if a loose pex). :param pex_args: The arguments to pass to the PEX executable. @@ -53,7 +53,7 @@ def create_process( PATH=create_path_env_var(python_setup.interpreter_search_paths), PEX_INHERIT_PATH="false", PEX_IGNORE_RCFILES="true", - **subprocess_encoding_environment.invocation_environment_dict, + **subprocess_environment.invocation_environment, ) if env: hermetic_env.update(env) diff --git a/src/python/pants/backend/python/rules/pex.py b/src/python/pants/backend/python/rules/pex.py index 1b4be294b7d..4c28c086d4b 100644 --- a/src/python/pants/backend/python/rules/pex.py +++ b/src/python/pants/backend/python/rules/pex.py @@ -23,8 +23,8 @@ from pants.backend.python.rules.download_pex_bin import DownloadedPexBin from pants.backend.python.rules.hermetic_pex import HermeticPex from pants.backend.python.rules.util import parse_interpreter_constraint -from pants.backend.python.subsystems.python_native_code import PexBuildEnvironment -from pants.backend.python.subsystems.subprocess_environment import SubprocessEncodingEnvironment +from pants.backend.python.subsystems.python_native_code import PythonNativeCode +from pants.backend.python.subsystems.subprocess_environment import SubprocessEnvironment from pants.backend.python.target_types import PythonInterpreterCompatibility from pants.backend.python.target_types import PythonPlatforms as PythonPlatformsField from pants.backend.python.target_types import PythonRequirementsField @@ -308,8 +308,8 @@ async def create_pex( pex_bin: DownloadedPexBin, python_setup: PythonSetup, python_repos: PythonRepos, - subprocess_encoding_environment: SubprocessEncodingEnvironment, - pex_build_environment: PexBuildEnvironment, + subprocess_environment: SubprocessEnvironment, + python_native_code: PythonNativeCode, platform: Platform, log_level: LogLevel, ) -> Pex: @@ -416,8 +416,8 @@ async def create_pex( PlatformConstraint(platform.value), ): pex_bin.create_process( python_setup=python_setup, - subprocess_encoding_environment=subprocess_encoding_environment, - pex_build_environment=pex_build_environment, + subprocess_environment=subprocess_environment, + python_native_code=python_native_code, pex_args=argv, input_digest=merged_digest, description=description, diff --git a/src/python/pants/backend/python/rules/pex_from_targets.py b/src/python/pants/backend/python/rules/pex_from_targets.py index 5d8904185ce..c4d3b3a1315 100644 --- a/src/python/pants/backend/python/rules/pex_from_targets.py +++ b/src/python/pants/backend/python/rules/pex_from_targets.py @@ -157,7 +157,7 @@ async def pex_from_targets(request: PexFromTargetsRequest, python_setup: PythonS f"entries for the following requirements: {', '.join(unconstrained_projects)}" ) - if python_setup.options.resolve_all_constraints: + if python_setup.resolve_all_constraints: if unconstrained_projects: logger.warning( "Ignoring resolve_all_constraints setting in [python_setup] scope" @@ -165,7 +165,7 @@ async def pex_from_targets(request: PexFromTargetsRequest, python_setup: PythonS ) else: requirements = PexRequirements(str(req) for req in constraints_file_reqs) - elif python_setup.options.resolve_all_constraints: + elif python_setup.resolve_all_constraints: raise ValueError( "resolve_all_constraints in the [python-setup] scope is set, so " "requirement_constraints in [python-setup] must also be provided." diff --git a/src/python/pants/backend/python/rules/pytest_runner.py b/src/python/pants/backend/python/rules/pytest_runner.py index a13ec1ddde1..4c3821e785b 100644 --- a/src/python/pants/backend/python/rules/pytest_runner.py +++ b/src/python/pants/backend/python/rules/pytest_runner.py @@ -25,7 +25,7 @@ UnstrippedPythonSourcesRequest, ) from pants.backend.python.subsystems.pytest import PyTest -from pants.backend.python.subsystems.subprocess_environment import SubprocessEncodingEnvironment +from pants.backend.python.subsystems.subprocess_environment import SubprocessEnvironment from pants.backend.python.target_types import ( PythonInterpreterCompatibility, PythonTestsSources, @@ -212,7 +212,7 @@ async def run_python_test( field_set: PythonTestFieldSet, test_setup: TestTargetSetup, python_setup: PythonSetup, - subprocess_encoding_environment: SubprocessEncodingEnvironment, + subprocess_environment: SubprocessEnvironment, global_options: GlobalOptions, test_subsystem: TestSubsystem, ) -> TestResult: @@ -252,7 +252,7 @@ async def run_python_test( process = test_setup.test_runner_pex.create_process( python_setup=python_setup, - subprocess_encoding_environment=subprocess_encoding_environment, + subprocess_environment=subprocess_environment, pex_path=f"./{test_setup.test_runner_pex.output_filename}", pex_args=test_setup.args, input_digest=test_setup.input_digest, diff --git a/src/python/pants/backend/python/rules/repl.py b/src/python/pants/backend/python/rules/repl.py index 6ccb1e14537..abbb9079e1a 100644 --- a/src/python/pants/backend/python/rules/repl.py +++ b/src/python/pants/backend/python/rules/repl.py @@ -55,8 +55,8 @@ async def create_ipython_repl_request(repl: IPythonRepl, ipython: IPython) -> Re PexFromTargetsRequest( (tgt.address for tgt in repl.targets), output_filename="ipython.pex", - entry_point=ipython.get_entry_point(), - additional_requirements=ipython.get_requirement_specs(), + entry_point=ipython.entry_point, + additional_requirements=ipython.all_requirements, include_source_files=True, ), ) diff --git a/src/python/pants/backend/python/rules/run_setup_py.py b/src/python/pants/backend/python/rules/run_setup_py.py index e89b18f0f53..4490ce97cc5 100644 --- a/src/python/pants/backend/python/rules/run_setup_py.py +++ b/src/python/pants/backend/python/rules/run_setup_py.py @@ -17,7 +17,7 @@ ) from pants.backend.python.rules.setuptools import Setuptools from pants.backend.python.rules.util import PackageDatum, distutils_repr, find_packages, is_python2 -from pants.backend.python.subsystems.subprocess_environment import SubprocessEncodingEnvironment +from pants.backend.python.subsystems.subprocess_environment import SubprocessEnvironment from pants.backend.python.target_types import ( PythonEntryPoint, PythonInterpreterCompatibility, @@ -374,7 +374,7 @@ async def run_setup_py( req: RunSetupPyRequest, setuptools_setup: SetuptoolsSetup, python_setup: PythonSetup, - subprocess_encoding_environment: SubprocessEncodingEnvironment, + subprocess_environment: SubprocessEnvironment, ) -> RunSetupPyResult: """Run a setup.py command on a single exported target.""" input_digest = await Get( @@ -385,7 +385,7 @@ async def run_setup_py( dist_dir = "dist/" process = setuptools_setup.requirements_pex.create_process( python_setup=python_setup, - subprocess_encoding_environment=subprocess_encoding_environment, + subprocess_environment=subprocess_environment, pex_path="./setuptools.pex", pex_args=("setup.py", *req.args), input_digest=input_digest, @@ -687,10 +687,8 @@ async def setup_setuptools(setuptools: Setuptools) -> SetuptoolsSetup: Pex, PexRequest( output_filename="setuptools.pex", - requirements=PexRequirements(setuptools.get_requirement_specs()), - interpreter_constraints=PexInterpreterConstraints( - setuptools.default_interpreter_constraints - ), + requirements=PexRequirements(setuptools.all_requirements), + interpreter_constraints=PexInterpreterConstraints(setuptools.interpreter_constraints), ), ) return SetuptoolsSetup(requirements_pex=requirements_pex,) 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 6a9ba6acf9e..f3d02dce41f 100644 --- a/src/python/pants/backend/python/subsystems/python_native_code.py +++ b/src/python/pants/backend/python/subsystems/python_native_code.py @@ -2,10 +2,9 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). import os -from dataclasses import dataclass from typing import Dict, Tuple -from pants.engine.rules import collect_rules, rule +from pants.engine.rules import collect_rules from pants.subsystem.subsystem import Subsystem from pants.util.strutil import safe_shlex_join, safe_shlex_split @@ -34,29 +33,21 @@ def register_options(cls, register): help="Override the `LDFLAGS` environment variable for any forked subprocesses.", ) + @property + def cpp_flags(self) -> Tuple[str, ...]: + return tuple(self.options.cpp_flags) -@dataclass(frozen=True) -class PexBuildEnvironment: - cpp_flags: Tuple[str, ...] - ld_flags: Tuple[str, ...] + @property + def ld_flags(self) -> Tuple[str, ...]: + return tuple(self.options.ld_flags) @property - def invocation_environment_dict(self) -> Dict[str, str]: + def invocation_environment(self) -> Dict[str, str]: return { "CPPFLAGS": safe_shlex_join(self.cpp_flags), "LDFLAGS": safe_shlex_join(self.ld_flags), } -@rule -def create_pex_native_build_environment( - python_native_code: PythonNativeCode, -) -> PexBuildEnvironment: - return PexBuildEnvironment( - cpp_flags=python_native_code.get_options().cpp_flags, - ld_flags=python_native_code.get_options().ld_flags, - ) - - def rules(): return collect_rules() 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 da81c47e3cb..b736cdcac7c 100644 --- a/src/python/pants/backend/python/subsystems/python_tool_base.py +++ b/src/python/pants/backend/python/subsystems/python_tool_base.py @@ -1,7 +1,7 @@ # Copyright 2018 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). -from typing import Optional, Sequence, Tuple +from typing import Optional, Sequence, Tuple, cast from pants.subsystem.subsystem import Subsystem @@ -54,11 +54,22 @@ def register_options(cls, register): "library, invoked by a wrapper script.", ) - def get_interpreter_constraints(self): - return self.get_options().interpreter_constraints + @property + def version(self) -> Optional[str]: + return cast(Optional[str], self.options.version) - def get_requirement_specs(self) -> Tuple[str, ...]: + @property + def extra_requirements(self) -> Tuple[str, ...]: + return tuple(self.options.extra_requirements) + + @property + def all_requirements(self) -> Tuple[str, ...]: return (self.options.version, *self.options.extra_requirements) - def get_entry_point(self): - return self.get_options().entry_point + @property + def interpreter_constraints(self) -> Tuple[str, ...]: + return tuple(self.options.interpreter_constraints) + + @property + def entry_point(self) -> Optional[str]: + return cast(Optional[str], self.options.entry_point) diff --git a/src/python/pants/backend/python/subsystems/subprocess_environment.py b/src/python/pants/backend/python/subsystems/subprocess_environment.py index 5abc91e3663..90f82245e59 100644 --- a/src/python/pants/backend/python/subsystems/subprocess_environment.py +++ b/src/python/pants/backend/python/subsystems/subprocess_environment.py @@ -2,10 +2,9 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). import os -from dataclasses import dataclass -from typing import Dict, Optional +from typing import Dict, Optional, cast -from pants.engine.rules import collect_rules, rule +from pants.engine.rules import collect_rules from pants.subsystem.subsystem import Subsystem @@ -17,43 +16,33 @@ class SubprocessEnvironment(Subsystem): @classmethod def register_options(cls, register): super().register_options(register) - # TODO(#7735): move the --lang and --lc-all flags to a general subprocess support subsystem. register( "--lang", + type=str, default=os.environ.get("LANG"), advanced=True, help="Override the `LANG` environment variable for any forked subprocesses.", ) register( "--lc-all", + type=str, default=os.environ.get("LC_ALL"), advanced=True, help="Override the `LC_ALL` environment variable for any forked subprocesses.", ) + @property + def lang(self) -> Optional[str]: + return cast(Optional[str], self.options.lang) -@dataclass(frozen=True) -class SubprocessEncodingEnvironment: - lang: Optional[str] - lc_all: Optional[str] + @property + def lc_all(self) -> Optional[str]: + return cast(Optional[str], self.options.lc_all) @property - def invocation_environment_dict(self) -> Dict[str, str]: - return { - "LANG": self.lang or "", - "LC_ALL": self.lc_all or "", - } - - -@rule -def create_subprocess_encoding_environment( - subprocess_environment: SubprocessEnvironment, -) -> SubprocessEncodingEnvironment: - return SubprocessEncodingEnvironment( - lang=subprocess_environment.get_options().lang, - lc_all=subprocess_environment.get_options().lc_all, - ) + def invocation_environment(self) -> Dict[str, str]: + return {"LANG": self.lang or "", "LC_ALL": self.lc_all or ""} def rules(): diff --git a/src/python/pants/backend/python/typecheck/mypy/rules.py b/src/python/pants/backend/python/typecheck/mypy/rules.py index eaaf36381bf..d5cd3ed2383 100644 --- a/src/python/pants/backend/python/typecheck/mypy/rules.py +++ b/src/python/pants/backend/python/typecheck/mypy/rules.py @@ -16,7 +16,7 @@ UnstrippedPythonSourcesRequest, ) from pants.backend.python.subsystems import python_native_code, subprocess_environment -from pants.backend.python.subsystems.subprocess_environment import SubprocessEncodingEnvironment +from pants.backend.python.subsystems.subprocess_environment import SubprocessEnvironment from pants.backend.python.target_types import PythonSources from pants.backend.python.typecheck.mypy.subsystem import MyPy from pants.core.goals.typecheck import TypecheckRequest, TypecheckResult, TypecheckResults @@ -66,7 +66,7 @@ async def mypy_lint( request: MyPyRequest, mypy: MyPy, python_setup: PythonSetup, - subprocess_encoding_environment: SubprocessEncodingEnvironment, + subprocess_environment: SubprocessEnvironment, ) -> TypecheckResults: if mypy.skip: return TypecheckResults() @@ -82,14 +82,14 @@ async def mypy_lint( Pex, PexRequest( output_filename="mypy.pex", - requirements=PexRequirements(mypy.get_requirement_specs()), + requirements=PexRequirements(mypy.all_requirements), # NB: This only determines what MyPy is run with. The user can specify what version # their code is with `--python-version`. See # https://mypy.readthedocs.io/en/stable/config_file.html#platform-configuration. We do # not auto-configure this for simplicity and to avoid Pants magically setting values for # users. - interpreter_constraints=PexInterpreterConstraints(mypy.default_interpreter_constraints), - entry_point=mypy.get_entry_point(), + interpreter_constraints=PexInterpreterConstraints(mypy.interpreter_constraints), + entry_point=mypy.entry_point, ), ) config_digest_request = Get( @@ -119,7 +119,7 @@ async def mypy_lint( process = pex.create_process( python_setup=python_setup, - subprocess_encoding_environment=subprocess_encoding_environment, + subprocess_environment=subprocess_environment, pex_path=pex.output_filename, pex_args=generate_args(mypy, file_list_path=file_list_path), input_digest=merged_input_files, diff --git a/src/python/pants/binaries/binary_util.py b/src/python/pants/binaries/binary_util.py index 8d9d7f355cf..fc960ce812b 100644 --- a/src/python/pants/binaries/binary_util.py +++ b/src/python/pants/binaries/binary_util.py @@ -287,7 +287,7 @@ def create(cls) -> "BinaryUtil": @classmethod def _create_for_cls(cls, binary_util_cls): # NB: We read global bootstrap options, but through our own scoped options instance. - options = cls.global_instance().get_options() + options = cls.global_instance().options binary_tool_fetcher = BinaryToolFetcher( bootstrap_dir=options.pants_bootstrapdir, timeout_secs=options.binaries_fetch_timeout_secs, diff --git a/src/python/pants/core/util_rules/external_tool.py b/src/python/pants/core/util_rules/external_tool.py index 8545d251bf8..d7130d90c19 100644 --- a/src/python/pants/core/util_rules/external_tool.py +++ b/src/python/pants/core/util_rules/external_tool.py @@ -4,7 +4,7 @@ import textwrap from abc import abstractmethod from dataclasses import dataclass -from typing import List +from typing import List, Tuple, cast from pants.core.util_rules.archive import ExtractedDigest, MaybeExtractable from pants.engine.fs import Digest, DownloadFile @@ -100,20 +100,20 @@ def register_options(cls, register): help_str = textwrap.dedent( f""" - Known versions to verify downloads against. + Known versions to verify downloads against. - Each element is a pipe-separated string of `version|platform|sha256|length`, where: + Each element is a pipe-separated string of `version|platform|sha256|length`, where: - - `version` is the version string - - `platform` is one of [{','.join(Platform.__members__.keys())}], - - `sha256` is the 64-character hex representation of the expected sha256 - digest of the download file, as emitted by `shasum -a 256` - - `length` is the expected length of the download file in bytes + - `version` is the version string + - `platform` is one of [{','.join(Platform.__members__.keys())}], + - `sha256` is the 64-character hex representation of the expected sha256 + digest of the download file, as emitted by `shasum -a 256` + - `length` is the expected length of the download file in bytes - E.g., `3.1.2|darwin|6d0f18cd84b918c7b3edd0203e75569e0c7caecb1367bbbe409b44e28514f5be|42813`. + E.g., `3.1.2|darwin|6d0f18cd84b918c7b3edd0203e75569e0c7caecb1367bbbe409b44e28514f5be|42813`. - Values are space-stripped, so pipes can be indented for readability if necessary. - """ + Values are space-stripped, so pipes can be indented for readability if necessary. + """ ) # Note that you can compute the length and sha256 conveniently with: # `curl -L $URL | tee >(wc -c) >(shasum -a 256) >/dev/null` @@ -126,6 +126,14 @@ def register_options(cls, register): help=help_str, ) + @property + def version(self) -> str: + return cast(str, self.options.version) + + @property + def known_versions(self) -> Tuple[str, ...]: + return tuple(self.options.known_versions) + @abstractmethod def generate_url(self, plat: Platform) -> str: """Returns the URL for the given version of the tool, runnable on the given os+arch. @@ -145,28 +153,27 @@ def generate_exe(self, plat: Platform) -> str: def get_request(self, plat: Platform) -> ExternalToolRequest: """Generate a request for this tool.""" - version = self.get_options().version - known_versions = self.get_options().known_versions - for known_version in known_versions: + for known_version in self.known_versions: try: ver, plat_val, sha256, length = (x.strip() for x in known_version.split("|")) except ValueError: raise ExternalToolError( - f"Bad value for --known-versions (see {self.get_options().pants_bin_name} " + f"Bad value for --known-versions (see {self.options.pants_bin_name} " f"help-advanced {self.options_scope}): {known_version}" ) - if plat_val == plat.value and ver == version: + if plat_val == plat.value and ver == self.version: digest = Digest(fingerprint=sha256, serialized_bytes_length=int(length)) try: url = self.generate_url(plat) exe = self.generate_exe(plat) or url.rsplit("/", 1)[-1] except ExternalToolError as e: raise ExternalToolError( - f"Couldn't find {self.name} version {version} on {plat.value}" + f"Couldn't find {self.name} version {self.version} on {plat.value}" ) from e return ExternalToolRequest(DownloadFile(url=url, expected_digest=digest), exe) raise UnknownVersion( - f"No known version of {self.name} {version} for {plat.value} found in {known_versions}" + f"No known version of {self.name} {self.version} for {plat.value} found in " + f"{self.known_versions}" ) diff --git a/src/python/pants/core/util_rules/external_tool_test.py b/src/python/pants/core/util_rules/external_tool_test.py index c10e5a04cfa..54b860af34e 100644 --- a/src/python/pants/core/util_rules/external_tool_test.py +++ b/src/python/pants/core/util_rules/external_tool_test.py @@ -33,11 +33,10 @@ def generate_url(self, plat: Platform) -> str: plat_str = "linux-x86_64" else: raise ExternalToolError() - version = self.get_options().version - return f"https://foobar.org/bin/v{version}/foobar-{version}-{plat_str}.tgz" + return f"https://foobar.org/bin/v{self.version}/foobar-{self.version}-{plat_str}.tgz" def generate_exe(self, plat: Platform) -> str: - return f"foobar-{self.get_options().version}/bin/foobar" + return f"foobar-{self.version}/bin/foobar" def test_generate_request() -> None: diff --git a/src/python/pants/core/util_rules/pants_bin.py b/src/python/pants/core/util_rules/pants_bin.py index 73208478ed7..8a85d8d2b31 100644 --- a/src/python/pants/core/util_rules/pants_bin.py +++ b/src/python/pants/core/util_rules/pants_bin.py @@ -27,7 +27,7 @@ def render_command( @rule def pants_bin(global_options: GlobalOptions) -> PantsBin: - pants_bin_name = cast(str, global_options.get_options().pants_bin_name) + pants_bin_name = cast(str, global_options.options.pants_bin_name) return PantsBin(name=pants_bin_name) diff --git a/src/python/pants/engine/internals/options_parsing.py b/src/python/pants/engine/internals/options_parsing.py index 0b0cc1182b1..11a30e7877d 100644 --- a/src/python/pants/engine/internals/options_parsing.py +++ b/src/python/pants/engine/internals/options_parsing.py @@ -37,7 +37,7 @@ def scope_options(scope: Scope, options: _Options) -> ScopedOptions: @rule def log_level(global_options: GlobalOptions) -> LogLevel: - log_level: LogLevel = global_options.get_options().level + log_level: LogLevel = global_options.options.level return log_level diff --git a/src/python/pants/goal/run_tracker.py b/src/python/pants/goal/run_tracker.py index 35c4fde3eff..8fa35f40b73 100644 --- a/src/python/pants/goal/run_tracker.py +++ b/src/python/pants/goal/run_tracker.py @@ -174,10 +174,10 @@ def __init__(self, *args, **kwargs): self.outcomes = {} # Number of threads for foreground work. - self._num_foreground_workers = self.get_options().num_foreground_workers + self._num_foreground_workers = self.options.num_foreground_workers # Number of threads for background work. - self._num_background_workers = self.get_options().num_background_workers + self._num_background_workers = self.options.num_background_workers # self._threadlocal.current_workunit contains the current workunit for the calling thread. # Note that multiple threads may share a name (e.g., all the threads in a pool). @@ -239,13 +239,13 @@ def start(self, all_options, run_start_time=None): # Initialize the run. - info_dir = os.path.join(self.get_options().pants_workdir, self.options_scope) + info_dir = os.path.join(self.options.pants_workdir, self.options_scope) self.run_info_dir = os.path.join(info_dir, self.run_id) self.run_info = RunInfo(os.path.join(self.run_info_dir, "info")) self.run_info.add_basic_info(self.run_id, self._run_timestamp) self.run_info.add_info("cmd_line", self._cmd_line) - if self.get_options().parent_build_id: - self.run_info.add_info("parent_build_id", self.get_options().parent_build_id) + if self.options.parent_build_id: + self.run_info.add_info("parent_build_id", self.options.parent_build_id) # Create a 'latest' symlink, after we add_infos, so we're guaranteed that the file exists. link_to_latest = os.path.join(os.path.dirname(self.run_info_dir), "latest") @@ -365,7 +365,7 @@ def new_workunit_under_parent(self, name, parent, labels=None, cmd="", log_confi @property def _stats_version(self) -> int: - stats_version: int = self.get_options().stats_version + stats_version: int = self.options.stats_version return stats_version def log(self, level, *msg_elements): @@ -499,13 +499,13 @@ def store_stats(self): stats = self._stats() # Write stats to user-defined json file. - stats_json_file_name = self.get_options().stats_local_json_file + stats_json_file_name = self.options.stats_local_json_file if stats_json_file_name: self.write_stats_to_json(stats_json_file_name, stats) # Upload to remote stats db. - stats_upload_urls = copy.copy(self.get_options().stats_upload_urls) - timeout = self.get_options().stats_upload_timeout + stats_upload_urls = copy.copy(self.options.stats_upload_urls) + timeout = self.options.stats_upload_timeout for stats_url, auth_provider in stats_upload_urls.items(): self.post_stats( stats_url, @@ -610,7 +610,7 @@ def shutdown_worker_pool(self): def _get_options_to_record(self) -> dict: recorded_options = {} - for scope in self.get_options().stats_option_scopes_to_record: + for scope in self.options.stats_option_scopes_to_record: scope_and_maybe_option = scope.split("^") recorded_options[scope] = self._get_option_to_record(*scope_and_maybe_option) return recorded_options diff --git a/src/python/pants/notes/1.17.x.rst b/src/python/pants/notes/1.17.x.rst index 213edd8eaa8..52b8fccbbd1 100644 --- a/src/python/pants/notes/1.17.x.rst +++ b/src/python/pants/notes/1.17.x.rst @@ -82,7 +82,7 @@ Bugfixes * Fix dependency cycle between `backend/native/subsystems` and `backend/python/subsystems` (#7793) `PR #7793 `_ -* Fix `create_subprocess_encoding_environment` rule. (#7789) +* Fix `create_subprocess_environment` rule. (#7789) `PR #7789 `_ New Features diff --git a/src/python/pants/process/subprocess.py b/src/python/pants/process/subprocess.py index fbd163407fc..ba0d37e79a9 100644 --- a/src/python/pants/process/subprocess.py +++ b/src/python/pants/process/subprocess.py @@ -17,8 +17,7 @@ class Factory(Subsystem): options_scope = "subprocess" def create(self): - options = self.global_instance().get_options() - return Subprocess(options.pants_subprocessdir) + return Subprocess(self.global_instance().options.pants_subprocessdir) def __init__(self, pants_subprocess_dir): self._pants_subprocess_dir = pants_subprocess_dir diff --git a/src/python/pants/python/python_setup.py b/src/python/pants/python/python_setup.py index c3e54087656..c19648a3d42 100644 --- a/src/python/pants/python/python_setup.py +++ b/src/python/pants/python/python_setup.py @@ -145,44 +145,46 @@ def requirement_constraints(self) -> Optional[str]: """Path to constraint file.""" return cast(Optional[str], self.options.requirement_constraints) + @property + def resolve_all_constraints(self) -> bool: + return cast(bool, self.options.resolve_all_constraints) + @memoized_property def interpreter_search_paths(self): - return self.expand_interpreter_search_paths(self.get_options().interpreter_search_paths) + return self.expand_interpreter_search_paths(self.options.interpreter_search_paths) @property def platforms(self): - return self.get_options().platforms + return self.options.platforms @property def interpreter_cache_dir(self): - return self.get_options().interpreter_cache_dir or os.path.join( - self.scratch_dir, "interpreters" - ) + return self.options.interpreter_cache_dir or os.path.join(self.scratch_dir, "interpreters") @property def resolver_cache_dir(self): - return self.get_options().resolver_cache_dir or os.path.join( + return self.options.resolver_cache_dir or os.path.join( self.scratch_dir, "resolved_requirements" ) @property def resolver_allow_prereleases(self): - return self.get_options().resolver_allow_prereleases + return self.options.resolver_allow_prereleases @property def manylinux(self): - manylinux = self.get_options().resolver_manylinux + manylinux = self.options.resolver_manylinux if manylinux is None or manylinux.lower() in ("false", "no", "none"): return None return manylinux @property def resolver_jobs(self): - return self.get_options().resolver_jobs + return self.options.resolver_jobs @property def scratch_dir(self): - return os.path.join(self.get_options().pants_workdir, *self.options_scope.split(".")) + return os.path.join(self.options.pants_workdir, *self.options_scope.split(".")) def compatibility_or_constraints( self, compatibility: Optional[Iterable[str]] @@ -191,7 +193,7 @@ def compatibility_or_constraints( If interpreter constraints are supplied by the CLI flag, return those only. """ - if self.get_options().is_flagged("interpreter_constraints"): + if self.options.is_flagged("interpreter_constraints"): return self.interpreter_constraints return tuple(compatibility or self.interpreter_constraints) diff --git a/src/python/pants/subsystem/subsystem.py b/src/python/pants/subsystem/subsystem.py index 58066830acd..528cb3f8b17 100644 --- a/src/python/pants/subsystem/subsystem.py +++ b/src/python/pants/subsystem/subsystem.py @@ -7,6 +7,7 @@ from dataclasses import dataclass from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, Type, TypeVar, Union, cast +from pants.base.deprecated import deprecated from pants.option.option_value_container import OptionValueContainer from pants.option.optionable import Optionable, OptionableFactory from pants.option.options import Options @@ -203,6 +204,9 @@ def options(self) -> OptionValueContainer: """ return self._scoped_options + @deprecated( + removal_version="2.1.0.dev0", hint_message="Use the property `self.options` instead." + ) def get_options(self) -> OptionValueContainer: """Returns the option values for this subsystem's scope. diff --git a/tests/python/pants_test/init/test_plugin_resolver.py b/tests/python/pants_test/init/test_plugin_resolver.py index abd1a18c3f5..d571f183559 100644 --- a/tests/python/pants_test/init/test_plugin_resolver.py +++ b/tests/python/pants_test/init/test_plugin_resolver.py @@ -16,8 +16,6 @@ from pants.backend.python.rules import download_pex_bin, pex from pants.backend.python.rules.pex import Pex, PexRequest, PexRequirements from pants.backend.python.subsystems import python_native_code, subprocess_environment -from pants.backend.python.subsystems.python_native_code import PexBuildEnvironment -from pants.backend.python.subsystems.subprocess_environment import SubprocessEncodingEnvironment from pants.core.util_rules import archive, external_tool from pants.engine.fs import CreateDigest, Digest, FileContent, MergeDigests, Snapshot from pants.engine.process import Process, ProcessResult @@ -62,8 +60,6 @@ def _create_pex(self) -> Pex: requirements=PexRequirements(["setuptools==44.0.0", "wheel==0.34.2"]), ), create_options_bootstrapper(args=["--backend-packages=pants.backend.python"]), - SubprocessEncodingEnvironment(None, None), - PexBuildEnvironment(tuple(), tuple()), ), ) From e2a11c5c3e8e0126cb80b3961eb806360f74684a Mon Sep 17 00:00:00 2001 From: Eric Arellano Date: Tue, 28 Jul 2020 12:00:48 -0700 Subject: [PATCH 2/2] Don't update release notes [ci skip-rust] [ci skip-build-wheels] --- src/python/pants/notes/1.17.x.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python/pants/notes/1.17.x.rst b/src/python/pants/notes/1.17.x.rst index 52b8fccbbd1..213edd8eaa8 100644 --- a/src/python/pants/notes/1.17.x.rst +++ b/src/python/pants/notes/1.17.x.rst @@ -82,7 +82,7 @@ Bugfixes * Fix dependency cycle between `backend/native/subsystems` and `backend/python/subsystems` (#7793) `PR #7793 `_ -* Fix `create_subprocess_environment` rule. (#7789) +* Fix `create_subprocess_encoding_environment` rule. (#7789) `PR #7789 `_ New Features