I was trying to avoid having two separate arrays for specifying supported roots into the graph. I’m open to making them separate.
But that’s not required, it’s just a choice.
No ambiguity in following the graph in the same group. This allows for having e.g., a group for the newest versions of things and a group with the oldest version of things in the same lock file, but also not having a more complicated installer algorithm beyond “follow the edges whose markers you support” (i.e. how to guarantee no resolving in the installer by having to make any decisions).
See my answer above; without groups you can’t segment the packages to avoid conflicts in versions and other things if you want everything in one lock file.
For that group, yes.
Sorry, this is hard to follow as you seem to be referring to packages and groups with the same letters (plus I don’t know what you mean by “workspace” as that’s not a defined term in the PEP or Python packaging in general).
But if I’m following correctly, if group A was to use the same packages as group B in some instances, then you would either do groups = ["A", "B"] or list the packages twice, once in each group.
Not if you skip extras that you didn’t lock for. Let’s say you lock for spam[fast], but skipped spam[compat]. This would be recorded in [[groups]] by only recording the one case. But if you left that detail out and tried to enter the graph at spam, you would have to walk the graph first to know that the lock file won’t succeed in your case.
So you’re right, you don’t have to record the supported roots, but if lock files are meant to be self-contained then you’re saying you always have to know what you want to install and that you won’t know if it even feasible until you try it, versus looking at the lock file and seeing what it recorded as what it’s meant for. So it’s a question around ergonomics of treating lock files as self-contained and how much should they try to make themselves easier to work with in total isolation?
Groups also help with ambiguity when the same package is listed multiple times for different versions.
I think it depends on whether you expect any and all extras for every package in the lock file to be supported? If the answer is “yes” then you’re right. If you say “no, but that’s okay to find out later”, then you’re also right. But if you say, “no, and you should know that upfront”, then treating a project as an explicit root makes sense to me.
This is why I hate sdists in lock files.
Let me turn that around and ask how you support that in uv? The only way I see that working is not keying packages off of their name and version but off of the file source, but that’s a bit a shift from how packaging has worked up to this point.
That’s where groups come in; different group for different needs.
Only way I can see that working is if you propagate up the 'darwin' marker requirement to two different requirements under root (or two separate groups). Otherwise what’s your proposal to solve it without getting a resolver involved?
Create a group for that child’s dependency groups.
I think there might be a misunderstanding here: the lock file is not expected to cover any and all paths down all edges of the graph at any arbitrary node. That could lead to a massive graph and a long resolve time for locking (but probably not installing). So I don’t expect you to want all of the extra stuff some random package version has.
Separate from that, I don’t view dependency groups as something you would install from some arbitrary dependency, but from the project you’re directly working with. So going with your workspace example (which, once again, isn’t a defined concept, so I’m somewhat guessing here), if you had a monorepo where you wanted to support all dependency groups in all projects, then you would explicitly do that with separate groups.
Yes, they are a top-level thing, but I don’t think they are mutually-exclusive.
Ah, is this what you mean by “writing the resolved versions on the edges” (even though groups as not versions directly)? As in you select the group and instead of filtering at the [[packages]] level you filter at the requirements level? Or filter at both levels since you still have to pick the correct version somehow (and the PEP currently handles that by saying, “there can only be one package version”)?


I’m going to ask the direct question here and say what design choice do you think I’m missing here? What’s your proposal of how the graph should be laid out in the file?