astral-sh / uv

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

Unable to install `gitlint` on Windows #8988

Open ayussh-verma opened 5 days ago

ayussh-verma commented 5 days ago

TL;DR: uv init followed by uv add gitlint==0.19.1 fails. pip install gitlint==0.19.1, however, works.

uv is trying to install the "sh" dependency from gitlint even though I'm on Windows and the dependency is marked for UNIX only. DEBUG Adding transitive dependency for gitlint-core==0.19.1: sh{sys_platform != 'win32'}>=1.14.3, <1.14.3+

DEBUG uv 0.5.1 (f399a5271 2024-11-08)
DEBUG Selecting: gitlint==0.19.1 [compatible] (gitlint-0.19.1-py3-none-any.whl)
DEBUG Found fresh response for: https://files.pythonhosted.org/packages/84/90/8b6a29ddceb51272a054399d4864eefd28083530349f5735e0bb979c5f0f/gitlint-0.19.1-py3-none-any.whl.metadata
DEBUG Adding transitive dependency for gitlint==0.19.1: gitlint-core>=0.19.1, <0.19.1+
DEBUG Adding transitive dependency for gitlint==0.19.1: gitlint-core[trusted-deps]>=0.19.1, <0.19.1+
DEBUG Found fresh response for: https://pypi.org/simple/gitlint-core/
DEBUG Searching for a compatible version of gitlint-core[trusted-deps] (>=0.19.1, <0.19.1+)
DEBUG Selecting: gitlint-core==0.19.1 [compatible] (gitlint_core-0.19.1-py3-none-any.whl)
DEBUG Adding transitive dependency for gitlint-core==0.19.1: gitlint-core==0.19.1
DEBUG Adding transitive dependency for gitlint-core==0.19.1: gitlint-core[trusted-deps]==0.19.1
DEBUG Searching for a compatible version of gitlint-core (==0.19.1)
DEBUG Selecting: gitlint-core==0.19.1 [compatible] (gitlint_core-0.19.1-py3-none-any.whl)
DEBUG Found fresh response for: https://files.pythonhosted.org/packages/b0/57/dea471da24ceac6de8c3dc5d37e4ddde57a5c340d6bac90010898734de34/gitlint_core-0.19.1-py3-none-any.whl.metadata
DEBUG Adding transitive dependency for gitlint-core==0.19.1: arrow>=1
DEBUG Adding transitive dependency for gitlint-core==0.19.1: click>=8
DEBUG Adding transitive dependency for gitlint-core==0.19.1: sh{sys_platform != 'win32'}>=1.13.0
DEBUG Searching for a compatible version of gitlint-core[trusted-deps] (==0.19.1)
DEBUG Selecting: gitlint-core==0.19.1 [compatible] (gitlint_core-0.19.1-py3-none-any.whl)
DEBUG Adding transitive dependency for gitlint-core==0.19.1: arrow>=1.2.3, <1.2.3+
DEBUG Adding transitive dependency for gitlint-core==0.19.1: click>=8.1.3, <8.1.3+
DEBUG Found fresh response for: https://pypi.org/simple/arrow/
DEBUG Adding transitive dependency for gitlint-core==0.19.1: sh{sys_platform != 'win32'}>=1.14.3, <1.14.3+
DEBUG Searching for a compatible version of arrow (>=1.2.3, <1.2.3+)
DEBUG Found fresh response for: https://pypi.org/simple/sh/
DEBUG Selecting: arrow==1.2.3 [compatible] (arrow-1.2.3-py3-none-any.whl)
DEBUG Found fresh response for: https://pypi.org/simple/click/
DEBUG Found fresh response for: https://files.pythonhosted.org/packages/f8/ed/e97229a566617f2ae958a6b13e7cc0f585470eac730a73e9e82c32a3cdd2/arrow-1.3.0-py3-none-any.whl.metadata
DEBUG Found fresh response for: https://files.pythonhosted.org/packages/c2/f1/df59e28c642d583f7dacffb1e0965d0e00b218e0186d7858ac5233dce840/click-8.1.3-py3-none-any.whl.metadata
DEBUG Found fresh response for: https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl.metadata
DEBUG Found fresh response for: https://files.pythonhosted.org/packages/67/67/4bca5a595e2f89bff271724ddb1098e6c9e16f7f3d018d120255e3c30313/arrow-1.2.3-py3-none-any.whl.metadata
DEBUG Adding transitive dependency for arrow==1.2.3: python-dateutil>=2.7.0
DEBUG Searching for a compatible version of click (>=8.1.3, <8.1.3+)
DEBUG Selecting: click==8.1.3 [compatible] (click-8.1.3-py3-none-any.whl)
DEBUG Adding transitive dependency for click==8.1.3: colorama{platform_system == 'Windows'}*
DEBUG Found fresh response for: https://pypi.org/simple/python-dateutil/
DEBUG Searching for a compatible version of sh{sys_platform != 'win32'} (>=1.14.3, <1.14.3+)
DEBUG Selecting: sh==1.14.3 [compatible] (sh-1.14.3.tar.gz)
DEBUG Adding transitive dependency for sh==1.14.3: sh==1.14.3
DEBUG Found fresh response for: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl.metadata
DEBUG Adding transitive dependency for sh==1.14.3: sh{sys_platform != 'win32'}==1.14.3
DEBUG Found fresh response for: https://pypi.org/simple/colorama/
DEBUG Searching for a compatible version of sh{sys_platform != 'win32'} (==1.14.3)
DEBUG Selecting: sh==1.14.3 [compatible] (sh-1.14.3.tar.gz)
charliermarsh commented 5 days ago

