Repository: astral-sh/uv
File: crates/uv-resolver/src/lock/mod.rs (Rust)

Code before:

        let packages = packages.into_values().collect();

        let options = ResolverOptions {
            resolution_mode: resolution.options.resolution_mode,
            prerelease_mode: resolution.options.prerelease_mode,
            fork_strategy: resolution.options.fork_strategy,
            exclude_newer: resolution.options.exclude_newer.clone().into(),
        };
        let lock = Self::new(
            VERSION,
            REVISION,
            packages,
            requires_python,
            options,
            ResolverManifest::default(),
            Conflicts::empty(),
            vec![],
            vec![],
            resolution.fork_markers.clone(),
        )?;
        Ok(lock)
    }

    /// Initialize a [`Lock`] from a list of [`Package`] entries.
    fn new(
        version: u32,
        revision: u32,
        mut packages: Vec<Package>,
        requires_python: RequiresPython,
        options: ResolverOptions,
        manifest: ResolverManifest,
        conflicts: Conflicts,
        supported_environments: Vec<MarkerTree>,
        required_environments: Vec<MarkerTree>,
        fork_markers: Vec<UniversalMarker>,
    ) -> Result<Self, LockError> {
        // Put all dependencies for each package in a canonical order and
        // check for duplicates.
        for package in &mut packages {
            package.dependencies.sort();
            for windows in package.dependencies.windows(2) {
                let (dep1, dep2) = (&windows[0], &windows[1]);
                if dep1 == dep2 {
                    return Err(LockErrorKind::DuplicateDependency {
                        id: package.id.clone(),
                        dependency: dep1.clone(),
                    }
                    .into());
                }
            }

Review comment (suggestion):
I think what confuses me is that deserializing a lock file is already doing this step?

https://github.com/astral-sh/uv/blob/7ba594650ac8baa3fef162f3d72c488208af3b6e/crates/uv-resolver/src/lock/mod.rs#L2279-L2284

Code after:
                        dependency_dist,
                        marker,
                        root,
                    )?;
                }
            }
        }

        let packages = packages.into_values().collect();

        let options = ResolverOptions {
            resolution_mode: resolution.options.resolution_mode,
            prerelease_mode: resolution.options.prerelease_mode,
            fork_strategy: resolution.options.fork_strategy,
            exclude_newer: resolution.options.exclude_newer.clone().into(),
        };
        // Normalize fork markers with a simplify/complexify round-trip through
        // `requires-python`. This ensures markers from the resolver (which don't include
        // `requires-python` bounds) match markers deserialized from the lockfile (which get
        // complexified on read).
        let fork_markers = resolution
            .fork_markers
            .iter()
            .map(|marker| {
                let simplified = SimplifiedMarkerTree::new(&requires_python, marker.combined());
                UniversalMarker::from_combined(simplified.into_marker(&requires_python))
            })
            .collect();
        let lock = Self::new(
            VERSION,
            REVISION,
            packages,
            requires_python,
            options,
            ResolverManifest::default(),
            Conflicts::empty(),
            vec![],
            vec![],
            fork_markers,
        )?;
        Ok(lock)
    }

    /// Initialize a [`Lock`] from a list of [`Package`] entries.
    fn new(
        version: u32,
        revision: u32,
        mut packages: Vec<Package>,
        requires_python: RequiresPython,
        options: ResolverOptions,
        manifest: ResolverManifest,