uv: `uv` fails to install `scikits.odes` on Python 3.11 due to Cython dependency resolution mismatch, works on Python 3.10 and earlier (cannot find `longintrepr.h`?)
Description
Hi there! I’m opening this issue because I’m unable to install a package with uv
, but the installation works with pip
– it’s called scikits.odes
. The installation instructions mention the requirement of a Fortran compiler and a SUNDIALS installation present before installing off of the source distribution available on PyPI (no wheels are available).
How to reproduce
Here is a reproducer on an M-series macOS machine (compiling scikits.odes
is much easier on Unix-like platforms such as GNU/Linux and macOS, rather than on Windows).
[!NOTE] Installing SUNDIALS via Homebrew usually works, but it doesn’t work at the time of writing because the formula was updated to SUNDIALS v7.0.0, which is not supported (we regularly test in CI against v6.5.0). I have provided another method of installing SUNDIALS v6.5.0 for the purpose of this MWE.
# install Python 3.11 with Homebrew
brew install python@3.11
# Clone repository (we provide a helper script to install SUNDIALS
git clone https://github.com/pybamm-team/PyBaMM.git --depth 1
# Create a virtual environment in venv/
python3.11 -m venv venv
# Activate it
source venv/bin/activate
# Install SUNDIALS v6.5.0 via helper script, to ~/.local/
pip install nox
nox -s pybamm-requires
# Install uv into this virtual environment via pip
pip install uv
# Point to the SUNDIALS installation directory before installation
export SUNDIALS_INST="$HOME/.local/"
# Install it
uv pip install scikits.odes --verbose --no-cache-dir
Expected behaviour
The expected behaviour would be that I can install scikits.odes
with uv
on both Python 3.10 and Python 3.11 (or between Python 3.8–3.11 based on the provided official support for the package). I can currently install scikits.odes
with pip
on all Python versions from 3.8–3.11.
Additional context
I see that https://github.com/astral-sh/uv/issues/1946 faced this issue of not being able to find longintrepr.h
earlier, I don’t know if that’s related – I am not used to working with Cython or Fortran codebases, but can help debug a bit with pybind11
linkage. However, I’m noticing with a deeper dive with the logs that pip
’s resolver chooses to point to cython==0.29.37
, while uv
chooses cython==3.0a7
, which might be causing the trouble?
I would be happy to provide additional reproducers or logs as necessary.
xref: pybamm-team/PyBaMM#3825, aio-libs/aiohttp#6600
Specifications
uv 0.1.24 (a5cae0292 2024-03-22)
installed via pip
from PyPI
macOS M-series, running Mac OS X Sonoma v14.3 (arm64)
About this issue
- Original URL
- State: closed
- Created 3 months ago
- Comments: 24 (7 by maintainers)
FWIW I’ve made a PR: https://github.com/pypa/packaging/pull/794
This is a bug in packaging.
I’ve created an issue on packaging side, let’s see if there’s any feedback there: https://github.com/pypa/packaging/issues/788
Sorry for doing a second u-turn on this conversation, I really should have waited until I had time to carefully read through everything before posting, I will try and learn from this.
But I remember why I linked the packse issue now, it linked to an important comment that was in a conversation I was involved in on this: https://github.com/pypa/packaging/issues/776#issuecomment-1900515985
In particular from @dstufft
So it is intentional that packaging does not include
3.0.0a7
here:And this is where pip inherits it’s behavior from, therefore at least according to the person who wrote the spec, uv would not be following it.
I’m going to close as “working as intended”.
Yes,
3.0.0a8
should absolutely be excluded givencython<3.0.0a8
. What’s being discussed here is whether3.0.0a7
should be included, givencython<3.0.0a8
. The PEP says: yes, it should be included in the specifier.Being the person who opened that thread, I strongly came away with the opinion of “the spec is ambiguous” in a lot of these prerelease cases 😔, and pip has not reviewed if it is closely following it where it’s not ambiguous (there’s several open issues on pip side, both before this thread and after it that I’ve created).
I’m a little confused –
uv pip install "cython<3.0.0a8"
returningcython-3.0a7
is right, per the spec, isn’t it?Pip doesn’t include prereleases when using exclusive ordered comparison, e.g.
<
.It does include prereleases when using inclusive ordered comparison, e.g.
<=
.I beleive pip is following the spec here and uv is probably wrong, but the spec is open to some interpretation. I wrote about this issue here: https://github.com/astral-sh/packse/issues/161, but hadn’t got round to making a specific uv issue yet.
I think you could add a constraints file:
And then pass it when you install, like:
uv pip install -r requirements.txt -c constraints.txt