pylock.select: fail on unknown extras and dependency groups - #1376
Open
sbidoul wants to merge 3 commits into
Open
pylock.select: fail on unknown extras and dependency groups#1376sbidoul wants to merge 3 commits into
sbidoul wants to merge 3 commits into
Conversation
sbidoul
force-pushed
the
pylock-select-reject-unknown-groups-extras-sbi
branch
2 times, most recently
from
August 9, 2026 17:47
e03728b to
99ab5eb
Compare
sbidoul
force-pushed
the
pylock-select-reject-unknown-groups-extras-sbi
branch
from
August 9, 2026 17:49
99ab5eb to
c9cda9a
Compare
sbidoul
commented
Aug 9, 2026
…groups exist The spec says membes of default-groups should not be listed in dependency-groups.
sbidoul
force-pushed
the
pylock-select-reject-unknown-groups-extras-sbi
branch
from
August 10, 2026 06:43
e11f62b to
588863c
Compare
henryiii
reviewed
Aug 18, 2026
henryiii
left a comment
Contributor
There was a problem hiding this comment.
Looks good, I also ran a review (below). We type this to a Sequence, so the correctness isn't technically correct, but if we could support Iterable instead easily (the old version did support one-shot iterables), I think that would be nice.
🤖 AI text below 🤖
- Correctness:
select()now iterates the extras and dependency_groups parameters twice (validation, then env building), so a one-shot iterable is exhausted by the new check and silently selects nothing instead of raising. - Simplification: The new validation block repeats the
{canonicalize_name(x) for x in (seq or [])}comprehension four times, including two unioned comprehensions that could be one comprehension over the chained sequences.
Diff:
diff --git a/src/packaging/pylock.py b/src/packaging/pylock.py
index 81e51de..03107c0 100644
--- a/src/packaging/pylock.py
+++ b/src/packaging/pylock.py
@@ -653,34 +653,29 @@ class Pylock:
Raise :class:`PylockSelectError` if passed extras or dependency groups
that are not declared in the corresponding pylock fields.
"""
- if extras:
- unknown_extras = {canonicalize_name(extra) for extra in extras} - set(
- self.extras or []
+ canonical_extras = {canonicalize_name(extra) for extra in extras or ()}
+ unknown_extras = canonical_extras - set(self.extras or ())
+ if unknown_extras:
+ raise PylockSelectError(
+ f"Undeclared extras: {', '.join(sorted(unknown_extras))}"
)
- if unknown_extras:
- raise PylockSelectError(
- f"Undeclared extras: {', '.join(sorted(unknown_extras))}"
- )
- if dependency_groups:
- unknown_dependency_groups = {
- canonicalize_name(dependency_group)
- for dependency_group in dependency_groups
- } - (
- {
- canonicalize_name(dependency_group)
- for dependency_group in self.dependency_groups or []
- }
- | {
- canonicalize_name(dependency_group)
- for dependency_group in self.default_groups or []
- }
+ canonical_dependency_groups = {
+ canonicalize_name(dependency_group)
+ for dependency_group in dependency_groups or ()
+ }
+ unknown_dependency_groups = canonical_dependency_groups - {
+ canonicalize_name(dependency_group)
+ for dependency_group in [
+ *(self.dependency_groups or ()),
+ *(self.default_groups or ()),
+ ]
+ }
+ if unknown_dependency_groups:
+ raise PylockSelectError(
+ f"Undeclared dependency groups: "
+ f"{', '.join(sorted(unknown_dependency_groups))}"
)
- if unknown_dependency_groups:
- raise PylockSelectError(
- f"Undeclared dependency groups: "
- f"{', '.join(sorted(unknown_dependency_groups))}"
- )
compatible_tags_selector = create_compatible_tags_selector(
tags if tags is not None else sys_tags()
@@ -696,11 +691,11 @@ class Pylock:
"dict[str, str | frozenset[str]]",
dict(
environment or {}, # Marker.evaluate will fill-up
- extras=frozenset(extras or []),
+ extras=frozenset(canonical_extras),
dependency_groups=frozenset(
(self.default_groups or [])
if dependency_groups is None # to allow selecting no group
- else dependency_groups
+ else canonical_dependency_groups
),
),
)
Member
Author
|
@henryiii I applied the suggested diff. |
henryiii
approved these changes
Aug 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
With this PR,
Pylock.select()now fails when providedextrasordependency_groupsthat are not declared in the lock file.Strictly speaking this is a breaking change, since before it would silently skip packages.
However the API is young, and I feel that the current behaviour is surprising, so I propose this change.
Consumers that wish to ignore instead of failing can easily pre-filter (and likely warn their users in such cases).
Alternatives are enabling this new check with a flag, or doing nothing and leave such validation to consumers.