Skip to content
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

Filter out incompatible dists #398

Merged
merged 4 commits into from
Nov 13, 2023
Merged

Filter out incompatible dists #398

merged 4 commits into from
Nov 13, 2023

Conversation

konstin
Copy link
Member

@konstin konstin commented Nov 10, 2023

Filter out source dists and wheels whose requires-python from the simple api is incompatible with the current python version.

This change showed an important problem: When we use a fake python version for resolving, building source distributions breaks down because we can only build with versions we actually have.

This change became surprisingly big. The tests now require python 3.7 to be installed, but changing that would mean an even bigger change.

Fixes #388

// https://github.com/astral-sh/puffin/issues/388
if file
.requires_python
.clone()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm surprised this needs to clone -- is it necessary? Should VersionSpecifiers from implement From<&str>?

if let std::collections::btree_map::Entry::Vacant(entry) =
version_map.entry(version)
// Only add source dists compatible with the python version
// https://github.com/astral-sh/puffin/issues/388
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can omit the issue link here, folks can always look this up in the Git history.

@@ -15,7 +17,7 @@ pub struct File {
pub data_dist_info_metadata: Metadata,
pub filename: String,
pub hashes: Hashes,
pub requires_python: Option<String>,
pub requires_python: Option<LenientVersionSpecifiers>,
Copy link
Member

@charliermarsh charliermarsh Nov 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the type here should be VersionSpecifiers, right? As it is in Metadata21?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like I think the stored type should be VersionSpecifiers even if we use LenientVersionSpecifiers for parsing...

let interpreter_info = venv
.interpreter_info()
.clone()
.patch_markers(markers.clone().into_owned());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you say more about this? Don't we want to mirror the real markers in the resolver?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is so we use the fake python version everywhere including when recursing for builds, it's effectively #407

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean we'll end up trying to build source distributions that aren't actually supported? E.g., if we're using Python 3.7, but we use --python-version py312, when recursing, would we try to build Python 3.12-only source distributions?

let version = PubGrubVersion::from(filename.version.clone());
if let std::collections::btree_map::Entry::Vacant(entry) =
version_map.entry(version)
// Only add source dists compatible with the python version
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the right place to filter this?

It seems like it'd be ideal of we could reject these versions with a message (in the style of pubgrub-rs/pubgrub#152) so that the reason the versions are rejected are tracked in the derivation tree.

Copy link
Member

@charliermarsh charliermarsh Nov 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that would be better for sure. Resolvo has this concept too: dependencies that are available but don’t match the current platform. (I don’t see how we can support this right now though, and we already filter out incompatible wheels…)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay — the xref here will be enough for me to revisit if I get this functionality added to PubGrub.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, thank you!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like this, if that works in the pubgrub/resolvo models?

type VersionMap = BTreeMap<PubGrubVersion, MaybeDistFile>
enum MaybeDistFile {
    /// No compatible wheels and no source distribution (e.g. only an `.exe`)
    NoCompatiblePackage,
    /// No compatible wheels and the source distribution isn't compatible 
    VersionMismatch(VersionSpecifiers),
    ///
    Available {
        /// The highest priority file, usually a wheel
       picked: DistFile,
       /// Other installation candidates, such as lower priority compatible wheels and the source distribution if a wheel exists
        ///
        /// We track them here to add their hashes to the lockfile (the user may e.g. have a different glibc version)
        /// TODO(konstin): Check that this is actually how pip-tools generates the hashes list
       others: Vec<DistFile>
    }
}

otoh it might make more sense to keep those sdists in and instead give them a dependency on the python version, so we can properly report a conflict on root requiring python ==3.7, while pandas at the selected version requires python >3.9

Copy link
Member Author

@konstin konstin Nov 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@konstin
Copy link
Member Author

konstin commented Nov 13, 2023

My suggestion would be to merge this because it unblocks a bunch of downstream things where we currently fail on picking an invalid sdist and add the proper #406 solution later

Filter out source dists whose `requires-python` from the simple api is incompatible with the current python version.

This change showed an important problem: When we use a fake python version for resolving, building source distributions breaks down because we can only build with versions we actually have.

This change became surprisingly big.
@konstin konstin changed the title Filter out incompatible source dists Filter out incompatible dists Nov 13, 2023
---
success: true
exit_code: 0
----- stdout -----
# This file was autogenerated by Puffin v0.0.1 via the following command:
# [BIN_PATH] pip-compile requirements.in --constraint constraints.txt --cache-dir [CACHE_DIR]
anyio==4.0.0
exceptiongroup==1.1.3
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pip installs this one, too, so i assume it's correct

@@ -22,7 +22,9 @@ asgiref==3.7.2
django==5.0b1
sqlparse==0.4.3
# via django
typing-extensions==4.8.0
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pip installs this one, too, so i assume it's correct

@konstin konstin merged commit 76a4106 into main Nov 13, 2023
3 checks passed
@konstin konstin deleted the filter-out-sdists branch November 13, 2023 16:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Consider requires-python before selecting a source distribution
3 participants