Skip to content

Commit 219cd42

Browse files
Deprecate python_binary in favor of pex_binary (#10939)
Reasons: 1. Users have expressed interest in other formats than Pex, such as Pyinstaller. We don't want to privilege Pex over those other formats. 2. More explicit to users what it is Pants is doing. `python_binary` is not some magical thing; it is an interface around the Pex tool. * Reminder: we are framing Pants as "an orchestrator around the tools you already use". A theme of 2.0 has been to reduce places where Pants is magical, e.g. our revised `__init__.py` handling. We want to make this change before 2.0 is released to the world. [ci skip-rust] [ci skip-build-wheels]
1 parent ac9f7d1 commit 219cd42

File tree

26 files changed

+195
-142
lines changed

26 files changed

+195
-142
lines changed

build-support/bin/BUILD

+11-11
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,22 @@ python_tests(
1212
timeout=90,
1313
)
1414

15-
python_binary(
15+
pex_binary(
1616
name = 'bootstrap_and_deploy_ci_pants_pex',
1717
sources = ['bootstrap_and_deploy_ci_pants_pex.py'],
1818
)
1919

20-
python_binary(
20+
pex_binary(
2121
name = 'check_banned_imports',
2222
sources = ['check_banned_imports.py'],
2323
)
2424

25-
python_binary(
25+
pex_binary(
2626
name = 'check_inits',
2727
sources = ['check_inits.py'],
2828
)
2929

30-
python_binary(
30+
pex_binary(
3131
name = 'ci',
3232
sources = ['ci.py'],
3333
)
@@ -37,17 +37,17 @@ python_library(
3737
sources = ['common.py'],
3838
)
3939

40-
python_binary(
40+
pex_binary(
4141
name = 'deploy_to_s3',
4242
sources = ['deploy_to_s3.py'],
4343
)
4444

45-
python_binary(
45+
pex_binary(
4646
name = 'generate_travis_yml',
4747
sources = ['generate_travis_yml.py'],
4848
)
4949

50-
python_binary(
50+
pex_binary(
5151
name = 'generate_docs',
5252
sources = ['generate_docs.py'],
5353
dependencies = [
@@ -60,23 +60,23 @@ resources(
6060
sources = ['docs_templates/*.mustache'],
6161
)
6262

63-
python_binary(
63+
pex_binary(
6464
name = 'get_rbe_token',
6565
sources = ['get_rbe_token.py'],
6666
)
6767

68-
python_binary(
68+
pex_binary(
6969
name='reversion',
7070
sources=["reversion.py"],
7171
)
7272

73-
python_binary(
73+
pex_binary(
7474
name = 'shellcheck',
7575
sources = ['shellcheck.py'],
7676
)
7777

7878
# TODO: rename this to `release.py` once done porting Bash to Python.
79-
python_binary(
79+
pex_binary(
8080
name = "packages",
8181
sources = ["packages.py"],
8282
)

examples/src/python/example/hello/main/BUILD

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# Licensed under the Apache License, Version 2.0 (see LICENSE).
33

44
# Like Hello world, but built with Pants.
5-
python_binary(
5+
pex_binary(
66
dependencies=[
77
'examples/src/python/example/hello/greet:greet',
88
':lib',

src/python/pants/backend/python/goals/package_python_binary.py src/python/pants/backend/python/goals/package_pex_binary.py

+29-32
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,16 @@
66
from typing import Tuple, cast
77

88
from pants.backend.python.target_types import (
9-
PexAlwaysWriteCache,
10-
PexEmitWarnings,
11-
PexIgnoreErrors,
12-
PexInheritPath,
13-
PexShebang,
14-
PexZipSafe,
15-
PythonBinaryDefaults,
16-
PythonBinarySources,
17-
PythonEntryPoint,
9+
PexAlwaysWriteCacheField,
10+
PexBinaryDefaults,
11+
PexBinarySources,
12+
PexEmitWarningsField,
13+
PexEntryPointField,
14+
PexIgnoreErrorsField,
15+
PexInheritPathField,
1816
)
19-
from pants.backend.python.target_types import PythonPlatforms as PythonPlatformsField
17+
from pants.backend.python.target_types import PexPlatformsField as PythonPlatformsField
18+
from pants.backend.python.target_types import PexShebangField, PexZipSafeField
2019
from pants.backend.python.util_rules.pex import PexPlatforms, TwoStepPex
2120
from pants.backend.python.util_rules.pex_from_targets import (
2221
PexFromTargetsRequest,
@@ -40,28 +39,26 @@
4039

4140

4241
@dataclass(frozen=True)
43-
class PythonBinaryFieldSet(PackageFieldSet, BinaryFieldSet, RunFieldSet):
44-
required_fields = (PythonEntryPoint, PythonBinarySources)
42+
class PexBinaryFieldSet(PackageFieldSet, BinaryFieldSet, RunFieldSet):
43+
required_fields = (PexEntryPointField, PexBinarySources)
4544

46-
sources: PythonBinarySources
47-
entry_point: PythonEntryPoint
45+
sources: PexBinarySources
46+
entry_point: PexEntryPointField
4847

4948
output_path: OutputPathField
50-
always_write_cache: PexAlwaysWriteCache
51-
emit_warnings: PexEmitWarnings
52-
ignore_errors: PexIgnoreErrors
53-
inherit_path: PexInheritPath
54-
shebang: PexShebang
55-
zip_safe: PexZipSafe
49+
always_write_cache: PexAlwaysWriteCacheField
50+
emit_warnings: PexEmitWarningsField
51+
ignore_errors: PexIgnoreErrorsField
52+
inherit_path: PexInheritPathField
53+
shebang: PexShebangField
54+
zip_safe: PexZipSafeField
5655
platforms: PythonPlatformsField
5756

58-
def generate_additional_args(
59-
self, python_binary_defaults: PythonBinaryDefaults
60-
) -> Tuple[str, ...]:
57+
def generate_additional_args(self, pex_binary_defaults: PexBinaryDefaults) -> Tuple[str, ...]:
6158
args = []
6259
if self.always_write_cache.value is True:
6360
args.append("--always-write-cache")
64-
if self.emit_warnings.value_or_global_default(python_binary_defaults) is False:
61+
if self.emit_warnings.value_or_global_default(pex_binary_defaults) is False:
6562
args.append("--no-emit-warnings")
6663
if self.ignore_errors.value is True:
6764
args.append("--ignore-errors")
@@ -75,9 +72,9 @@ def generate_additional_args(
7572

7673

7774
@rule(level=LogLevel.DEBUG)
78-
async def package_python_binary(
79-
field_set: PythonBinaryFieldSet,
80-
python_binary_defaults: PythonBinaryDefaults,
75+
async def package_pex_binary(
76+
field_set: PexBinaryFieldSet,
77+
pex_binary_defaults: PexBinaryDefaults,
8178
global_options: GlobalOptions,
8279
) -> BuiltPackage:
8380
entry_point = field_set.entry_point.value
@@ -97,7 +94,7 @@ async def package_python_binary(
9794
SourceRootRequest,
9895
SourceRootRequest.for_file(entry_point_path),
9996
)
100-
entry_point = PythonBinarySources.translate_source_file_to_entry_point(
97+
entry_point = PexBinarySources.translate_source_file_to_entry_point(
10198
os.path.relpath(entry_point_path, source_root.path)
10299
)
103100

@@ -115,22 +112,22 @@ async def package_python_binary(
115112
entry_point=entry_point,
116113
platforms=PexPlatforms.create_from_platforms_field(field_set.platforms),
117114
output_filename=output_filename,
118-
additional_args=field_set.generate_additional_args(python_binary_defaults),
115+
additional_args=field_set.generate_additional_args(pex_binary_defaults),
119116
)
120117
),
121118
)
122119
return BuiltPackage(two_step_pex.pex.digest, (BuiltPackageArtifact(output_filename),))
123120

124121

125122
@rule(level=LogLevel.DEBUG)
126-
async def create_python_binary(field_set: PythonBinaryFieldSet) -> CreatedBinary:
123+
async def create_pex_binary(field_set: PexBinaryFieldSet) -> CreatedBinary:
127124
pex = await Get(BuiltPackage, PackageFieldSet, field_set)
128125
return CreatedBinary(pex.digest, cast(str, pex.artifacts[0].relpath))
129126

130127

131128
def rules():
132129
return [
133130
*collect_rules(),
134-
UnionRule(PackageFieldSet, PythonBinaryFieldSet),
135-
UnionRule(BinaryFieldSet, PythonBinaryFieldSet),
131+
UnionRule(PackageFieldSet, PexBinaryFieldSet),
132+
UnionRule(BinaryFieldSet, PexBinaryFieldSet),
136133
]

src/python/pants/backend/python/goals/pytest_runner_integration_test.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010
import pytest
1111

1212
from pants.backend.python.dependency_inference import rules as dependency_inference_rules
13-
from pants.backend.python.goals import package_python_binary, pytest_runner
13+
from pants.backend.python.goals import package_pex_binary, pytest_runner
1414
from pants.backend.python.goals.coverage_py import create_coverage_config
1515
from pants.backend.python.goals.pytest_runner import PythonTestFieldSet
1616
from pants.backend.python.target_types import (
17-
PythonBinary,
17+
PexBinary,
1818
PythonLibrary,
1919
PythonRequirementLibrary,
2020
PythonTests,
@@ -40,12 +40,12 @@ def rule_runner() -> RuleRunner:
4040
*dependency_inference_rules.rules(), # For conftest detection.
4141
*distdir.rules(),
4242
*binary.rules(),
43-
*package_python_binary.rules(),
43+
*package_pex_binary.rules(),
4444
get_filtered_environment,
4545
QueryRule(TestResult, (PythonTestFieldSet,)),
4646
QueryRule(TestDebugRequest, (PythonTestFieldSet,)),
4747
],
48-
target_types=[PythonBinary, PythonLibrary, PythonTests, PythonRequirementLibrary],
48+
target_types=[PexBinary, PythonLibrary, PythonTests, PythonRequirementLibrary],
4949
)
5050

5151

@@ -110,13 +110,13 @@ def create_test_target(
110110
return tgt
111111

112112

113-
def create_python_binary_target(rule_runner: RuleRunner, source_file: FileContent) -> None:
113+
def create_pex_binary_target(rule_runner: RuleRunner, source_file: FileContent) -> None:
114114
rule_runner.create_file(source_file.path, source_file.content.decode())
115115
rule_runner.add_to_build_file(
116116
relpath=PACKAGE,
117117
target=dedent(
118118
f"""\
119-
python_binary(
119+
pex_binary(
120120
name='bin',
121121
sources=['{PurePath(source_file.path).name}'],
122122
)
@@ -442,7 +442,7 @@ def test_args():
442442

443443

444444
def test_runtime_package_dependency(rule_runner: RuleRunner) -> None:
445-
create_python_binary_target(rule_runner, BINARY_SOURCE)
445+
create_pex_binary_target(rule_runner, BINARY_SOURCE)
446446
rule_runner.create_file(
447447
f"{PACKAGE}/test_binary_call.py",
448448
dedent(

src/python/pants/backend/python/goals/run_python_binary.py src/python/pants/backend/python/goals/run_pex_binary.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33

44
import os
55

6-
from pants.backend.python.goals.package_python_binary import PythonBinaryFieldSet
7-
from pants.backend.python.target_types import PythonBinaryDefaults, PythonBinarySources
6+
from pants.backend.python.goals.package_pex_binary import PexBinaryFieldSet
7+
from pants.backend.python.target_types import PexBinaryDefaults, PexBinarySources
88
from pants.backend.python.util_rules.pex import Pex, PexRequest
99
from pants.backend.python.util_rules.pex_environment import PexEnvironment
1010
from pants.backend.python.util_rules.pex_from_targets import PexFromTargetsRequest
@@ -23,9 +23,9 @@
2323

2424

2525
@rule(level=LogLevel.DEBUG)
26-
async def create_python_binary_run_request(
27-
field_set: PythonBinaryFieldSet,
28-
python_binary_defaults: PythonBinaryDefaults,
26+
async def create_pex_binary_run_request(
27+
field_set: PexBinaryFieldSet,
28+
pex_binary_defaults: PexBinaryDefaults,
2929
pex_env: PexEnvironment,
3030
) -> RunRequest:
3131
entry_point = field_set.entry_point.value
@@ -45,7 +45,7 @@ async def create_python_binary_run_request(
4545
SourceRootRequest,
4646
SourceRootRequest.for_file(entry_point_path),
4747
)
48-
entry_point = PythonBinarySources.translate_source_file_to_entry_point(
48+
entry_point = PexBinarySources.translate_source_file_to_entry_point(
4949
os.path.relpath(entry_point_path, source_root.path)
5050
)
5151
transitive_targets = await Get(TransitiveTargets, TransitiveTargetsRequest([field_set.address]))
@@ -70,7 +70,7 @@ async def create_python_binary_run_request(
7070
PexRequest(
7171
output_filename=output_filename,
7272
interpreter_constraints=requirements_pex_request.interpreter_constraints,
73-
additional_args=field_set.generate_additional_args(python_binary_defaults),
73+
additional_args=field_set.generate_additional_args(pex_binary_defaults),
7474
internal_only=True,
7575
# Note that the entry point file is not in the Pex itself, but on the
7676
# PEX_PATH. This works fine!
@@ -105,4 +105,4 @@ def in_chroot(relpath: str) -> str:
105105

106106

107107
def rules():
108-
return [*collect_rules(), UnionRule(RunFieldSet, PythonBinaryFieldSet)]
108+
return [*collect_rules(), UnionRule(RunFieldSet, PexBinaryFieldSet)]

src/python/pants/backend/python/goals/run_python_binary_integration_test.py src/python/pants/backend/python/goals/run_pex_binary_integration_test.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@
1111
@pytest.mark.parametrize(
1212
"tgt_content",
1313
[
14-
"python_binary(sources=['app.py'])",
15-
"python_binary(sources=['app.py'], entry_point='project.app')",
16-
"python_binary(sources=['app.py'], entry_point='project.app:main')",
14+
"pex_binary(sources=['app.py'])",
15+
"pex_binary(sources=['app.py'], entry_point='project.app')",
16+
"pex_binary(sources=['app.py'], entry_point='project.app:main')",
1717
],
1818
)
1919
def test_run_sample_script(tgt_content: str) -> None:
20-
"""Test that we properly run a `python_binary` target.
20+
"""Test that we properly run a `pex_binary` target.
2121
2222
This checks a few things:
2323
- We can handle source roots.

src/python/pants/backend/python/goals/setup_py.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from pants.backend.python.macros.python_artifact import PythonArtifact
1515
from pants.backend.python.subsystems.setuptools import Setuptools
1616
from pants.backend.python.target_types import (
17-
PythonEntryPoint,
17+
PexEntryPointField,
1818
PythonInterpreterCompatibility,
1919
PythonProvidesField,
2020
PythonRequirementsField,
@@ -620,7 +620,7 @@ async def generate_chroot(request: SetupPyChrootRequest) -> SetupPyChroot:
620620
Targets, UnparsedAddressInputs(key_to_binary_spec.values(), owning_address=target.address)
621621
)
622622
for key, binary in zip(key_to_binary_spec.keys(), binaries):
623-
binary_entry_point = binary.get(PythonEntryPoint).value
623+
binary_entry_point = binary.get(PexEntryPointField).value
624624
if not binary_entry_point:
625625
raise InvalidEntryPoint(
626626
f"The binary {key} exported by {target.address} is not a valid entry point."

src/python/pants/backend/python/goals/setup_py_test.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
)
3535
from pants.backend.python.macros.python_artifact import PythonArtifact
3636
from pants.backend.python.target_types import (
37-
PythonBinary,
37+
PexBinary,
3838
PythonDistribution,
3939
PythonLibrary,
4040
PythonRequirementLibrary,
@@ -56,7 +56,7 @@ def create_setup_py_rule_runner(*, rules: Iterable) -> RuleRunner:
5656
return RuleRunner(
5757
rules=rules,
5858
target_types=[
59-
PythonBinary,
59+
PexBinary,
6060
PythonDistribution,
6161
PythonLibrary,
6262
PythonRequirementLibrary,
@@ -149,7 +149,7 @@ def test_generate_chroot(chroot_rule_runner: RuleRunner) -> None:
149149
"""
150150
python_library()
151151
152-
python_binary(name="bin", entry_point="foo.qux.bin")
152+
pex_binary(name="bin", entry_point="foo.qux.bin")
153153
"""
154154
),
155155
)
@@ -226,7 +226,7 @@ def test_invalid_binary(chroot_rule_runner: RuleRunner) -> None:
226226
textwrap.dedent(
227227
"""
228228
python_library(name='not_a_binary', sources=[])
229-
python_binary(name='no_entrypoint')
229+
pex_binary(name='no_entrypoint')
230230
python_distribution(
231231
name='invalid_bin1',
232232
provides=setup_py(

src/python/pants/backend/python/macros/python_artifact.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ def with_binaries(self, *args, **kw):
5252
my_command = ':my_library_bin'
5353
)
5454
55-
This adds a console_script entry_point for the python_binary target
55+
This adds a console_script entry_point for the pex_binary target
5656
pointed at by :my_library_bin. Currently only supports
57-
python_binaries that specify entry_point explicitly instead of source.
57+
pex_binaries that specify entry_point explicitly instead of source.
5858
5959
Also can take a dictionary, e.g.
6060
with_binaries({'my-command': ':my_library_bin'})

0 commit comments

Comments
 (0)