Skip to content
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

Merged
merged 5 commits into from Jul 21, 2020

Conversation

benjyw
Copy link
Sponsor Contributor

@benjyw benjyw commented Jul 19, 2020

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]

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]
@coveralls
Copy link

coveralls commented Jul 19, 2020

Coverage Status

Coverage remained the same at 0.0% when pulling 881ec72 on benjyw:resolve_everything into 669b5f3 on pantsbuild:master.

@benjyw
Copy link
Sponsor Contributor Author

benjyw commented Jul 20, 2020

PS feel free to bikeshed the flag name

Copy link
Contributor

@Eric-Arellano Eric-Arellano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

Comment on lines 56 to 58
# 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,
Copy link
Contributor

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.

src/python/pants/python/python_setup.py Outdated Show resolved Hide resolved
src/python/pants/python/python_setup.py Outdated Show resolved Hide resolved
src/python/pants/backend/python/rules/pex_from_targets.py Outdated Show resolved Hide resolved
src/python/pants/backend/python/rules/pex_from_targets.py Outdated Show resolved Hide resolved
Comment on lines 416 to 417
# 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.
Copy link
Contributor

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.

src/python/pants/python/python_setup.py Outdated Show resolved Hide resolved
# Rust tests will be skipped. Delete if not intended.
[ci skip-rust-tests]
@benjyw
Copy link
Sponsor Contributor Author

benjyw commented Jul 20, 2020

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)

@benjyw
Copy link
Sponsor Contributor Author

benjyw commented Jul 20, 2020

@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).

Copy link
Sponsor Member

@stuhood stuhood left a 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
Copy link
Sponsor Member

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.

Copy link
Contributor

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.

Copy link
Sponsor Member

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

Copy link
Contributor

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.

Copy link
Sponsor Contributor Author

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.

pants.toml Show resolved Hide resolved
src/python/pants/python/python_setup.py Outdated Show resolved Hide resolved
src/python/pants/python/python_setup.py Outdated Show resolved Hide resolved
Copy link
Contributor

@Eric-Arellano Eric-Arellano left a 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!

@benjyw
Copy link
Sponsor Contributor Author

benjyw commented Jul 21, 2020

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.

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?

@stuhood
Copy link
Sponsor Member

stuhood commented Jul 21, 2020

For example, creating the relevant subset means, I assume, symlink farming.

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.

@benjyw
Copy link
Sponsor Contributor Author

benjyw commented Jul 21, 2020

For example, creating the relevant subset means, I assume, symlink farming.

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?

@stuhood
Copy link
Sponsor Member

stuhood commented Jul 21, 2020

The info is only half the problem. How do you actually create a chroot with just the relevant dists and no others?

Unclear. A filtering operation on a pex? Or perhaps after splitting resolve from install, there will be other intermediate artifacts (...perhaps just wheels).

[ci skip-rust-tests]
@benjyw
Copy link
Sponsor Contributor Author

benjyw commented Jul 21, 2020

OK, added the warning when the constraints don't cover the requirements (in all cases, regardless of the new flag), and added a test.

@benjyw benjyw merged commit 45ca5b4 into pantsbuild:master Jul 21, 2020
@benjyw benjyw deleted the resolve_everything branch August 7, 2020 18:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants