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
Support for using a single global resolve. #10405
Conversation
Introduces a --python-setup-use-all-requirements flag. If set, instead of resolving just the exact requirements needed, we resolve the entire lockfile. This prevents a huge amount of resolving work of all the various requirement subsets needed by specific tests. [ci skip-rust-tests]
e639d0c
to
81d58f6
Compare
PS feel free to bikeshed the flag name |
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!
# TODO: Should this default to True? Seems like a better initial experience for most | ||
# users (although they still require at least a trivial lockfile to get any benefit). | ||
default=False, |
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.
I think no, in part for that reason of needing a lockfile configured. Instead, we can suggest it in the docs.
# Note that if a request has both requirements and requirements_files, the description | ||
# will only mention the requirements. However we have no such case today anyway. |
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.
See below on possibly merging this.
# Rust tests will be skipped. Delete if not intended. [ci skip-rust-tests]
[ci skip-rust-tests]
OK so now we don't apply the behavior unless we confirm that the reqs are a subset of those in the lockfile .(at the project name level) |
@stuhood does this address the concern? Namely this change still doesn't have an opinion about how to pick a lockfile, but if one is picked, it will apply this behavior in that context - only if the reqs are a subset (so for example if no single lockfile is possible, something sensible will still happen). |
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.
I think that we should try to eliminate this setting in the future by removing the downside (namely, that all of the requirements from the lockfile file are present). If we have time to implement that approach now, that would be preferable.
The existence of a lockfile implies that there is a globally consistent resolve associated with that lockfile (ie, that it's possible to choose exactly one version of each library). If that is the case, then targets that depend on that resolve should be able to consume only the relevant subset of the resolve... consuming the "relevant subset" could be accomplished by having either pip or pex emit a graph of the dependencies within the resolve, allowing individual targets to depend on a subset of the artifacts, while still depending on the same single resolve associated with their lockfile. That would avoid invalidating tests/binaries for irrelevant artifacts.
if exact_req_projects.issubset(constraint_file_projects): | ||
requirements = PexRequirements(str(req) for req in constraints_file_reqs) | ||
else: | ||
requirements = exact_reqs |
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.
This would mean that the lockfile was incorrectly or partially created, I think? That probably justifies a warning.
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.
That could possibly the case. Or they may intentionally be using an inline requirement and they don't want it included in the global constraints file. I'd bias towards no warning (noisy), but will defer to you both.
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.
Given that 1) creating a lockfile is currently a manual process that someone can get wrong, and 2) the reason that you would do it would be to give you build determinism... I think that it makes sense to warn here, at the very least.
But perhaps it is the case that that warning should trigger regardless of the --resolve-all-constraints
setting, anytime that you have a lockfile configured and we encounter a requirement that is not specified in the constraints file? This is in the general category of "things are pretty manual right now" as described in https://www.pantsbuild.org/docs/python-third-party-dependencies#using-a-lockfile-recommended
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.
Good points. That makes sense and fits with a theme I'd like for Pants to have of Pants eagerly helping you to do what you likely intended, kind of like how people describe the Rust compiler.
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.
Yeah, I think this makes sense as a warning. Will add.
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.
This looks great! Thank you for making the change with inline requirements!
This might be more complicated, and I would rather punt on it for now. For example, creating the relevant subset means, I assume, symlink farming. Are we sure we can always get that right? |
It would mean having pex or pip emit this information. https://pypi.org/project/pipdeptree/ exists, although it might do symlink farming behind the scenes. But also, I recall that @jsirois had talked about extracting this info from wheel metadata in order to render better error messages, so that's another alternative. |
The info is only half the problem. How do you actually create a chroot with just the relevant dists and no others? |
[ci skip-rust-tests]
Unclear. A filtering operation on a pex? Or perhaps after splitting resolve from install, there will be other intermediate artifacts (...perhaps just wheels). |
OK, added the warning when the constraints don't cover the requirements (in all cases, regardless of the new flag), and added a test. |
Introduces a --python-setup-use-all-requirements flag.
If set, instead of resolving just the exact requirements
needed, we resolve the entire lockfile.
This prevents a huge amount of resolving work of all
the various requirement subsets needed by specific tests.
[ci skip-rust-tests]