astral-sh / uv

An extremely fast Python package and project manager, written in Rust.
https://docs.astral.sh/uv
Apache License 2.0
20.3k stars 603 forks source link

`--universal` output incompatible with `requires-python` #6031

Open blueraft opened 1 month ago

blueraft commented 1 month ago

Simple MRE:

[project]
name = "foobar"
version = "0.1"
requires-python = ">=3.9"
dependencies = ["networkx"]
❯ uv pip compile pyproject.toml --universal
Resolved 1 package in 16ms
# This file was autogenerated by uv via the following command:
#    uv pip compile pyproject.toml --universal
networkx==3.3
    # via foobar (pyproject.toml)

The output is not universal since networkx==3.3 only supports >=py3.10.

❯ uv pip install -r requirements.txt
  × No solution found when resolving dependencies:
  ╰─▶ Because the current Python version (3.9.6) does not satisfy Python>=3.10 and networkx==3.3 depends on Python>=3.10, we can conclude that networkx==3.3 cannot be used.
      And because you require networkx==3.3, we can conclude that the requirements are unsatisfiable.

The lock file is correct though.

❯ cat uv.lock
version = 1
requires-python = ">=3.9"

[[package]]
name = "foobar"
version = "0.1"
source = { editable = "." }
dependencies = [
    { name = "networkx" },
]

[[package]]
name = "networkx"
version = "3.2.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/c4/80/a84676339aaae2f1cfdf9f418701dd634aef9cc76f708ef55c36ff39c3ca/networkx-3.2.1.tar.gz", hash = "sha256:9f1bb5cf3409bf324e0a722c20bdb4c20ee39bf1c30ce8ae499c8502b0b5e0c6", size = 2073928 }
wheels = [
    { url = "https://files.pythonhosted.org/packages/d5/f0/8fbc882ca80cf077f1b246c0e3c3465f7f415439bdea6b899f6b19f61f70/networkx-3.2.1-py3-none-any.whl", hash = "sha256:f18c69adc97877c42332c170849c96cefa91881c99a7cb3e95b7c659ebdc1ec2", size = 1647772 },
]

uv 0.2.35

blueraft commented 1 month ago

Huh can't reproduce this anymore, I'll close this.

ibraheemdev commented 1 month ago

I don't believe --universal reads requires-python from the input files, you have to specify -p 3.9. By default it will use the major and minor version of the current interpreter as a lower bound.

blueraft commented 1 month ago

Oh that's why the resolution got fixed.

Is there a reason why it doesn't read the requires-python from the pyproject.toml file?

      --universal                                        Perform a universal resolution, attempting to generate a single `requirements.txt` output file that is compatible with all operating systems,
                                                         architectures, and Python implementations

The 'and Python implementations' gives me the impression that it'd be compatible with requires-python in the project metadata.

zanieb commented 1 month ago

I think we don't want uv pip compile to implicitly read a pyproject.toml but maybe if it's explicitly provided we should use the metadata? I believe we discussed this previously cc @charliermarsh

charliermarsh commented 1 month ago

I'm a little hesitant to read from them but we can consider it.

blueraft commented 1 month ago

Maybe only for --universal, since that's a uv only thing?

charliermarsh commented 1 month ago

I think it probably does make sense to pick a Python that meets the requires-python for all provided pyproject.toml files.

blueraft commented 1 month ago

Happy to make a PR for this if you decide to support it!