-
Notifications
You must be signed in to change notification settings - Fork 636
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
Normalize extras in lockfile #3958
Conversation
crates/uv-resolver/src/lock.rs
Outdated
pub(crate) source: Source, | ||
} | ||
|
||
impl DistributionId { | ||
fn from_annotated_dist(annotated_dist: &AnnotatedDist) -> DistributionId { | ||
pub(crate) fn from_annotated_dist(annotated_dist: &AnnotatedDist) -> DistributionId { |
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.
Not thrilled that I'm making so many things pub(crate)
here. Should I change ResolutionGraph::to_lock
into a impl TryFrom<ResolutionGraph
for Lock
?
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 kind of bias toward concrete and bespoke (but conventional) conversion routines like ResolutionGraph::to_lock
unless there's a specific need for generic fallible conversions.
I think this is more of a stylistic choice, but I'd say it's just a specific manifestation of "don't go generic unless there's a reason to." And with specific conversion routines, it's straight-forward to add more parameters if they ever become necessary.
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.
Ooooooooo, I completely misunderstood your question. You were suggesting the TryFrom
impl so that the conversion would be defined in this module, and that would in turn prevent exposing stuff.
Yeah I think I'd do that. Although, following from my previous comment, I'd probably just define Lock::from_resolution_graph
or something. And that might in turn require exposing more stuff from the graph, but maybe that's okay.
(I don't think we've really settled on a great balance here. I wonder, for example, whether it really makes sense to have a ResolutionGraph
at all. But this gets to the "installation might want different types" idea that's been floating around. It's a bigger refactor for sure.)
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'm also not totally convinced that ResolutionGraph
will be necessary in the long run.
@BurntSushi - Ignoring the code, curious if you prefer this representation? |
CodSpeed Performance ReportMerging #3958 will not alter performanceComparing Summary
|
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 new representation generally makes sense to me.
Would it make more sense to put optional dependencies under distributions.extras."name".dependencies
? Could we ever want to put other information under distributions.extras."name"
?
let mut locked_dist = lock::Distribution::from_annotated_dist(dist)?; | ||
for neighbor in self.petgraph.neighbors(node_index) { | ||
let dependency_dist = &self.petgraph[neighbor]; | ||
locked_dist.add_dependency(dependency_dist); | ||
} | ||
locked_dists.push(locked_dist); | ||
if let Some(locked_dist) = locked_dists.insert(locked_dist.id.clone(), locked_dist) { |
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.
Why could the previous code do an unconditional push
here?
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 I'd echo @ibraheemdev's question. Otherwise, this generally LGTM. If it's possible, I think I would prefer a way where we're not slapping pub(crate)
on everything, but I don't feel too strongly at this point while we're still trying to figure out what the data types should be.
crates/uv-resolver/src/lock.rs
Outdated
pub(crate) source: Source, | ||
} | ||
|
||
impl DistributionId { | ||
fn from_annotated_dist(annotated_dist: &AnnotatedDist) -> DistributionId { | ||
pub(crate) fn from_annotated_dist(annotated_dist: &AnnotatedDist) -> DistributionId { |
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 kind of bias toward concrete and bespoke (but conventional) conversion routines like ResolutionGraph::to_lock
unless there's a specific need for generic fallible conversions.
I think this is more of a stylistic choice, but I'd say it's just a specific manifestation of "don't go generic unless there's a reason to." And with specific conversion routines, it's straight-forward to add more parameters if they ever become necessary.
crates/uv-resolver/src/lock.rs
Outdated
pub(crate) source: Source, | ||
} | ||
|
||
impl DistributionId { | ||
fn from_annotated_dist(annotated_dist: &AnnotatedDist) -> DistributionId { | ||
pub(crate) fn from_annotated_dist(annotated_dist: &AnnotatedDist) -> DistributionId { |
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.
Ooooooooo, I completely misunderstood your question. You were suggesting the TryFrom
impl so that the conversion would be defined in this module, and that would in turn prevent exposing stuff.
Yeah I think I'd do that. Although, following from my previous comment, I'd probably just define Lock::from_resolution_graph
or something. And that might in turn require exposing more stuff from the graph, but maybe that's okay.
(I don't think we've really settled on a great balance here. I wonder, for example, whether it really makes sense to have a ResolutionGraph
at all. But this gets to the "installation might want different types" idea that's been floating around. It's a bigger refactor for sure.)
I think I will leave the representation as-is for now because it closely mirrors the |
ec7ee43
to
eaa1c91
Compare
Summary
Previously, when we locked something like
flask[dotenv]
, we created two separate distributions in the lockfile: one forflask
, which included the base dependencies, and one forflask[dotenv]
, which included the base dependencies and thedotenv
dependencies. This was easy to implement, but it meant that we were duplicating all of the distribution files for every extra, and duplicating all of the base dependencies for every extra.This PR normalizes the data such that we now have one entry per distribution (i.e.,
ExtraName
was removed fromDistributionId
), with an optional dependencies table with an entry per extra, like:This requires a bit more work upfront, because we now need to merge multiple packages from the
PetGraph
representation when creating the lockfile.Closes #3916.