That's because we're trying to do a universal resolution. You can instruct the resolve to solve for Windows and non-Windows separately:

[tool.uv]
environments = ["sys_platform == 'win32'", "sys_platform != 'win32'"]
ayussh-verma commented 5 days ago

Thank you for the prompt reply. That unfortunately doesn't work for me: To reproduce:

[project]
name = "test"
version = "0.1.0"
description = "test"
requires-python = ">=3.10"
dependencies = [
    "gitlint",
]

[tool.uv]
environments = ["sys_platform == 'win32'", "sys_platform != 'win32'"]

uv sync --verbose

I'm not sure why uv is trying to install sh even though that is incompatible with windows. Shouldn't the installation be skipped?

I'm able to run uv add red-discordbot (even without the tool.uv section) which declares a dependency "distro" with the marker sys_platform == 'linux' uv correctly adds the dependency to the lock file but doesn't install distro

ayussh-verma commented 5 days ago

Just as a sanity check, Poetry is able to install gitlint - poetry add gitlint[core]

❯ poetry run pip list      
Package         Version
--------------- -----------
arrow           1.2.3
click           8.1.3
colorama        0.4.6
gitlint         0.19.1
gitlint-core    0.19.1
python-dateutil 2.9.0.post0
six             1.16.0

Here's the rest of the debug log

