-
-
Notifications
You must be signed in to change notification settings - Fork 292
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for --override
.
#2431
Conversation
This allows overriding transitive requirements in a resolve when the user knows a thrid party project's requirements are too restrictive. Also plumb the existing `--exclude` through to locks (along with `--override`) to allow sealing dependency manipulation configuration into the lock. Closes pex-tool#2425
tests/integration/test_overrides.py
Outdated
@skip_unless_compatible_with_requests_2_31_0 | ||
def test_override( | ||
tmpdir, # type: Any | ||
complex_requests_override_pex, # type: str | ||
): | ||
# type: (...) -> None | ||
|
||
pex = os.path.join(str(tmpdir), "pex") | ||
run_pex_command( | ||
args=[ | ||
"--python", | ||
sys.executable, | ||
"--python", | ||
ensure_python_interpreter(PY310 if PY_VER < (3, 10) else PY39), | ||
"requests==2.31.0", | ||
"--override", | ||
"urllib3==1.21; python_version >= '3.10'", | ||
"--override", | ||
"urllib3==1.20; python_version < '3.10'", | ||
"--override", | ||
"idna<2.5", | ||
"-o", | ||
pex, | ||
] | ||
).assert_success() | ||
|
||
dists = [ | ||
dist for dist in PEX(pex).resolve() if ProjectName("requests") == dist.metadata.project_name | ||
] | ||
assert 1 == len(dists) | ||
requests = dists[0] | ||
request_deps_by_project_name = {dep.project_name: dep for dep in requests.requires()} | ||
assert ( | ||
Requirement.parse("urllib3<3,>=1.21.1") | ||
== request_deps_by_project_name[ProjectName("urllib3")] | ||
), ( | ||
"Our multiple override test requires requests normally have an urllib3 lower bound of " | ||
"1.21.1." | ||
) | ||
assert ( | ||
Requirement.parse("idna<4,>=2.5") == request_deps_by_project_name[ProjectName("idna")] | ||
), "Our single override test requires requests normally have an idna lower bound of 2.5." | ||
|
||
assert_overrides( | ||
pex, | ||
expected_overrides=[ | ||
'urllib3==1.21; python_version >= "3.10"', | ||
'urllib3==1.20; python_version < "3.10"', | ||
"idna<2.5", | ||
], | ||
expected_overridden_dists={"urllib3": ["1.20", "1.21"], "idna": ["2.4"]}, | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cognifloyd you can do pretty crazy stuff now between --exclude
and --override
. Use the power wisely.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you! That turned out to be very elegant.
def register(parser): | ||
# type: (_ActionsContainer) -> None | ||
"""Register dependency configuration options with the given parser. | ||
|
||
:param parser: The parser to register dependency configuration options with. | ||
""" | ||
parser.add_argument( | ||
"--exclude", | ||
dest="excluded", | ||
default=[], | ||
type=str, | ||
action="append", | ||
help=( | ||
"Specifies a requirement to exclude from the built PEX. Any distribution included in " | ||
"the PEX's resolve that matches the requirement is excluded from the built PEX along " | ||
"with all of its transitive dependencies that are not also required by other " | ||
"non-excluded distributions. At runtime, the PEX will boot without checking the " | ||
"excluded dependencies are available (say, via `--inherit-path`). This option can be " | ||
"used multiple times." | ||
), | ||
) | ||
parser.add_argument( | ||
"--override", | ||
dest="overridden", | ||
default=[], | ||
type=str, | ||
action="append", | ||
help=( | ||
"Specifies a transitive requirement to override when resolving. Any distribution " | ||
"requirement in the PEX's resolve that matches the override project name is replaced " | ||
"with the given override requirement. This option can be used multiple times." | ||
), | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@benjyw I wanted to draw your attention to this change retroactively. The --exclude
and --override
options are very different from --constraints
. With --constraints
you can only narrow the requirements of some transitive dependency. With --exclude
and --override
you can actually edit the requirements of a transitive dependency.
This allows overriding transitive requirements in a resolve when the
user knows a thrid party project's requirements are too restrictive.
Also plumb the existing
--exclude
through to locks (along with--override
) to allow sealing dependency manipulation configurationinto the lock.
Closes #2425