uv icon indicating copy to clipboard operation
uv copied to clipboard

constraint-dependencies setting ignores environment markers

Open espdev opened this issue 6 months ago • 2 comments

Summary

Hello,

I try to use constraint-dependencies setting to apply constraints for the dependency resolver.

I need to apply constraints because I need to install pyqt5 dependency in a Windows/Linux project (Python>=3.10).

pyqt5 depends on pyqt5-qt5 dependency. Without constraint-dependencies I can't add/install pyqt5 on Windows because there is no pyqt5-qt5 binary distribution on PyPI (This is a mistake by the package maintainers, but nevertheless it is true). The same issue describes here.

So, I have added constraint-dependencies to the pyproject.toml file:

[project]
name = "my-app"
version = "0.1.0"
description = "My app"
readme = "README.md"

requires-python = ">=3.10, <3.14"

dependencies = [
    "pyqt5>=5.15.11",
]

[tool.uv]
constraint-dependencies = [
    "pyqt5-qt5<=5.15.2; sys_platform == 'win32'"
]

And manifest section has been added to uv.lock file:

[manifest]
constraints = [{ name = "pyqt5-qt5", marker = "sys_platform == 'win32'", specifier = "<=5.15.2" }]

It works fine on Windows, now I can install pyqt5==5.15.11 and pyqt5-qt5==5.15.2. However, on Linux I would like to install the latest version of pyqt5-qt5 package: pyqt5-qt5==5.15.16 because the latest binary distribution is available for Linux platform. But on Linux I also get pyqt5-qt5==5.15.2. The environment marker "sys_platform == 'win32'" just ignored.

uv even downgrades pyqt5-qt5 version if I add constraint-dependencies after:

❯ uv sync
Using CPython 3.10.17
Creating virtual environment at: .venv
Resolved 4 packages in 0.66ms
Prepared 3 packages in 10.66s
Installed 3 packages in 24ms
 + pyqt5==5.15.11
 + pyqt5-qt5==5.15.16
 + pyqt5-sip==12.17.0

... add constraint-dependencies

❯ uv lock
Resolved 5 packages in 149ms
Updated pyqt5-qt5 v5.15.16 -> v5.15.2, v5.15.16

I think constraint-dependencies setting should take into account environment markers. Especially the fact that the markers are even indicated in the manifest in uv.lock file.

Platform

Windows/Linux

Version

uv 0.7.4

Python version

Python >= 3.10

espdev avatar May 17 '25 11:05 espdev

I don't think the marker is "ignored"; rather, uv tries to find a solution that avoids including multiple versions of pyqt5-qt5 unnecessarily. Using 5.15.2 on Linux is actually totally compatible with the requirements you provided. I might suggest adding another constraint to say you want > 5.15.2 on non-Windows.

charliermarsh avatar May 17 '25 11:05 charliermarsh

Interesting note.

So, I just added the constraints and it works as I expect! Thank you @charliermarsh!

[tool.uv]
constraint-dependencies = [
    "pyqt5-qt5<=5.15.2; sys_platform == 'win32'",
    "pyqt5-qt5>=5.15.16; sys_platform == 'linux'",
]

But this seems counter-intuitive to me. I expect the constraint will not apply to another platform. Because if I don't specify any constraints at all, uv will add/install the latest version of the dependency. But the main thing is that it works!

espdev avatar May 17 '25 12:05 espdev

👍 This is working as expected, though there's been consideration in the past to being more "aggressive" in "forking" to include multiple versions here. I think that's best tracked elsewhere, though.

charliermarsh avatar May 18 '25 21:05 charliermarsh