DEBUG Selecting: sh==1.14.3 [compatible] (sh-1.14.3.tar.gz)
DEBUG Acquired lock for `C:\Users\X\AppData\Local\uv\cache\sdists-v6\pypi\sh\1.14.3`
DEBUG Found fresh response for: https://files.pythonhosted.org/packages/b7/09/89c28aaf2a49f226fef8587c90c6386bd2cc03a0295bc4ff7fc6ee43c01d/sh-1.14.3.tar.gz
DEBUG No static `pyproject.toml` available for: sh==1.14.3 (MissingPyprojectToml)
DEBUG No static `PKG-INFO` available for: sh==1.14.3 (PkgInfo(UnsupportedMetadataVersion("1.2")))
DEBUG No static `egg-info` available for: sh==1.14.3 (MissingRequiresTxt)
DEBUG Preparing metadata for: sh==1.14.3
DEBUG Ignoring empty directory
DEBUG Resolving build requirements
DEBUG Solving with installed Python version: 3.10.15
DEBUG Solving with target Python version: >=3.10.15
DEBUG Adding direct dependency: setuptools>=40.8.0
DEBUG Found stale response for: https://pypi.org/simple/setuptools/
DEBUG Sending revalidation request for: https://pypi.org/simple/setuptools/
DEBUG Found not-modified response for: https://pypi.org/simple/setuptools/
DEBUG Searching for a compatible version of setuptools (>=40.8.0)
DEBUG Selecting: setuptools==75.3.0 [compatible] (setuptools-75.3.0-py3-none-any.whl)
DEBUG Found fresh response for: https://files.pythonhosted.org/packages/90/12/282ee9bce8b58130cb762fbc9beabd531549952cac11fc56add11dcb7ea0/setuptools-75.3.0-py3-none-any.whl.metadata
DEBUG Tried 1 versions: setuptools 1
DEBUG marker environment resolution took 0.089s
DEBUG Installing in setuptools==75.3.0 in C:\Users\X\AppData\Local\uv\cache\builds-v0\.tmpRNTII7
DEBUG Requirement already cached: setuptools==75.3.0
DEBUG Installing build requirement: setuptools==75.3.0
DEBUG Creating PEP 517 build environment
DEBUG Calling `setuptools.build_meta:__legacy__.get_requires_for_build_wheel()`
DEBUG Traceback (most recent call last):
DEBUG   File "<string>", line 14, in <module>
DEBUG   File "C:\Users\X\AppData\Local\uv\cache\builds-v0\.tmpRNTII7\lib\site-packages\setuptools\build_meta.py", line 333, in get_requires_for_build_wheel
DEBUG     return self._get_build_requires(config_settings, requirements=[])
DEBUG   File "C:\Users\X\AppData\Local\uv\cache\builds-v0\.tmpRNTII7\lib\site-packages\setuptools\build_meta.py", line 303, in _get_build_requires
DEBUG     self.run_setup()
DEBUG   File "C:\Users\X\AppData\Local\uv\cache\builds-v0\.tmpRNTII7\lib\site-packages\setuptools\build_meta.py", line 521, in run_setup
DEBUG     super().run_setup(setup_script=setup_script)
DEBUG   File "C:\Users\X\AppData\Local\uv\cache\builds-v0\.tmpRNTII7\lib\site-packages\setuptools\build_meta.py", line 319, in run_setup
DEBUG     exec(code, locals())
DEBUG   File "<string>", line 5, in <module>
DEBUG   File "C:\Users\X\AppData\Local\uv\cache\sdists-v6\pypi\sh\1.14.3\d7QG76cQeuGLPVj9Fw5gY\src\sh.py", line 37, in <module>
DEBUG     import fcntl
DEBUG ModuleNotFoundError: No module named 'fcntl'
DEBUG Released lock at `C:\Users\X\AppData\Local\uv\cache\sdists-v6\pypi\sh\1.14.3\.lock`
  × Failed to download and build `sh==1.14.3`
  ╰─▶ Build backend failed to determine requirements with `build_wheel()` (exit code: 1)

      [stderr]
      Traceback (most recent call last):
        File "<string>", line 14, in <module>
        File "C:\Users\X\AppData\Local\uv\cache\builds-v0\.tmpRNTII7\lib\site-packages\setuptools\build_meta.py", line 333, in get_requires_for_build_wheel
          return self._get_build_requires(config_settings, requirements=[])
        File "C:\Users\X\AppData\Local\uv\cache\builds-v0\.tmpRNTII7\lib\site-packages\setuptools\build_meta.py", line 303, in _get_build_requires
          self.run_setup()
        File "C:\Users\X\AppData\Local\uv\cache\builds-v0\.tmpRNTII7\lib\site-packages\setuptools\build_meta.py", line 521, in run_setup
          super().run_setup(setup_script=setup_script)
        File "C:\Users\X\AppData\Local\uv\cache\builds-v0\.tmpRNTII7\lib\site-packages\setuptools\build_meta.py", line 319, in run_setup
          exec(code, locals())
        File "<string>", line 5, in <module>
        File "C:\Users\X\AppData\Local\uv\cache\sdists-v6\pypi\sh\1.14.3\d7QG76cQeuGLPVj9Fw5gY\src\sh.py", line 37, in <module>
          import fcntl
      ModuleNotFoundError: No module named 'fcntl'
charliermarsh commented 5 days ago

Just to clarify: the logs DEBUG Adding transitive dependency for gitlint-core==0.19.1: sh{sys_platform != 'win32'}>=1.14.3, <1.14.3+ do not mean that we're trying to install that package. They mean we're trying to resolve it. So we're trying to resolve sh==1.14.3, which means we need its metadata. That package doesn't include a wheel (see: https://pypi.org/project/sh/1.14.3/#files). So we have to build it. And we're failing to build it for reasons that likely aren't related to uv.

charliermarsh commented 5 days ago

You can probably do environments = ["sys_platform == 'win32'"] if you only want to resolve for Windows.

charliermarsh commented 5 days ago

My guess is that this works on Poetry due to their heuristics that try to detect source distribution metadata? But those are being removed in the next Poetry release IIUC.

charliermarsh commented 5 days ago

I can test it on my Windows machine later though.

ayussh-verma commented 5 days ago

I think you're absolutely right, The setup file that sh v1.14.3 is using contains import fcntl which is a std-lib module that doesn't exist on Windows

[[package]]
name = "sh"
version = "1.14.3"
description = "Python subprocess replacement"
optional = false
python-versions = "*"
files = [
    {file = "sh-1.14.3.tar.gz", hash = "sha256:e4045b6c732d9ce75d571c79f5ac2234edd9ae4f5fa9d59b09705082bdca18c7"},
]

This is the lockfile Poetry generated, not sure if it's the heuristics like you mentioned

ayussh-verma commented 5 days ago

I want to resolve for both windows & linux though, thankfully this issue made me stumble upon a more well-maintained commit linter so I'll be parting ways with gitlint... gitlint is using pretty old deps