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

specify minimum uv version in pyproject.toml #8605

Open
sebhoss opened this issue Oct 27, 2024 · 5 comments
Open

specify minimum uv version in pyproject.toml #8605

sebhoss opened this issue Oct 27, 2024 · 5 comments
Labels
configuration Settings and such needs-design Needs discussion, investigation, or design

Comments

@sebhoss
Copy link

sebhoss commented Oct 27, 2024

I recently noticed that the list of available python versions is hardcoded in uv and thus depends on the version of uv used. One of my colleagues was using an older version of uv and could not install python 3.13 without updating uv first. While updating uv is not a problem, I wish that there was a way to specify a minimum required version for uv itself when working on a project. I think this would improve developer experience because he would immediately have updated uv instead of debugging why the latest python version cannot be downloaded.

@nathanjmcdougall
Copy link
Contributor

Just to summarize some of the thinking from the duplicates, more generally we are wanting to set constraints on the version of uv, similar to how project.requires-python sets constraints on the version of Python.

Aside from a lower bound, I think the most useful constraint would be pinning/equality. I see limited value in upper bounds.

Pinning is useful in a CI pipeline to make sure breaking changes in uv don't break a deployment, etc. So for example, in the setup-uv GitHub Action (or other CI config), you can pin a version of uv. But then there can be inconsistencies between the developer's local uv version and the one used on CI (or different developer's local uv versions for that matter).

I personally had this situation recently in my organization with the release of v0.5.0 - a whole lot of pipelines failed. Pinning would have prevented this, which is what we're doing now. But now we need a hacky script which re-downloads a hard-coded version of uv per project - or some other workaround. If we could specify the version of uv in pyproject.toml, then this could be avoided.

A similar situation exists in regard to pre-commit-uv; you need to pin a version of uv. Actually, you're pinning the version of pre-commit-uv which is synchronized with uv itself. In any case, this introduces a similar issue where passing pre-commit depends on using the same version of uv as the one pinned in the pre-commit config. In addition, there is a similar issue to the one discussed at astral-sh/uv-pre-commit#23, where the version of e.g. ruff needs to be synchronized between the virtual environment and the pre-commit config. In this case, the user's installed uv version can mismatch with the one used by pre-commit. This could potentially be solved by allowing the pre-commit-uv implementation to respect a pinned uv version in pyproject.toml.

@dmarcoux
Copy link

dmarcoux commented Nov 19, 2024

Regarding pinning uv's version, I have a workaround for this. Maybe in the meantime this can help others, so here's how I do it.

In my git repository, I track uv's version in the file .uv-version, like this. I generate this file when my development environment is started with this command uv version | cut --delimiter=' ' --fields=2 > .uv-version. So this file is updated whenever I update the uv package. It's less error-prone since I don't have to remember to manually update the file .uv-version, it's just a matter of committing/pushing changes whenever I see them with git status.

As for continuous integration, this is how I pin uv's version with GitHub Actions:

(...)

jobs:
  continuous_integration:
    name: Continuous integration
    runs-on: ubuntu-24.04

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Fetch uv's version from .uv-version
        id: uv-version
        run: echo "uv-version=$(cat .uv-version)" >> "$GITHUB_OUTPUT"

      - name: Install uv with the version in .uv-version
        uses: astral-sh/setup-uv@v3
        with:
          version: ${{ steps.uv-version.outputs.uv-version }}
          enable-cache: true

(...)

You can see the whole workflow here.

Let me know if something isn't clear.

@sebhoss
Copy link
Author

sebhoss commented Nov 22, 2024

Just thinking out loud: What if uv somehow knows which version of itself introduced a certain feature? It could use that information to automatically calculate the minimal required uv version based on the features used in the current project and save the result in uv.lock right next to the required python version.

Users could then run something like uv pin python 3.13 and uv would automatically change the minimal required version to the version that first added python 3.13 support. Depending on how well this works, maybe there is no need for a new field in pyproject.toml at all?

@nathanjmcdougall
Copy link
Contributor

nathanjmcdougall commented Nov 22, 2024

@sebhoss I think you are describing a way to infer a lower bound based on project file contents. The issue with this is that the intended uv behaviour on a project can be implicit - e.g. we might be relying on a new environment variable provided in the latest version of uv, which earlier versions would ignore.

This goes in both directions - there might be a new default incoming in the latest version of uv which I don't want, so I'd want an upper bound to protect from breaking changes.

Another similar issue: I think this would require older versions of uv to identify the presence of future versions' features. Perhaps one could use heuristics like unrecognized [tool.uv] fields but in any case this would probably need to be backported functionality? Which I think is out of the question.

I think any solution would need to deal with the complexity of actually complying with the bounds (inferred or otherwise)- what should uv do in the situation where uv has the 'wrong' version? Probably there needs to be some uv installation cache to allow switching between uv versions without re-downloading.

@sebhoss
Copy link
Author

sebhoss commented Nov 22, 2024

@nathanjmcdougall yeah agreed on all points. I was just a concerned that introducing yet another version might make simple things like switching to a newer python version more annoying than it should be, e.g. consider:

  1. Update project.requires-python version in pyproject.toml first so that it includes the python version you want
  2. Update project.requires-uv (or whatever the name will be) to require a version of uv that supports the wanted python version
  3. Update .python-version file to finally get the new python version

That said, I don't really want to derail the conversation here and I think usability improvements can be made after introducing version constraints for uv itself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
configuration Settings and such needs-design Needs discussion, investigation, or design
Projects
None yet
Development

No branches or pull requests

4 participants