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

uv pip compile --universal not picking up required transitive dependency for certain python versions #11304

Open
brendan-morin opened this issue Feb 7, 2025 · 4 comments
Labels
question Asking for clarification or support

Comments

@brendan-morin
Copy link

brendan-morin commented Feb 7, 2025

Summary

Overview

I'm seeing some weird behavior where uv pip compile --universal does not seem to properly resolve the async-timeout transitive dependency of aiohttp, which is only required for python < 3.11. We can see this dep listed here.

It does seem to work if --python-version is specified to a lower version (despite warning it doesn't exist), though this doesn't seem to be the intended outcome reading the docs/help strings for --universal and --python-version.

Repro

uv.toml

python-install-mirror = "https://..." # Internal mirror
python-preference = "managed"

[[index]]
url = internal index
default = true
native-tls = true

requirements.in

aiohttp==3.11.11

Commands:

uv pip compile --universal requirements.in

Output:

Resolved 9 packages in 10ms
# This file was autogenerated by uv via the following command:
#    uv pip compile --universal requirements.in
aiohappyeyeballs==2.4.4
    # via aiohttp
aiohttp==3.11.11
    # via -r requirements/test.in
aiosignal==1.3.2
    # via aiohttp
attrs==25.1.0
    # via aiohttp
frozenlist==1.5.0
    # via
    #   aiohttp
    #   aiosignal
idna==3.10
    # via yarl
multidict==6.1.0
    # via
    #   aiohttp
    #   yarl
propcache==0.2.1
    # via
    #   aiohttp
    #   yarl
yarl==1.18.3
    # via aiohttp

versions:

uv --version

> uv 0.5.29 (ca73c4754 2025-02-05)

python --version

> Python 3.11.8

Note that running using --python 3.10 provides a warning that it does not exist, but provides the expected output below now: async-timeout==5.0.1 ; python_full_version < '3.11'

uv pip compile --universal --python-version 3.10 requirements.in
warning: The requested Python version 3.10 is not available; 3.11.8 will be used to build dependencies instead.
Resolved 11 packages in 5ms
# This file was autogenerated by uv via the following command:
#    uv pip compile --universal --python-version 3.10  requirements.in
aiohappyeyeballs==2.4.4
    # via aiohttp
aiohttp==3.11.11
    # via -r requirements/test.in
aiosignal==1.3.2
    # via aiohttp
async-timeout==5.0.1 ; python_full_version < '3.11'
    # via aiohttp
attrs==25.1.0
    # via aiohttp
frozenlist==1.5.0
    # via
    #   aiohttp
    #   aiosignal
idna==3.10
    # via yarl
multidict==6.1.0
    # via
    #   aiohttp
    #   yarl
propcache==0.2.1
    # via
    #   aiohttp
    #   yarl
typing-extensions==4.12.2 ; python_full_version < '3.11'
    # via multidict
yarl==1.18.3
    # via aiohttp

Cargo culting

One more note, and take this with a grain of salt, but I am 80% sure it initially did not resolve the transitive dep when using--python-version 3.10, but then after removing python-preference = "managed" from my uv.toml and then rerunning, it seemed to now work (though I am unable to reproduce that behavior now). I am only including this in case it is somehow related to existing uv python versions on the system.

Platform

macOS

Version

uv 0.5.29 (ca73c47 2025-02-05)

Python version

Python 3.11.8

@brendan-morin brendan-morin added the bug Something isn't working label Feb 7, 2025
@charliermarsh
Copy link
Member

If you don't specify a --python-version, I believe we'll use the discovered Python as the minimum supported version. So, in this case, it looks like we're resolving for Python 3.11.8 and later -- in which case, async-timeout can be omitted, since it's never relevant on those versions!

@brendan-morin
Copy link
Author

I think that’s sensible enough. Maybe more of a documentation fix then, the cli help doesn’t seem to imply this limitation.

@zanieb
Copy link
Member

zanieb commented Feb 7, 2025

We do have this in the documentation

❯ uv help pip compile | grep "default minimum Python" -B 8

Python options:
      --python <PYTHON>
          The Python interpreter to use during resolution.
          
          A Python interpreter is required for building source distributions to
          determine package metadata when there are not wheels.
          
          The interpreter is also used to determine the default minimum Python

and

❯ uv help pip compile | grep "\-\-universal" -A 4
      --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.
          
          In universal mode, the current Python version (or user-provided `--python-version`) will be treated as a lower
          bound. For example, `--universal --python-version 3.7` would produce a universal resolution for Python 3.7 and
          later.
          
          Implies `--no-strip-markers`.

@zanieb zanieb added question Asking for clarification or support and removed bug Something isn't working labels Feb 7, 2025
@brendan-morin
Copy link
Author

brendan-morin commented Feb 7, 2025

Interesting, it looks like maybe the --help docs are out of sync with the uv help docs? Or perhaps just an unfortunate caveat cut off from concise vs detailed docs.

> uv pip compile --help | grep "default minimum Python" -B 8 

> uv pip compile --help | grep "\-\-universal" -A 4
      --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
      --no-emit-package <NO_EMIT_PACKAGE>                Specify a package to omit from the output resolution. Its dependencies will still be included in the
                                                         resolution. Equivalent to pip-compile's `--unsafe-package` option
      --emit-index-url                                   Include `--index-url` and `--extra-index-url` entries in the generated output file

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Asking for clarification or support
Projects
None yet
Development

No branches or pull requests

3 participants