diff --git a/build-support/bin/BUILD b/build-support/bin/BUILD index 388bab81ff6..6bd3afc3298 100644 --- a/build-support/bin/BUILD +++ b/build-support/bin/BUILD @@ -12,22 +12,22 @@ python_tests( timeout=90, ) -python_binary( +pex_binary( name = 'bootstrap_and_deploy_ci_pants_pex', sources = ['bootstrap_and_deploy_ci_pants_pex.py'], ) -python_binary( +pex_binary( name = 'check_banned_imports', sources = ['check_banned_imports.py'], ) -python_binary( +pex_binary( name = 'check_inits', sources = ['check_inits.py'], ) -python_binary( +pex_binary( name = 'ci', sources = ['ci.py'], ) @@ -37,17 +37,17 @@ python_library( sources = ['common.py'], ) -python_binary( +pex_binary( name = 'deploy_to_s3', sources = ['deploy_to_s3.py'], ) -python_binary( +pex_binary( name = 'generate_travis_yml', sources = ['generate_travis_yml.py'], ) -python_binary( +pex_binary( name = 'generate_docs', sources = ['generate_docs.py'], dependencies = [ @@ -60,23 +60,23 @@ resources( sources = ['docs_templates/*.mustache'], ) -python_binary( +pex_binary( name = 'get_rbe_token', sources = ['get_rbe_token.py'], ) -python_binary( +pex_binary( name='reversion', sources=["reversion.py"], ) -python_binary( +pex_binary( name = 'shellcheck', sources = ['shellcheck.py'], ) # TODO: rename this to `release.py` once done porting Bash to Python. -python_binary( +pex_binary( name = "packages", sources = ["packages.py"], ) diff --git a/examples/src/python/example/hello/main/BUILD b/examples/src/python/example/hello/main/BUILD index d9dc9fae157..9687b683b33 100644 --- a/examples/src/python/example/hello/main/BUILD +++ b/examples/src/python/example/hello/main/BUILD @@ -2,7 +2,7 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). # Like Hello world, but built with Pants. -python_binary( +pex_binary( dependencies=[ 'examples/src/python/example/hello/greet:greet', ':lib', diff --git a/src/python/pants/backend/python/goals/package_python_binary.py b/src/python/pants/backend/python/goals/package_pex_binary.py similarity index 73% rename from src/python/pants/backend/python/goals/package_python_binary.py rename to src/python/pants/backend/python/goals/package_pex_binary.py index 8b0880382f5..2157d132edb 100644 --- a/src/python/pants/backend/python/goals/package_python_binary.py +++ b/src/python/pants/backend/python/goals/package_pex_binary.py @@ -6,17 +6,16 @@ from typing import Tuple, cast from pants.backend.python.target_types import ( - PexAlwaysWriteCache, - PexEmitWarnings, - PexIgnoreErrors, - PexInheritPath, - PexShebang, - PexZipSafe, - PythonBinaryDefaults, - PythonBinarySources, - PythonEntryPoint, + PexAlwaysWriteCacheField, + PexBinaryDefaults, + PexBinarySources, + PexEmitWarningsField, + PexEntryPointField, + PexIgnoreErrorsField, + PexInheritPathField, ) -from pants.backend.python.target_types import PythonPlatforms as PythonPlatformsField +from pants.backend.python.target_types import PexPlatformsField as PythonPlatformsField +from pants.backend.python.target_types import PexShebangField, PexZipSafeField from pants.backend.python.util_rules.pex import PexPlatforms, TwoStepPex from pants.backend.python.util_rules.pex_from_targets import ( PexFromTargetsRequest, @@ -40,28 +39,26 @@ @dataclass(frozen=True) -class PythonBinaryFieldSet(PackageFieldSet, BinaryFieldSet, RunFieldSet): - required_fields = (PythonEntryPoint, PythonBinarySources) +class PexBinaryFieldSet(PackageFieldSet, BinaryFieldSet, RunFieldSet): + required_fields = (PexEntryPointField, PexBinarySources) - sources: PythonBinarySources - entry_point: PythonEntryPoint + sources: PexBinarySources + entry_point: PexEntryPointField output_path: OutputPathField - always_write_cache: PexAlwaysWriteCache - emit_warnings: PexEmitWarnings - ignore_errors: PexIgnoreErrors - inherit_path: PexInheritPath - shebang: PexShebang - zip_safe: PexZipSafe + always_write_cache: PexAlwaysWriteCacheField + emit_warnings: PexEmitWarningsField + ignore_errors: PexIgnoreErrorsField + inherit_path: PexInheritPathField + shebang: PexShebangField + zip_safe: PexZipSafeField platforms: PythonPlatformsField - def generate_additional_args( - self, python_binary_defaults: PythonBinaryDefaults - ) -> Tuple[str, ...]: + def generate_additional_args(self, pex_binary_defaults: PexBinaryDefaults) -> Tuple[str, ...]: args = [] if self.always_write_cache.value is True: args.append("--always-write-cache") - if self.emit_warnings.value_or_global_default(python_binary_defaults) is False: + if self.emit_warnings.value_or_global_default(pex_binary_defaults) is False: args.append("--no-emit-warnings") if self.ignore_errors.value is True: args.append("--ignore-errors") @@ -75,9 +72,9 @@ def generate_additional_args( @rule(level=LogLevel.DEBUG) -async def package_python_binary( - field_set: PythonBinaryFieldSet, - python_binary_defaults: PythonBinaryDefaults, +async def package_pex_binary( + field_set: PexBinaryFieldSet, + pex_binary_defaults: PexBinaryDefaults, global_options: GlobalOptions, ) -> BuiltPackage: entry_point = field_set.entry_point.value @@ -97,7 +94,7 @@ async def package_python_binary( SourceRootRequest, SourceRootRequest.for_file(entry_point_path), ) - entry_point = PythonBinarySources.translate_source_file_to_entry_point( + entry_point = PexBinarySources.translate_source_file_to_entry_point( os.path.relpath(entry_point_path, source_root.path) ) @@ -115,7 +112,7 @@ async def package_python_binary( entry_point=entry_point, platforms=PexPlatforms.create_from_platforms_field(field_set.platforms), output_filename=output_filename, - additional_args=field_set.generate_additional_args(python_binary_defaults), + additional_args=field_set.generate_additional_args(pex_binary_defaults), ) ), ) @@ -123,7 +120,7 @@ async def package_python_binary( @rule(level=LogLevel.DEBUG) -async def create_python_binary(field_set: PythonBinaryFieldSet) -> CreatedBinary: +async def create_pex_binary(field_set: PexBinaryFieldSet) -> CreatedBinary: pex = await Get(BuiltPackage, PackageFieldSet, field_set) return CreatedBinary(pex.digest, cast(str, pex.artifacts[0].relpath)) @@ -131,6 +128,6 @@ async def create_python_binary(field_set: PythonBinaryFieldSet) -> CreatedBinary def rules(): return [ *collect_rules(), - UnionRule(PackageFieldSet, PythonBinaryFieldSet), - UnionRule(BinaryFieldSet, PythonBinaryFieldSet), + UnionRule(PackageFieldSet, PexBinaryFieldSet), + UnionRule(BinaryFieldSet, PexBinaryFieldSet), ] 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 a48b998338a..fd9be04f752 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 @@ -10,11 +10,11 @@ import pytest from pants.backend.python.dependency_inference import rules as dependency_inference_rules -from pants.backend.python.goals import package_python_binary, pytest_runner +from pants.backend.python.goals import package_pex_binary, pytest_runner from pants.backend.python.goals.coverage_py import create_coverage_config from pants.backend.python.goals.pytest_runner import PythonTestFieldSet from pants.backend.python.target_types import ( - PythonBinary, + PexBinary, PythonLibrary, PythonRequirementLibrary, PythonTests, @@ -40,12 +40,12 @@ def rule_runner() -> RuleRunner: *dependency_inference_rules.rules(), # For conftest detection. *distdir.rules(), *binary.rules(), - *package_python_binary.rules(), + *package_pex_binary.rules(), get_filtered_environment, QueryRule(TestResult, (PythonTestFieldSet,)), QueryRule(TestDebugRequest, (PythonTestFieldSet,)), ], - target_types=[PythonBinary, PythonLibrary, PythonTests, PythonRequirementLibrary], + target_types=[PexBinary, PythonLibrary, PythonTests, PythonRequirementLibrary], ) @@ -110,13 +110,13 @@ def create_test_target( return tgt -def create_python_binary_target(rule_runner: RuleRunner, source_file: FileContent) -> None: +def create_pex_binary_target(rule_runner: RuleRunner, source_file: FileContent) -> None: rule_runner.create_file(source_file.path, source_file.content.decode()) rule_runner.add_to_build_file( relpath=PACKAGE, target=dedent( f"""\ - python_binary( + pex_binary( name='bin', sources=['{PurePath(source_file.path).name}'], ) @@ -442,7 +442,7 @@ def test_args(): def test_runtime_package_dependency(rule_runner: RuleRunner) -> None: - create_python_binary_target(rule_runner, BINARY_SOURCE) + create_pex_binary_target(rule_runner, BINARY_SOURCE) rule_runner.create_file( f"{PACKAGE}/test_binary_call.py", dedent( diff --git a/src/python/pants/backend/python/goals/run_python_binary.py b/src/python/pants/backend/python/goals/run_pex_binary.py similarity index 89% rename from src/python/pants/backend/python/goals/run_python_binary.py rename to src/python/pants/backend/python/goals/run_pex_binary.py index eeaccbdecde..daf17f5c3da 100644 --- a/src/python/pants/backend/python/goals/run_python_binary.py +++ b/src/python/pants/backend/python/goals/run_pex_binary.py @@ -3,8 +3,8 @@ import os -from pants.backend.python.goals.package_python_binary import PythonBinaryFieldSet -from pants.backend.python.target_types import PythonBinaryDefaults, PythonBinarySources +from pants.backend.python.goals.package_pex_binary import PexBinaryFieldSet +from pants.backend.python.target_types import PexBinaryDefaults, PexBinarySources from pants.backend.python.util_rules.pex import Pex, PexRequest from pants.backend.python.util_rules.pex_environment import PexEnvironment from pants.backend.python.util_rules.pex_from_targets import PexFromTargetsRequest @@ -23,9 +23,9 @@ @rule(level=LogLevel.DEBUG) -async def create_python_binary_run_request( - field_set: PythonBinaryFieldSet, - python_binary_defaults: PythonBinaryDefaults, +async def create_pex_binary_run_request( + field_set: PexBinaryFieldSet, + pex_binary_defaults: PexBinaryDefaults, pex_env: PexEnvironment, ) -> RunRequest: entry_point = field_set.entry_point.value @@ -45,7 +45,7 @@ async def create_python_binary_run_request( SourceRootRequest, SourceRootRequest.for_file(entry_point_path), ) - entry_point = PythonBinarySources.translate_source_file_to_entry_point( + entry_point = PexBinarySources.translate_source_file_to_entry_point( os.path.relpath(entry_point_path, source_root.path) ) transitive_targets = await Get(TransitiveTargets, TransitiveTargetsRequest([field_set.address])) @@ -70,7 +70,7 @@ async def create_python_binary_run_request( PexRequest( output_filename=output_filename, interpreter_constraints=requirements_pex_request.interpreter_constraints, - additional_args=field_set.generate_additional_args(python_binary_defaults), + additional_args=field_set.generate_additional_args(pex_binary_defaults), internal_only=True, # Note that the entry point file is not in the Pex itself, but on the # PEX_PATH. This works fine! @@ -105,4 +105,4 @@ def in_chroot(relpath: str) -> str: def rules(): - return [*collect_rules(), UnionRule(RunFieldSet, PythonBinaryFieldSet)] + return [*collect_rules(), UnionRule(RunFieldSet, PexBinaryFieldSet)] diff --git a/src/python/pants/backend/python/goals/run_python_binary_integration_test.py b/src/python/pants/backend/python/goals/run_pex_binary_integration_test.py similarity index 87% rename from src/python/pants/backend/python/goals/run_python_binary_integration_test.py rename to src/python/pants/backend/python/goals/run_pex_binary_integration_test.py index c8055578028..0800875564d 100644 --- a/src/python/pants/backend/python/goals/run_python_binary_integration_test.py +++ b/src/python/pants/backend/python/goals/run_pex_binary_integration_test.py @@ -11,13 +11,13 @@ @pytest.mark.parametrize( "tgt_content", [ - "python_binary(sources=['app.py'])", - "python_binary(sources=['app.py'], entry_point='project.app')", - "python_binary(sources=['app.py'], entry_point='project.app:main')", + "pex_binary(sources=['app.py'])", + "pex_binary(sources=['app.py'], entry_point='project.app')", + "pex_binary(sources=['app.py'], entry_point='project.app:main')", ], ) def test_run_sample_script(tgt_content: str) -> None: - """Test that we properly run a `python_binary` target. + """Test that we properly run a `pex_binary` target. This checks a few things: - We can handle source roots. diff --git a/src/python/pants/backend/python/goals/setup_py.py b/src/python/pants/backend/python/goals/setup_py.py index 425fc296fda..a74983f0c58 100644 --- a/src/python/pants/backend/python/goals/setup_py.py +++ b/src/python/pants/backend/python/goals/setup_py.py @@ -14,7 +14,7 @@ from pants.backend.python.macros.python_artifact import PythonArtifact from pants.backend.python.subsystems.setuptools import Setuptools from pants.backend.python.target_types import ( - PythonEntryPoint, + PexEntryPointField, PythonInterpreterCompatibility, PythonProvidesField, PythonRequirementsField, @@ -620,7 +620,7 @@ async def generate_chroot(request: SetupPyChrootRequest) -> SetupPyChroot: Targets, UnparsedAddressInputs(key_to_binary_spec.values(), owning_address=target.address) ) for key, binary in zip(key_to_binary_spec.keys(), binaries): - binary_entry_point = binary.get(PythonEntryPoint).value + binary_entry_point = binary.get(PexEntryPointField).value if not binary_entry_point: raise InvalidEntryPoint( f"The binary {key} exported by {target.address} is not a valid entry point." diff --git a/src/python/pants/backend/python/goals/setup_py_test.py b/src/python/pants/backend/python/goals/setup_py_test.py index 23cb175d69d..eee0f8538db 100644 --- a/src/python/pants/backend/python/goals/setup_py_test.py +++ b/src/python/pants/backend/python/goals/setup_py_test.py @@ -34,7 +34,7 @@ ) from pants.backend.python.macros.python_artifact import PythonArtifact from pants.backend.python.target_types import ( - PythonBinary, + PexBinary, PythonDistribution, PythonLibrary, PythonRequirementLibrary, @@ -56,7 +56,7 @@ def create_setup_py_rule_runner(*, rules: Iterable) -> RuleRunner: return RuleRunner( rules=rules, target_types=[ - PythonBinary, + PexBinary, PythonDistribution, PythonLibrary, PythonRequirementLibrary, @@ -149,7 +149,7 @@ def test_generate_chroot(chroot_rule_runner: RuleRunner) -> None: """ python_library() - python_binary(name="bin", entry_point="foo.qux.bin") + pex_binary(name="bin", entry_point="foo.qux.bin") """ ), ) @@ -226,7 +226,7 @@ def test_invalid_binary(chroot_rule_runner: RuleRunner) -> None: textwrap.dedent( """ python_library(name='not_a_binary', sources=[]) - python_binary(name='no_entrypoint') + pex_binary(name='no_entrypoint') python_distribution( name='invalid_bin1', provides=setup_py( diff --git a/src/python/pants/backend/python/macros/python_artifact.py b/src/python/pants/backend/python/macros/python_artifact.py index 3aed0e03d1a..4005b5d9c41 100644 --- a/src/python/pants/backend/python/macros/python_artifact.py +++ b/src/python/pants/backend/python/macros/python_artifact.py @@ -52,9 +52,9 @@ def with_binaries(self, *args, **kw): my_command = ':my_library_bin' ) - This adds a console_script entry_point for the python_binary target + This adds a console_script entry_point for the pex_binary target pointed at by :my_library_bin. Currently only supports - python_binaries that specify entry_point explicitly instead of source. + pex_binaries that specify entry_point explicitly instead of source. Also can take a dictionary, e.g. with_binaries({'my-command': ':my_library_bin'}) diff --git a/src/python/pants/backend/python/register.py b/src/python/pants/backend/python/register.py index 3120c22f366..c1a819ed4af 100644 --- a/src/python/pants/backend/python/register.py +++ b/src/python/pants/backend/python/register.py @@ -9,10 +9,10 @@ from pants.backend.python.dependency_inference import rules as dependency_inference_rules from pants.backend.python.goals import ( coverage_py, - package_python_binary, + package_pex_binary, pytest_runner, repl, - run_python_binary, + run_pex_binary, setup_py, ) from pants.backend.python.macros.pants_requirement import PantsRequirement @@ -21,6 +21,7 @@ from pants.backend.python.macros.python_requirements import PythonRequirements from pants.backend.python.subsystems import python_native_code from pants.backend.python.target_types import ( + PexBinary, PythonBinary, PythonDistribution, PythonLibrary, @@ -69,10 +70,10 @@ def rules(): *pex_environment.rules(), *pex_from_targets.rules(), *pytest_runner.rules(), - *package_python_binary.rules(), + *package_pex_binary.rules(), *python_native_code.rules(), *repl.rules(), - *run_python_binary.rules(), + *run_pex_binary.rules(), *target_type_rules(), *setup_py.rules(), ) @@ -80,6 +81,7 @@ def rules(): def target_types(): return [ + PexBinary, PythonBinary, PythonDistribution, PythonLibrary, diff --git a/src/python/pants/backend/python/target_types.py b/src/python/pants/backend/python/target_types.py index 5cf3d5f723a..e18a5bffcf1 100644 --- a/src/python/pants/backend/python/target_types.py +++ b/src/python/pants/backend/python/target_types.py @@ -5,13 +5,13 @@ import logging import os.path from textwrap import dedent -from typing import Iterable, Optional, Tuple, Union, cast +from typing import Any, Dict, Iterable, Optional, Tuple, Union, cast from pkg_resources import Requirement from pants.backend.python.macros.python_artifact import PythonArtifact from pants.backend.python.subsystems.pytest import PyTest -from pants.base.deprecated import warn_or_error +from pants.base.deprecated import resolve_conflicting_options, warn_or_error from pants.core.goals.package import OutputPathField from pants.engine.addresses import Address, Addresses, UnparsedAddressInputs from pants.engine.rules import Get, collect_rules, rule @@ -36,6 +36,7 @@ Target, WrappedTarget, ) +from pants.engine.unions import UnionMembership from pants.option.subsystem import Subsystem from pants.python.python_requirement import PythonRequirement from pants.python.python_setup import PythonSetup @@ -77,14 +78,16 @@ def value_or_global_default(self, python_setup: PythonSetup) -> Tuple[str, ...]: # ----------------------------------------------------------------------------------------------- -# `python_binary` target +# `pex_binary` target # ----------------------------------------------------------------------------------------------- -class PythonBinaryDefaults(Subsystem): - """Default settings for creating Python executables.""" +class PexBinaryDefaults(Subsystem): + """Default settings for creating PEX executables.""" - options_scope = "python-binary" + options_scope = "pex-binary" + deprecated_options_scope = "python-binary" + deprecated_options_scope_removal_version = "2.1.0.dev0" @classmethod def register_options(cls, register): @@ -96,17 +99,38 @@ def register_options(cls, register): default=True, help=( "Whether built PEX binaries should emit pex warnings at runtime by default. " - "Can be over-ridden by specifying the `emit_warnings` parameter of individual " - "`python_binary` targets" + "Can be overridden by specifying the `emit_warnings` parameter of individual " + "`pex_binary` targets" + ), + ) + register( + "--emit-warnings", + advanced=True, + type=bool, + default=True, + help=( + "Whether built PEX binaries should emit PEX warnings at runtime by default. " + "Can be overridden by specifying the `emit_warnings` parameter of individual " + "`pex_binary` targets" ), ) @property - def pex_emit_warnings(self) -> bool: - return cast(bool, self.options.pex_emit_warnings) + def emit_warnings(self) -> bool: + return cast( + bool, + resolve_conflicting_options( + old_option="pex_emit_warnings", + new_option="emit_warnings", + old_scope=self.options_scope, + new_scope=self.deprecated_options_scope, + old_container=self.options, + new_container=self.options, + ), + ) -class PythonBinarySources(PythonSources): +class PexBinarySources(PythonSources): """A single file containing the executable, such as ['app.py']. You can leave this off if you include the executable file in one of this target's @@ -124,11 +148,11 @@ def translate_source_file_to_entry_point(stripped_source_path: str) -> str: return module_base.replace(os.path.sep, ".") -class PythonBinaryDependencies(Dependencies): +class PexBinaryDependencies(Dependencies): supports_transitive_excludes = True -class PythonEntryPoint(StringField): +class PexEntryPointField(StringField): """The default entry point for the binary. If omitted, Pants will use the module name from the `sources` field, e.g. `project/app.py` will @@ -138,7 +162,7 @@ class PythonEntryPoint(StringField): alias = "entry_point" -class PythonPlatforms(StringOrStringSequenceField): +class PexPlatformsField(StringOrStringSequenceField): """The platforms the built PEX should be compatible with. This defaults to the current platform, but can be overridden to different platforms. You can @@ -155,7 +179,7 @@ class PythonPlatforms(StringOrStringSequenceField): alias = "platforms" -class PexInheritPath(StringField): +class PexInheritPathField(StringField): """Whether to inherit the `sys.path` of the environment that the binary runs in. Use `false` to not inherit `sys.path`; use `fallback` to inherit `sys.path` after packaged @@ -175,7 +199,7 @@ def compute_value( return super().compute_value(raw_value, address=address) -class PexZipSafe(BoolField): +class PexZipSafeField(BoolField): """Whether or not this binary is safe to run in compacted (zip-file) form. If they are not zip safe, they will be written to disk prior to execution. iff @@ -186,7 +210,7 @@ class PexZipSafe(BoolField): value: bool -class PexAlwaysWriteCache(BoolField): +class PexAlwaysWriteCacheField(BoolField): """Whether PEX should always write the .deps cache of the .pex file to disk or not. This can use less memory in RAM constrained environments. @@ -197,7 +221,7 @@ class PexAlwaysWriteCache(BoolField): value: bool -class PexIgnoreErrors(BoolField): +class PexIgnoreErrorsField(BoolField): """Should we ignore when PEX cannot resolve dependencies?""" alias = "ignore_errors" @@ -205,13 +229,13 @@ class PexIgnoreErrors(BoolField): value: bool -class PexShebang(StringField): +class PexShebangField(StringField): """For the generated PEX, use this shebang.""" alias = "shebang" -class PexEmitWarnings(BoolField): +class PexEmitWarningsField(BoolField): """Whether or not to emit PEX warnings at runtime. The default is determined by the option `pex_runtime_warnings` in the `[python-binary]` scope. @@ -219,36 +243,66 @@ class PexEmitWarnings(BoolField): alias = "emit_warnings" - def value_or_global_default(self, python_binary_defaults: PythonBinaryDefaults) -> bool: + def value_or_global_default(self, pex_binary_defaults: PexBinaryDefaults) -> bool: if self.value is None: - return python_binary_defaults.pex_emit_warnings + return pex_binary_defaults.emit_warnings return self.value -class PythonBinary(Target): +class PexBinary(Target): """A Python target that can be converted into an executable PEX file. PEX files are self-contained executable files that contain a complete Python environment capable of running the target. For more information, see https://www.pantsbuild.org/docs/pex-files. """ - alias = "python_binary" + alias = "pex_binary" core_fields = ( *COMMON_PYTHON_FIELDS, OutputPathField, - PythonBinarySources, - PythonBinaryDependencies, - PythonEntryPoint, - PythonPlatforms, - PexInheritPath, - PexZipSafe, - PexAlwaysWriteCache, - PexIgnoreErrors, - PexShebang, - PexEmitWarnings, + PexBinarySources, + PexBinaryDependencies, + PexEntryPointField, + PexPlatformsField, + PexInheritPathField, + PexZipSafeField, + PexAlwaysWriteCacheField, + PexIgnoreErrorsField, + PexShebangField, + PexEmitWarningsField, ) +class PythonBinary(PexBinary): + """A Python target that can be converted into an executable PEX file. + + PEX files are self-contained executable files that contain a complete Python environment capable + of running the target. For more information, see https://www.pantsbuild.org/docs/pex-files. + """ + + alias = "python_binary" + + def __init__( # type: ignore[misc] # This is `@final`, but it's fine to override here. + self, + unhydrated_values: Dict[str, Any], + *, + address: Address, + union_membership: Optional[UnionMembership] = None, + ) -> None: + warn_or_error( + removal_version="2.1.0.dev0", + deprecated_entity_description="the `python_binary` target", + hint=( + f"Use the target type `pex_binary`, rather than `python_binary` for {address}. " + "The behavior is identical.\n\nTo fix this globally, run the below command:\n\t" + "macOS: for f in $(find . -name BUILD); do sed -i '' -Ee " + "'s#^python_binary\\(#pex_binary(#g' $f ; done\n\tLinux: for f in $(find . " + "-name BUILD); do sed -i -Ee 's#^python_binary\\(#pex_binary(#g' $f ; done\n" + ), + ) + super().__init__(unhydrated_values, address=address, union_membership=union_membership) + + # ----------------------------------------------------------------------------------------------- # `python_tests` target # ----------------------------------------------------------------------------------------------- @@ -278,7 +332,7 @@ class PythonRuntimePackageDependencies(SpecialCasedDependencies): results in your archive using the same name they would normally have, but without the `--distdir` prefix (e.g. `dist/`). - You can include anything that can be built by `./pants package`, e.g. a `python_binary`, + You can include anything that can be built by `./pants package`, e.g. a `pex_binary`, `python_awslambda`, or even another `archive`. """ @@ -588,7 +642,7 @@ async def inject_dependencies( with_binaries = original_tgt.target[PythonProvidesField].value.binaries if not with_binaries: return InjectedDependencies() - # Note that we don't validate that these are all `python_binary` targets; we don't care about + # Note that we don't validate that these are all `pex_binary` targets; we don't care about # that here. `setup_py.py` will do that validation. addresses = await Get( Addresses, diff --git a/src/python/pants/backend/python/target_types_test.py b/src/python/pants/backend/python/target_types_test.py index 9e7372dc4d5..70656567886 100644 --- a/src/python/pants/backend/python/target_types_test.py +++ b/src/python/pants/backend/python/target_types_test.py @@ -11,8 +11,8 @@ from pants.backend.python.subsystems.pytest import PyTest from pants.backend.python.target_types import ( InjectPythonDistributionDependencies, - PythonBinary, - PythonBinarySources, + PexBinary, + PexBinarySources, PythonDistribution, PythonDistributionDependencies, PythonRequirementsField, @@ -65,12 +65,10 @@ def assert_timeout_calculated( def test_translate_source_file_to_entry_point() -> None: - assert ( - PythonBinarySources.translate_source_file_to_entry_point("example/app.py") == "example.app" - ) + assert PexBinarySources.translate_source_file_to_entry_point("example/app.py") == "example.app" # NB: the onus is on the call site to strip the source roots before calling this method. assert ( - PythonBinarySources.translate_source_file_to_entry_point("src/python/app.py") + PexBinarySources.translate_source_file_to_entry_point("src/python/app.py") == "src.python.app" ) @@ -127,14 +125,14 @@ def test_python_distribution_dependency_injection() -> None: (InjectPythonDistributionDependencies,), ), ], - target_types=[PythonDistribution, PythonBinary], + target_types=[PythonDistribution, PexBinary], objects={"setup_py": PythonArtifact}, ) rule_runner.add_to_build_file( "project", dedent( """\ - python_binary(name="my_binary") + pex_binary(name="my_binary") python_distribution( name="dist", provides=setup_py( diff --git a/src/python/pants/backend/python/util_rules/pex.py b/src/python/pants/backend/python/util_rules/pex.py index cfcc1103ee9..af95e462a48 100644 --- a/src/python/pants/backend/python/util_rules/pex.py +++ b/src/python/pants/backend/python/util_rules/pex.py @@ -23,9 +23,11 @@ from pkg_resources import Requirement from typing_extensions import Protocol -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 +from pants.backend.python.target_types import PexPlatformsField as PythonPlatformsField +from pants.backend.python.target_types import ( + PythonInterpreterCompatibility, + PythonRequirementsField, +) from pants.backend.python.util_rules import pex_cli from pants.backend.python.util_rules.pex_cli import PexCliProcess from pants.backend.python.util_rules.pex_environment import ( diff --git a/src/python/pants/bin/BUILD b/src/python/pants/bin/BUILD index 681973b9358..2f894f39792 100644 --- a/src/python/pants/bin/BUILD +++ b/src/python/pants/bin/BUILD @@ -22,7 +22,7 @@ python_library( # pip installers, ie: it is why this works to get `pants` on your PATH: # $ pip install pantsbuild.pants # $ pants -python_binary( +pex_binary( name='pants', entry_point='pants.bin.pants_loader:main', dependencies=[ @@ -35,7 +35,7 @@ python_binary( # This binary is for internal use only. It adds deps on internal_plugins and build-support config # files, both of which are not meant for publishing in the `pantsbuild.pants` sdist. -python_binary( +pex_binary( name='pants_local_binary', entry_point='pants.bin.pants_loader:main', dependencies=[ diff --git a/src/python/pants/core/target_types.py b/src/python/pants/core/target_types.py index 3af12854a2b..a1e13353eec 100644 --- a/src/python/pants/core/target_types.py +++ b/src/python/pants/core/target_types.py @@ -235,7 +235,7 @@ class ArchivePackages(SpecialCasedDependencies): results in your archive using the same name they would normally have, but without the `--distdir` prefix (e.g. `dist/`). - You can include anything that can be built by `./pants package`, e.g. a `python_binary`, + You can include anything that can be built by `./pants package`, e.g. a `pex_binary`, `python_awslambda`, or even another `archive`. """ diff --git a/src/python/pants/core/target_types_test.py b/src/python/pants/core/target_types_test.py index 8e64fd14fa9..ca1f24097a3 100644 --- a/src/python/pants/core/target_types_test.py +++ b/src/python/pants/core/target_types_test.py @@ -6,8 +6,8 @@ from io import BytesIO from textwrap import dedent -from pants.backend.python.goals import package_python_binary -from pants.backend.python.target_types import PythonBinary +from pants.backend.python.goals import package_pex_binary +from pants.backend.python.target_types import PexBinary from pants.backend.python.util_rules import pex_from_targets from pants.core.goals.package import BuiltPackage from pants.core.target_types import ( @@ -158,10 +158,10 @@ def test_archive() -> None: rules=[ *target_type_rules(), *pex_from_targets.rules(), - *package_python_binary.rules(), + *package_pex_binary.rules(), QueryRule(BuiltPackage, [ArchiveFieldSet]), ], - target_types=[ArchiveTarget, Files, RelocatedFiles, PythonBinary], + target_types=[ArchiveTarget, Files, RelocatedFiles, PexBinary], ) rule_runner.set_options( ["--backend-packages=pants.backend.python", "--no-pants-distdir-legacy-paths"] @@ -186,7 +186,7 @@ def test_archive() -> None: ) rule_runner.create_file("project/app.py", "print('hello world!')") - rule_runner.add_to_build_file("project", "python_binary(sources=['app.py'])") + rule_runner.add_to_build_file("project", "pex_binary(sources=['app.py'])") rule_runner.add_to_build_file( "", diff --git a/src/python/pants/python/python_setup.py b/src/python/pants/python/python_setup.py index 49b5ba9870c..939eaa3d264 100644 --- a/src/python/pants/python/python_setup.py +++ b/src/python/pants/python/python_setup.py @@ -96,7 +96,7 @@ def register_options(cls, register): removal_version="2.1.0.dev0", removal_hint=( "The option `--python-setup-platforms` does not do anything anymore. Instead, " - "explicitly set the `platforms` field on each `python_binary`." + "explicitly set the `platforms` field on each `pex_binary` target." ), ) register( diff --git a/src/python/pants/vcs/changed_integration_test.py b/src/python/pants/vcs/changed_integration_test.py index 76fe57aaf08..a5322b4da38 100644 --- a/src/python/pants/vcs/changed_integration_test.py +++ b/src/python/pants/vcs/changed_integration_test.py @@ -173,7 +173,7 @@ class ChangedIntegrationTest(PantsIntegrationTest, AbstractTestGenerator): hermetic = False TEST_MAPPING = { - # A `python_binary` with `sources=['file.name']`. + # A `pex_binary` with `sources=['file.name']`. "src/python/python_targets/test_binary.py": dict( none=["src/python/python_targets/test_binary.py:test"], direct=[ diff --git a/testprojects/src/python/bad_requirements/BUILD b/testprojects/src/python/bad_requirements/BUILD index f983a800975..532925cc0f7 100644 --- a/testprojects/src/python/bad_requirements/BUILD +++ b/testprojects/src/python/bad_requirements/BUILD @@ -6,7 +6,7 @@ python_requirement_library( requirements=['badreq==99.99.99'], ) -python_binary( +pex_binary( name='use_badreq', dependencies=[':badreq'], entry_point='bad_requirements.use_badreq', diff --git a/testprojects/src/python/build_file_imports_function/TEST_BUILD b/testprojects/src/python/build_file_imports_function/TEST_BUILD index 2df3e8752f7..fa13c0e65b7 100644 --- a/testprojects/src/python/build_file_imports_function/TEST_BUILD +++ b/testprojects/src/python/build_file_imports_function/TEST_BUILD @@ -1,6 +1,6 @@ from os.path import join -python_binary( +pex_binary( name = join("hello"), sources = ["hello.py"], ) diff --git a/testprojects/src/python/build_file_imports_module/TEST_BUILD b/testprojects/src/python/build_file_imports_module/TEST_BUILD index 4be69a85f3d..874ddcf523b 100644 --- a/testprojects/src/python/build_file_imports_module/TEST_BUILD +++ b/testprojects/src/python/build_file_imports_module/TEST_BUILD @@ -1,6 +1,6 @@ import os.path -python_binary( +pex_binary( name = os.path.join("hello"), sources = ["hello.py"], ) diff --git a/testprojects/src/python/coordinated_runs/BUILD b/testprojects/src/python/coordinated_runs/BUILD index 7d97f2f00c1..ddde4c235aa 100644 --- a/testprojects/src/python/coordinated_runs/BUILD +++ b/testprojects/src/python/coordinated_runs/BUILD @@ -1,17 +1,17 @@ # Copyright 2015 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). -python_binary( +pex_binary( name='creator', sources=['creator.py'], ) -python_binary( +pex_binary( name='phaser', sources=['phaser.py'], ) -python_binary( +pex_binary( name='waiter', sources=['waiter.py'], ) diff --git a/testprojects/src/python/print_env/BUILD b/testprojects/src/python/print_env/BUILD index 5fa5bc21c30..8074637b99f 100644 --- a/testprojects/src/python/print_env/BUILD +++ b/testprojects/src/python/print_env/BUILD @@ -1,7 +1,7 @@ # Copyright 2015 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). -python_binary( +pex_binary( entry_point = 'print_env.main', dependencies = [':lib'], ) diff --git a/testprojects/src/python/python_targets/BUILD b/testprojects/src/python/python_targets/BUILD index 0625b8104e8..c7f928f3b2f 100644 --- a/testprojects/src/python/python_targets/BUILD +++ b/testprojects/src/python/python_targets/BUILD @@ -1,7 +1,7 @@ # Copyright 2016 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). -python_binary( +pex_binary( name='test', sources=['test_binary.py'], dependencies=[':test_library'] diff --git a/testprojects/src/python/unicode/compilation_failure/BUILD b/testprojects/src/python/unicode/compilation_failure/BUILD index ca011dca4ee..f4e45cbef00 100644 --- a/testprojects/src/python/unicode/compilation_failure/BUILD +++ b/testprojects/src/python/unicode/compilation_failure/BUILD @@ -1,7 +1,7 @@ # Copyright 2015 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). -python_binary( +pex_binary( sources = ['main.py'], dependencies = [':lib'], tags = {"nolint"}, diff --git a/tests/python/pants_test/integration/prelude_integration_test.py b/tests/python/pants_test/integration/prelude_integration_test.py index d8d167a8d35..b2c7119b5c1 100644 --- a/tests/python/pants_test/integration/prelude_integration_test.py +++ b/tests/python/pants_test/integration/prelude_integration_test.py @@ -12,7 +12,7 @@ def test_build_file_prelude() -> None: "prelude.py": dedent( """\ def make_binary_macro(): - python_binary(name="main", sources=["main.py"]) + pex_binary(name="main", sources=["main.py"]) """ ), "BUILD": "make_binary_macro()",