Skip to content

Comments

Fix handling of != intersections in requires-python#7897

Merged
charliermarsh merged 1 commit intomainfrom
charlie/req
Oct 9, 2024
Merged

Fix handling of != intersections in requires-python#7897
charliermarsh merged 1 commit intomainfrom
charlie/req

Conversation

@charliermarsh
Copy link
Member

@charliermarsh charliermarsh commented Oct 3, 2024

Summary

The issue here is that, if you user has a requires-python like >= 3.7, != 3.8.5, this gets expanded to the following bounds:

  • [3.7, 3.8.5)
  • (3.8.5, ...

We then convert this to the specific >= 3.7, < 3.8.5, > 3.8.5. But the commas in that expression are conjunctions... So it's impossible to satisfy? No version is both < 3.8.5 and > 3.8.5.

Instead, we now preserve the input requires-python and just concatenate the terms, only using PubGrub to compute the bounds.

Closes #7862.

@charliermarsh charliermarsh added the bug Something isn't working label Oct 3, 2024
@charliermarsh charliermarsh marked this pull request as draft October 3, 2024 14:09
lock, @r###"
version = 1
requires-python = ">=3.11"
requires-python = ">=3.11b1"
Copy link
Member Author

Choose a reason for hiding this comment

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

We now retain this more-or-less verbatim. I think this is ok since we'll ignore these anywhere that it matters when we actually use it.

@charliermarsh charliermarsh requested a review from konstin October 3, 2024 14:24
@charliermarsh charliermarsh marked this pull request as ready for review October 3, 2024 14:24
let specifiers = range
.iter()
.flat_map(VersionSpecifier::from_release_only_bounds)
.collect();
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 isn't quite correct -- we can't just AND these, since a != specifier gets converted to < and > the value. So instead we retain the actual specifiers now.

----- stderr -----
Using CPython 3.8.[X] interpreter at: [PYTHON-3.8]
error: The requested interpreter resolved to Python 3.8.[X], which is incompatible with the project's Python requirement: `>=3.12`. However, a workspace member (`bird-feeder`) supports Python >=3.8. To install the workspace member on its own, navigate to `packages/bird-feeder`, then run `uv venv --python 3.8.[X]` followed by `uv pip install -e .`.
error: The requested interpreter resolved to Python 3.8.[X], which is incompatible with the project's Python requirement: `>=3.8, >=3.12`. However, a workspace member (`bird-feeder`) supports Python >=3.8. To install the workspace member on its own, navigate to `packages/bird-feeder`, then run `uv venv --python 3.8.[X]` followed by `uv pip install -e .`.
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 a pain. Maybe we do want to apply some simplifications here...? Like ignoring redundant clauses?

Copy link
Member Author

Choose a reason for hiding this comment

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

I guess we could do something like: only add the specifier if it changes the computed bounds? That could work.

Copy link
Member

@zanieb zanieb Oct 3, 2024

Choose a reason for hiding this comment

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

Can you use Range::subset_of?

Copy link
Member

Choose a reason for hiding this comment

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

Here's a POC of using subset_of. I'm guessing this can be done in a simpler way?

#8026

Copy link
Member Author

Choose a reason for hiding this comment

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

Good idea. I will do something like that to at least avoid these common cases.

Copy link
Member

Choose a reason for hiding this comment

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

My expectation is that we should be able to represent RequiresPython as a single pubgrub range, extracting the range's lower or upper bound as needed; My quick attempt at that failed though because there seem other constraints too.

Copy link
Member Author

Choose a reason for hiding this comment

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

I ended up writing a routine to convert to an "optimal" PEP 440 specifier using similar logic to the existing method, but for multiple bounds. It's kind of tedious but does work as expected.

@charliermarsh
Copy link
Member Author

@ibraheemdev -- You may be interested in this too.

@charliermarsh
Copy link
Member Author

Can I get review on this one?

let specifiers = combined.into_iter().collect();

Ok(Some(Self {
specifiers,
Copy link
Member

@zanieb zanieb Oct 8, 2024

Choose a reason for hiding this comment

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

Does the doc comment for this function (intersection) need to be updated?

@charliermarsh
Copy link
Member Author

I didn't mean to merge this as-is; I thought I had pushed #8060 but apparently I'm tired.

tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request Oct 15, 2024
This MR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [astral-sh/uv](https://github.com/astral-sh/uv) | patch | `0.4.20` -> `0.4.21` |

MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot).

**Proposed changes to behavior should be submitted there as MRs.**

---

### Release Notes

<details>
<summary>astral-sh/uv (astral-sh/uv)</summary>

### [`v0.4.21`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0421)

[Compare Source](astral-sh/uv@0.4.20...0.4.21)

##### Enhancements

-   Add support for managed installations of free-threaded Python ([#&#8203;8100](astral-sh/uv#8100))
-   Add note about `uvx` to `uv tool run` short help ([#&#8203;7695](astral-sh/uv#7695))
-   Enable HTTP/2 requests ([#&#8203;8049](astral-sh/uv#8049))
-   Support `uv tree --no-dev` ([#&#8203;8109](astral-sh/uv#8109))
-   Support PEP 723 metadata with `uv run -` ([#&#8203;8111](astral-sh/uv#8111))
-   Support `pip install --exact` ([#&#8203;8044](astral-sh/uv#8044))
-   Support `uv export --no-header` ([#&#8203;8096](astral-sh/uv#8096))
-   ADd Python 3.13 images to Docker publish ([#&#8203;8105](astral-sh/uv#8105))
-   Support remote (`https://`) scripts in `uv run` ([#&#8203;6375](astral-sh/uv#6375))
-   Allow comma value-delimited arguments in `uv run --with` ([#&#8203;7909](astral-sh/uv#7909))

##### Configuration

-   Support wildcards in `UV_INSECURE_HOST` ([#&#8203;8052](astral-sh/uv#8052))

##### Performance

-   Use shared index when fetching metadata in lock satisfaction routine ([#&#8203;8147](astral-sh/uv#8147))

##### Bug fixes

-   Add prerelease compatibility check to `uv python` CLI ([#&#8203;8020](astral-sh/uv#8020))
-   Avoid deleting a project environment directory if we cannot tell if a `pyvenv.cfg` file exists ([#&#8203;8012](astral-sh/uv#8012))
-   Avoid excluding valid wheels for exact `requires-python` bounds ([#&#8203;8140](astral-sh/uv#8140))
-   Bump `netrc` crate to latest commit ([#&#8203;8021](astral-sh/uv#8021))
-   Fix `uv python pin 3.13t` failure when parsing version for project requires check ([#&#8203;8056](astral-sh/uv#8056))
-   Fix handling of != intersections in `requires-python` ([#&#8203;7897](astral-sh/uv#7897))
-   Remove the newly created tool environment if sync failed ([#&#8203;8038](astral-sh/uv#8038))
-   Respect dynamic extras in `uv lock` and `uv sync` ([#&#8203;8091](astral-sh/uv#8091))
-   Treat resolver failures as fatal in lockfile validation ([#&#8203;8083](astral-sh/uv#8083))
-   Use `git config --get` for author information for improved backwards compatibility ([#&#8203;8101](astral-sh/uv#8101))
-   Use comma-separated values for `UV_FIND_LINKS` ([#&#8203;8061](astral-sh/uv#8061))
-   Use shared resolver state between add and lock to avoid double Git update ([#&#8203;8146](astral-sh/uv#8146))
-   Make `--relocatable` entrypoints robust to symlinking ([#&#8203;8079](astral-sh/uv#8079))
-   Improve compatibility with VSCode PS1 prompt ([#&#8203;8006](astral-sh/uv#8006))
-   Fix "Stream did not contain valid UTF-8" failures in Windows ([#&#8203;8120](astral-sh/uv#8120))
-   Use `--with-requirements` in `uvx` error hint ([#&#8203;8112](astral-sh/uv#8112))

##### Documentation

-   Include `uvx` installation in Docker examples ([#&#8203;8179](astral-sh/uv#8179))
-   Make the instructions for the Windows standalone installer consistent across README and documentation ([#&#8203;8125](astral-sh/uv#8125))
-   Update pip compatibility guide to note transitive URL dependency support ([#&#8203;8081](astral-sh/uv#8081))
-   Document `--reinstall` with `--exclude-newer` to ensure downgrades ([#&#8203;6721](astral-sh/uv#6721))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this MR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40NDAuNyIsInVwZGF0ZWRJblZlciI6IjM3LjQ0MC43IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJSZW5vdmF0ZSBCb3QiXX0=-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

requires-python specification not correctly resolved

3 participants