astral-sh / uv

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

uv fails to install correct odrive version on old macOS #8536

Open alecrobertson opened 4 hours ago

alecrobertson commented 4 hours ago

I'm using uv on two macOS systems -- a newer M1 on macOS 15.1, and an old Intel pegged to 11.7. I'm trying to install the odrive package. Newer odrive packages (>0.6.8) require macOS 12+, so I can install 0.6.9.post0 on the M1 but only 0.6.8 on the Intel.

If I don't use uv (and use requirements.txt and pip instead) I can specify odrive >= 0.6.8 in requirements.txt and pip install -r requirements.txt will choose the correct package version on both platforms (0.6.8 on the Intel, 0.6.9.post0 on the M1).

If I use uv with odrive>=0.6.8 in pyproject.toml, uv will try to install 0.6.9.pos0 on the Intel and will fail.

I can force uv to install 0.6.8 on the Intel using uv pip install -r requirements.txt but uv tree still shows 0.6.9.post0 and some functionality (uv run for example) is broken.

I can edit the pyproject.toml on the Intel to force "odrive==0.6.8" and keep the changes local, but I'm hoping to find a cross-platform solution.

Any recommendations?

charliermarsh commented 4 hours ago

Are you installing from PyPI?

alecrobertson commented 4 hours ago

Yes

charliermarsh commented 3 hours ago

This is an area where the package isn't well-setup for uv's model of universal resolution: there's no source distribution, and some set of wheels, but the wheels don't cover the entire set of possible platforms. We basically have to assume that they do, since the set of possible platforms is infinite and not known in advance. So the resolver picks 0.6.9, but we then fail (I assume) to find a compatible wheel when you're on Intel.

I can force uv to install 0.6.8 on the Intel using uv pip install -r requirements.txt but uv tree still shows 0.6.9.post0 and some functionality (uv run for example) is broken.

This works because uv pip install -r requirements.txt will only install and resolve for the current platform, whereas uv tree and uv run use the universal resolver. They're two different modes of working that you typically don't want to mix-and-match -- you should either use the uv pip interface or uv run (plus uv sync, uv lock). (They can be mixed and matched, but that's mostly for power users.)

I think what you want here is to declare a different version for Intel macOS, like:

[project]
dependencies = [
    "odrive < 0.6.9 ; platform_system == 'Darwin' and platform_machine == 'x86_64'",
    "odrive >= 0.6.9; platform_system != 'Darwin' or platform_machine != 'x86_64'",
]
alecrobertson commented 2 hours ago

Thanks for the suggestion, that worked. I tweaked it to use platform_release instead of _machine:

dependencies = [
    "odrive == 0.6.8 ; platform_system == 'Darwin' and platform_release <= '20.6.0'",
    "odrive > 0.6.8; platform_system == 'Darwin' and platform_release > '20.6.0'",
]
charliermarsh commented 2 hours ago

Nice! The underlying limitation around wheels-without-source-distributions is tracked here: https://github.com/astral-sh/uv/issues/5182. Gonna close in favor of that issue.