tox-uv icon indicating copy to clipboard operation
tox-uv copied to clipboard

Install fails when UV sources are a list

Open mdekstrand opened this issue 3 months ago • 2 comments

Issue

When entries in tools.uv.sources are lists instead of dictionaries, as is common in forked dependency structures such as multi-backend PyTorch setups, tox fails to install the virtual environment.

Example pyproject.toml snippet:

[tool.uv.sources]
torch = [
  { index = "pytorch-cpu", group = "cpu" },
  { index = "pytorch-gpu", group = "gpu" },
]

Stack trace:

Traceback (most recent call last):
  File "/Users/mde48/.local/share/uv/tools/tox/lib/python3.12/site-packages/tox/session/cmd/run/single.py", line 47, in _evaluate
    tox_env.setup()
  File "/Users/mde48/.local/share/uv/tools/tox/lib/python3.12/site-packages/tox/tox_env/api.py", line 285, in setup
    self._setup_with_env()
  File "/Users/mde48/.local/share/uv/tools/tox/lib/python3.12/site-packages/tox/tox_env/runner.py", line 146, in _setup_with_env
    self._setup_pkg()
  File "/Users/mde48/.local/share/uv/tools/tox/lib/python3.12/site-packages/tox/tox_env/runner.py", line 171, in _setup_pkg
    self._install(self._packages, RunToxEnv.__name__, "package")
  File "/Users/mde48/.local/share/uv/tools/tox/lib/python3.12/site-packages/tox/tox_env/api.py", line 119, in _install
    self.installer.install(arguments, section, of_type)
  File "/Users/mde48/.local/share/uv/tools/tox/lib/python3.12/site-packages/tox_uv/_installer.py", line 105, in install
    self._install_list_of_deps(arguments, section, of_type)
  File "/Users/mde48/.local/share/uv/tools/tox/lib/python3.12/site-packages/tox_uv/_installer.py", line 137, in _install_list_of_deps
    and pkg.name in self._sourced_pkg_names
                    ^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/mde48/.local/share/uv/python/cpython-3.12.11-macos-aarch64-none/lib/python3.12/functools.py", line 998, in __get__
    val = self.func(instance)
          ^^^^^^^^^^^^^^^^^^^
  File "/Users/mde48/.local/share/uv/tools/tox/lib/python3.12/site-packages/tox_uv/_installer.py", line 119, in _sourced_pkg_names
    return {key for key, val in sources.items() if val.get("workspace", False)}
                                                   ^^^^^^^
AttributeError: 'list' object has no attribute 'get'

After reviewing this function, it appears this line is assuming that tool.uv.sources maps package names to objects, but it is allowed to map them to lists of objects.

Environment

Provide at least:

  • OS: macOS
Output of pip list of the host Python, where tox is installed

not sure how to get this when using recommended uv tool install setup.

mdekstrand avatar Sep 04 '25 16:09 mdekstrand

PR welcome.

gaborbernat avatar Sep 04 '25 17:09 gaborbernat

Hi all,

I encountered this issue as well. Seems this occurs when parsing for workspace packages.

Would there ever be an instance where a list would be present for a workspace source? I wasn't able to find any information on the uv docs on this or example.

Otherwise, I guess tox-uv would then need to determine which item in the list to use which could depend on a group, or some other marker like sys_platform, python version, etc.

Would adding a simple check that the sources object is a dict here be sufficient? https://github.com/tox-dev/tox-uv/blob/main/src/tox_uv/_installer.py#L119

NickGeneva avatar Nov 03 '25 19:11 NickGeneva