-
-
Notifications
You must be signed in to change notification settings - Fork 649
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
Only python_binary's constraint should be included in a built pex #7775
Comments
Agreed that the desired behavior is to only use the As pitched over Slack, I think your idea to do an interpreter cache lookup with all constraints first to ensure is a good one. I recommend using this function: pants/src/python/pants/backend/python/interpreter_cache.py Lines 79 to 80 in 58706c1
Otherwise, we would have to build a Pex twice—the first time with all constraints and the second with just the -- It would be great to see a test added for this. I think we want to test where a binary's |
Although |
Good call, John. Making this resolution not depend on the local interpreters available also reduces the risk of Pex interpreter resolution diverging from Pants interpreter resolution. Finally, I suspect it will make it easier for us to port Stu, feel free to assign this ticket to me. |
The necessary bits:
|
@stuhood Here's an initial diff: diff --git a/src/python/pants/backend/python/subsystems/python_setup.py b/src/python/pants/backend/python/subsystems/python_setup.py
index 695b1def7..2e41aa07d 100644
--- a/src/python/pants/backend/python/subsystems/python_setup.py
+++ b/src/python/pants/backend/python/subsystems/python_setup.py
@@ -133,6 +133,22 @@ class PythonSetup(Subsystem):
return tuple(self.interpreter_constraints)
return tuple(compatibility or self.interpreter_constraints)
+ # TODO: this function should probably directly take interpreter constraints, and not call
+ # self.compatibility_or_constraints(), because it would be a simpler function that makes less
+ # assumptions and it would also become a pure function. Would make it much easier to test.
+ def has_no_compatibility_constraint_conflicts(self, *compatibility_entries):
+ """Confirm that all targets have compatible constraints.
+
+ :param compatibility_entries: List[Optional[List[str]]], e.g. *[None, ['CPython>3']].
+ """
+ resolved_constraints = {
+ constraint
+ for compatibility_entry in compatibility_entries
+ for constraint in self.compatibility_or_constraints(compatibility_entry)
+ }
+ # TODO: somehow calculate if any of the constraints fail, likely using packaging.requirements.
+ # TODO: add various unit tests for this this function.
+
@classmethod
def expand_interpreter_search_paths(cls, interpreter_search_paths, pyenv_root_func=None):
special_strings = {
diff --git a/src/python/pants/backend/python/tasks/python_binary_create.py b/src/python/pants/backend/python/tasks/python_binary_create.py
index 805dfa8a5..2b98a550d 100644
--- a/src/python/pants/backend/python/tasks/python_binary_create.py
+++ b/src/python/pants/backend/python/tasks/python_binary_create.py
@@ -140,9 +140,19 @@ class PythonBinaryCreate(Task):
if is_python_target(tgt):
constraint_tgts.append(tgt)
- # Add interpreter compatibility constraints to pex info. This will first check the targets for any
- # constraints, and if they do not have any will resort to the global constraints.
- pex_builder.add_interpreter_constraints_from(constraint_tgts)
+ # Check that all dependencies have valid compatibility constraints that do not conflict
+ # with the binary's constraints.
+ # TODO: somehow reference global instance of PythonSetup
+ # TODO: fail if not compatible
+ PythonSetup().has_no_compatibility_constraint_conflicts(*[
+ getattr(tgt, 'compatibility', None) for tgt in constraint_tgts
+ ])
+
+
+ # Add interpreter compatibility constraints to pex info from the binary target. This will
+ # first check if the target has `compatibility` defined, then will resort to the global
+ # constraints.
+ pex_builder.add_interpreter_constraints_from([binary_tgt])
# Dump everything into the builder's chroot.
for tgt in source_tgts:
I'm going to move on to other work for now, but can pick back up tomorrow if you'd like. |
So... while I agree that not requiring a matching local interpreter would be good, we're currently trying to unblock the I'd like to avoid doing anything algorithmically fiddly in that path, and hopefully hand off a working patch to @illicitonion in a few hours that he can land, cherry-pick, and ship. So I'm leaning toward just doing the |
So long as we have a good TODO to make this more robust, I'm fine with that given the context.
😀 |
) ### Problem See the problem described in #7775. ### Solution Compute and validate the transitive constraints, but only include the `python_binary`'s constraint in the built pex. ### Result Fixes #7775, but leaves a TODO about supporting building a binary for an interpreter for which we do not have a valid interpreter.
) ### Problem See the problem described in #7775. ### Solution Compute and validate the transitive constraints, but only include the `python_binary`'s constraint in the built pex. ### Result Fixes #7775, but leaves a TODO about supporting building a binary for an interpreter for which we do not have a valid interpreter.
It looks like there is an equivalent issue with |
Can we instead factor this out so that That would avoid this problem recurring, and would also mean that resources are treated uniformly across |
### Problem The problems observed in #7775 and #7563 had a third (and hopefully final: I'll audit before we land this) buddy in the `PythonRun` case. The tests in https://github.com/pantsbuild/pants/blob/817f7f6aedad8143fe7b2cf86559019254230da4/tests/python/pants_test/backend/python/tasks/test_python_run_integration.py#L134-L184 attempt to cover this case, but they were not using mixed contexts (contexts containing `(2-or-3, 3-only)` and `(2-only, 2-or-3)` constraints). ### Solution Similar to #7775 and #7563, do not include transitive constraints when `./pants run`ing a binary. Clarify the documentation of `PythonExecutionTaskBase`. Expand coverage of the mixed context case in existing tests. ### Result The tests linked above fail before this change for `PythonRun`, and succeed afterward.
The problems observed in #7775 and #7563 had a third (and hopefully final: I'll audit before we land this) buddy in the `PythonRun` case. The tests in https://github.com/pantsbuild/pants/blob/817f7f6aedad8143fe7b2cf86559019254230da4/tests/python/pants_test/backend/python/tasks/test_python_run_integration.py#L134-L184 attempt to cover this case, but they were not using mixed contexts (contexts containing `(2-or-3, 3-only)` and `(2-only, 2-or-3)` constraints). Similar to #7775 and #7563, do not include transitive constraints when `./pants run`ing a binary. Clarify the documentation of `PythonExecutionTaskBase`. Expand coverage of the mixed context case in existing tests. The tests linked above fail before this change for `PythonRun`, and succeed afterward.
pex-tool/pex#655 changed the default operator for lists of constraints to
OR
.But for a long time now
PythonBinaryCreate
has been using something like the following snippet to collect constraints from all targets in the closure:pants/src/python/pants/backend/python/tasks/python_binary_create.py
Lines 131 to 145 in 58706c1
For a usecase like:
... the resulting pex will have constraints:
...which when ORd, do not have the intended effect.
It looks like what this code wants to be doing is:
python_binary
target's constraint,Doing 1 is straightforward, but I'll need a pointer on 2. cc @jsirois , @Eric-Arellano
The text was updated successfully, but these errors were encountered: