-
-
Notifications
You must be signed in to change notification settings - Fork 634
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
Lockfile invalidation consumption #12448
Lockfile invalidation consumption #12448
Conversation
src/python/pants/backend/experimental/python/lockfile_metadata.py
Outdated
Show resolved
Hide resolved
src/python/pants/backend/experimental/python/lockfile_metadata.py
Outdated
Show resolved
Hide resolved
27f13b1
to
020777d
Compare
[ci skip-rust] [ci skip-build-wheels]
# Rust tests and lints will be skipped. Delete if not intended. [ci skip-rust] # Building wheels and fs_util will be skipped. Delete if not intended. [ci skip-build-wheels]
[ci skip-rust] [ci skip-build-wheels]
[ci skip-rust] [ci skip-build-wheels]
# Rust tests and lints will be skipped. Delete if not intended. [ci skip-rust] # Building wheels and fs_util will be skipped. Delete if not intended. [ci skip-build-wheels]
[ci skip-rust] [ci skip-build-wheels]
[ci skip-rust] [ci skip-build-wheels]
# Rust tests and lints will be skipped. Delete if not intended. [ci skip-rust] # Building wheels and fs_util will be skipped. Delete if not intended. [ci skip-build-wheels]
# Rust tests and lints will be skipped. Delete if not intended. [ci skip-rust] # Building wheels and fs_util will be skipped. Delete if not intended. [ci skip-build-wheels]
# Rust tests and lints will be skipped. Delete if not intended. [ci skip-rust] # Building wheels and fs_util will be skipped. Delete if not intended. [ci skip-build-wheels]
[ci skip-rust] [ci skip-build-wheels]
# Rust tests and lints will be skipped. Delete if not intended. [ci skip-rust] # Building wheels and fs_util will be skipped. Delete if not intended. [ci skip-build-wheels]
# Rust tests and lints will be skipped. Delete if not intended. [ci skip-rust] # Building wheels and fs_util will be skipped. Delete if not intended. [ci skip-build-wheels]
# Rust tests and lints will be skipped. Delete if not intended. [ci skip-rust] # Building wheels and fs_util will be skipped. Delete if not intended. [ci skip-build-wheels]
# Rust tests and lints will be skipped. Delete if not intended. [ci skip-rust] # Building wheels and fs_util will be skipped. Delete if not intended. [ci skip-build-wheels]
# Rust tests and lints will be skipped. Delete if not intended. [ci skip-rust] # Building wheels and fs_util will be skipped. Delete if not intended. [ci skip-build-wheels]
ed70791
to
0d691ad
Compare
# Rust tests and lints will be skipped. Delete if not intended. [ci skip-rust] # Building wheels and fs_util will be skipped. Delete if not intended. [ci skip-build-wheels]
# Rust tests and lints will be skipped. Delete if not intended. [ci skip-rust] # Building wheels and fs_util will be skipped. Delete if not intended. [ci skip-build-wheels]
# Rust tests and lints will be skipped. Delete if not intended. [ci skip-rust] # Building wheels and fs_util will be skipped. Delete if not intended. [ci skip-build-wheels]
@Eric-Arellano this is ready for review now |
# Rust tests and lints will be skipped. Delete if not intended. [ci skip-rust] # Building wheels and fs_util will be skipped. Delete if not intended. [ci skip-build-wheels]
# Rust tests and lints will be skipped. Delete if not intended. [ci skip-rust] # Building wheels and fs_util will be skipped. Delete if not intended. [ci skip-build-wheels]
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.
Awesome change!
lockfile_digest = None | ||
if lambdex.lockfile != "<none>": | ||
lockfile_request = await Get(PythonLockfileRequest, LambdexLockfileSentinel()) | ||
lockfile_digest = lockfile_request.hex_digest |
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.
Maybe lockfile_hash
? Now that I see this in an @rule
, the word "digest" is overloaded to think "directory digest" from pants.engine.fs
.
I think this could get really confusing, e.g. people accidentally using it with MergeDigests
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 still think that throwing around the word hash
in a Python database is likely to bring up similar confusion. That said, these lines from our JVM support make digest
on its own a non-starter for our lockfile support.
wheeeeeeeeeeeee
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.
Oh yeah true. Then, maybe being explicit is the key. invalidation_digest
or invalidation_hash
, but never just hash
or just digest
.
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'll go with hex_digest
, since that's what I'm using elsewhere.
raise ValueError("Invalid lockfile provided. [TODO: Improve message]") | ||
else: | ||
logger.warning("%s", "Invalid lockfile provided. [TODO: Improve message]") |
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.
Did you mean to address this here, or it will be a followup?
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.
It wasn't clear to me how to provide a really meaningful error here. I'll discuss this with you out-of-band
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.
Sg! Because this is experimental, it's fine to land in this state imo.
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.
Great. Let's follow up in a separate PR.
requirements_file_digest = await Get( | ||
Digest, | ||
PathGlobs( | ||
[request.requirements.file_path], | ||
glob_match_error_behavior=GlobMatchErrorBehavior.error, | ||
description_of_origin=request.requirements.file_path_description_of_origin, | ||
), | ||
PathGlobs, | ||
globs, |
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.
FYI this is split over 3 lines because there was a trailing comma so Black forces it to be split. You can get back to one line by removing the comma and rerunning Black.
You don't need to fix as that's what Black did, only an FYI. (can't remember if I've mentioned this already)
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.
👍
raise ValueError("Invalid lockfile provided. [TODO: Improve message]") | ||
else: | ||
logger.warning("%s", "Invalid lockfile provided. [TODO: Improve message]") |
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.
We will likely want this error message to differ from the one above. This is currently always the <default>
lockfile, whereas the above are always lockfiles checked in by the user. Our guidance is different depending on those two edge cases.
To formalize that implicit association, we may in a followup want to change PexRequirements
to be less generic than it is now, e.g. change the field to be "default_requirements_file: FileContentrather than
file_content: FileContent`.
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.
Addressing in a follow-up
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.
Okay, fair enough. I do think we have some tests using this style out there and iirc Benjy prefers your style - not blocking
@@ -535,3 +536,67 @@ def assert_description( | |||
use_repo_pex=True, | |||
expected="Extracting all requirements in lock.txt from repo.pex to build new.pex", | |||
) | |||
|
|||
|
|||
def test_error_on_invalid_lockfile_with_path(rule_runner: RuleRunner) -> None: |
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.
Subjective style suggestion, feel free to disagree. It may be more readable to have this in a single test that puts _run_pex_for_lockfile_test
as an inner helper function. These are all the same functionality, so I think makes sense to be in the same test as they're simply different edge cases of the same functionality. Kind of like pytest.parametrize.
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 thought about doing it that way, but my preferred behaviour is to match what pytest.parametrize
does, which is to run every case and report every failure. Each one of these tests is running a completely different code path, and the behaviour has to be tested in a different way, otherwise I'd have done it with parametrize
"--invalid-lockfile-behavior", | ||
advanced=True, | ||
type=InvalidLockfileBehavior, | ||
default=InvalidLockfileBehavior.warn, |
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 we talked about this a couple times, what the default should be. I can't remember what the conclusion was, but I'm thinking we should probably default to error
for now, at least until we get feedback from users it's an annoying default. We want to encourage people to do the right thing, and warnings are too easy to miss (e.g. in CI).
Lockfiles are feature gated, so this is fine to change.
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.
Fine by me.
Co-authored-by: Eric Arellano <14852634+Eric-Arellano@users.noreply.github.com>
# Rust tests and lints will be skipped. Delete if not intended. [ci skip-rust] # Building wheels and fs_util will be skipped. Delete if not intended. [ci skip-build-wheels]
# Rust tests and lints will be skipped. Delete if not intended. [ci skip-rust] # Building wheels and fs_util will be skipped. Delete if not intended. [ci skip-build-wheels]
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.
Thanks!
raise ValueError("Invalid lockfile provided. [TODO: Improve message]") | ||
else: | ||
logger.warning("%s", "Invalid lockfile provided. [TODO: Improve message]") |
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.
Okay, fair enough. I do think we have some tests using this style out there and iirc Benjy prefers your style - not blocking
Needs a new commit because of GitHub outage yesterday |
# Rust tests and lints will be skipped. Delete if not intended. [ci skip-rust] # Building wheels and fs_util will be skipped. Delete if not intended. [ci skip-build-wheels]
Turns out our lockfiles aren't quite valid: https://github.com/pantsbuild/pants/pull/12448/checks # Rust tests and lints will be skipped. Delete if not intended. [ci skip-rust] # Building wheels and fs_util will be skipped. Delete if not intended. [ci skip-build-wheels]
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.
The implementation looks good, but there is a lot of redundancy for consumers. It will be important to make doing the right thing easy, so it's possible that fixing some of that redundancy before landing would be good.
@@ -86,10 +87,15 @@ async def package_python_awslambda( | |||
], | |||
) | |||
|
|||
lockfile_hex_digest = None | |||
if lambdex.lockfile != "<none>": |
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 magic string ended up peppered a lot of places. Would be good to have def lockfile
convert "<none>"
to str | None
instead.
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.
Imo fine to do in a followup. This code path is still changing frequently.
if python_protobuf_mypy_plugin.lockfile != "<none>": | ||
lockfile_request = await Get(PythonLockfileRequest, MypyProtobufLockfileSentinel()) | ||
lockfile_hex_digest = lockfile_request.hex_digest |
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 code is very redundant...
Could PexRequest
take the sentinel type + lockfile and make this request for you instead? Or could the sentinel type be converted into a wrapper around the filename (i.e., no longer just a sentinel)?
Or, more fundamentally, should PexRequest.requirements
become a union of PexRequirements | PythonToolRequirementsBase
?
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 will absolutely want to fix this, but it's fine in a followup.
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 recommend we wait to fix this. For example, #12542 will make lots of changes to these call sites.
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 don't particularly like this code, and I'd be happy to take suggestions on how to make the improvement.
# Rust tests and lints will be skipped. Delete if not intended. [ci skip-rust] # Building wheels and fs_util will be skipped. Delete if not intended. [ci skip-build-wheels]
These were missed in #12448. To reduce the risk of this happening again, we remove the default argument for `PythonToolBase.pex_requirements(expected_lockfile_hex_digest)`. In the process, I realized that Pylint is not actually consuming it's lockfile at all because of how we handle first-party plugins. I'll address that in a followup that adds lockfile support to MyPy. [ci skip-rust] [ci skip-build-wheels]
Addresses #12415
This adds tools for consuming the lockfile invalidation digests that were added in #12427, both for lockfiles specified for the project, and for individual build tools.
Behavior on invalid lockfiles can be configured to either be a warning or an error.