uv icon indicating copy to clipboard operation
uv copied to clipboard

Explicit index not respected for transitive dependency

Open juzna opened this issue 1 year ago • 6 comments

Hey, thanks for delivering explicit indexes in #7481 ❤️ I'm trying this with uv built from the last commit (e71b1d0c), but I have a problem with transitive dependencies & explicit index.

Scenario: my-app depends on internal pkg a, which declares a dependency on (internal) package b.

In my app project.toml, I define the index plus I set sources for both pkg a & b. But then uv lock` gives me

Because b was not found in the package registry ...

So it's ignoring the source definition when resolving a transitive dependency.

[[tool.uv.index]]
name = "my-internal-index"
url = "..."
explicit = true

[tool.uv.sources]
a = { index = "my-internal-index" }
b = { index = "my-internal-index" }

[project.dependencies]
a = { version = "1.0" }  # `a` declares a dependency on `b`

juzna avatar Oct 16 '24 12:10 juzna

Sources only apply to dependencies that are declared in the project itself. In this case, you'd need to define b as a dependency.

charliermarsh avatar Oct 16 '24 12:10 charliermarsh

Yep, that works.

Though, is it a good approach? my-app doesn't really depend on b, only transitively. So if a removes the dependency on b in the future, I'll be left with an unused dependency. For this reason, I'll also get a warning by deptry that the dependency is not used in my code.

juzna avatar Oct 16 '24 12:10 juzna

I don't know if it applies here, but this handling of transitive dependencies is the primary driver for the "glob pattern-based source declaration" functionality that exists in PDM and others have implemented using poetry plugins described e.g. here. The idea is that in corporate environments, where it's common to enforce a namespace for internal packages, this makes it easy to setup a declaration that handles pinning transitive internal dependencies to a particular repository.

just echoing that there is some desire to have a way to inform a package manager about how to handle particular transitive dependencies.

corleyma avatar Oct 16 '24 21:10 corleyma

@juzna You may be better off though removing the explicit = true so that all packages are checked on your internal index first. That's probably a fair workaround, and improves your security.

odie5533 avatar Oct 18 '24 16:10 odie5533

We're also running into this issue. We have a library that depends on torch, so for that library we have set up as in the docs, and that works.

[tool.uv.sources]
torch = { index = "pytorch" }

[[tool.uv.index]]
name = "pytorch"
url = "https://download.pytorch.org/whl/cpu"
explicit = true

Now when this library is used in an application, I'm getting Because there is no version of torch{platform_system == 'Linux'}==2.5.0+cpu..., even when the same index is also added in the application's pyproject.toml. Making the index non-explicit also doesn't work, because the torch index contains some older version of requests which then blocks us from fetching the required requests from the default index. It does work with non-explicit index and --index-strategy unsafe-first-match but we'd prefer to avoid using the unsafe option.

mnchsmn avatar Oct 23 '24 15:10 mnchsmn

I would also be in favor of an improvement of this corporate use case. My package A depends on package B from private index which itself depends on C from private index.

No way to make it works from A pyproject.toml without explicit = true that we don't want as it puts unnecessary pressure on our internal index, only used for our packages. Option 2 of defining transitive dependencies like C directly in A is not very clean either.

oxenit avatar Dec 17 '24 13:12 oxenit

Hey guys, do you have any further thoughts on this? Using uv with multiple packages from separate indices is somewhat painful right now do to a lack of configurability of such a feature.

Example:

  • project depends on rospy from their index, which has other transitive dependencies in their custom index
  • project depends on custom-lib from an internal index, which has other transitive dependencies in the internal index
  • both depend on numpy (silly example) from the PyPi index

How do we resolve such dependencies without declaring both the rospy index and custom-lib index as non-explicit? Marking both as non-explicit leads to poor resolution from unexpected indices.

NellyWhads avatar May 08 '25 05:05 NellyWhads

Do you have any plans to add some options to resolve it ?

NeverDieOne avatar Sep 01 '25 12:09 NeverDieOne

This missing functionality is problematic for me, as well, so +1, but I'm going to go a bit further and say that uv pip install <package> should also honor the source configurations. The common use case for this is plugins: my (proprietary) app employs a plugin package architecture. Devs frequently need to test the app locally with different plugin packages installed (all of which are arbitrary and optional, so not dependencies of the main app at all). Currently, we can't simply install the package with uv pip install as one would hope, even if we assign those packages to our private package index in [tool.uv.sources]. That should work.

Note: currently we work around this by installing from the repo URL or a local clone, but this approach requires extra care, as it introduces the risk that we're testing with a build of the plugin package that doesn't correspond to the latest release.

mikenerone avatar Sep 02 '25 14:09 mikenerone

+1 from me for adding this fnctional. @charliermarsh advice from his answer works for me but in more complicated cases i see this approach may cause troubles in managing my company internal dependencies

JustGevorg avatar Sep 11 '25 17:09 JustGevorg

+1

Can't properly handle installing nightly torch for CUDA Toolkit 13.0:

[project.optional-dependencies]
cu128 = [ "torch==2.7.1" ]
cu129 = [ "torch==2.8.0" ]
cu130 = [ "torch==2.9.0.dev20250909+cu130" ]

[tool.uv.sources]
torch = [
  { index = "cu128", extra = "cu128" },
  { index = "cu129", extra = "cu129" },
  { index = "cu130", extra = "cu130" }
]

[[tool.uv.index]]
name = "cu128"
url = "https://download.pytorch.org/whl/cu128"
explicit = true

[[tool.uv.index]]
name = "cu129"
url = "https://download.pytorch.org/whl/cu129"
explicit = true

[[tool.uv.index]]
name = "cu130"
url = "https://download.pytorch.org/whl/nightly/cu130"
explicit = true

Making non-explicit all indices is kinda scary

ARKAD97 avatar Sep 19 '25 23:09 ARKAD97

Ran into the same issue also in a corporate setting where only some package should be fetched from the private index. Would appreciate seeing an improvement of that usecase here.

MauroPfister avatar Oct 06 '25 15:10 MauroPfister

+1

KochankovID avatar Oct 09 '25 13:10 KochankovID

+1, ran into this issue today as well

(Thanks for all u do)

tekeinhor avatar Nov 14 '25 14:11 tekeinhor

+1

karim-moon avatar Nov 27 '25 03:11 karim-moon

@KochankovID @tekeinhor @karim-moon

Just a quick note: on many projects, maintainers prefer avoiding “+1” comments since they notify everyone without adding new information. Using the 👍 reaction on the original post is usually the recommended way to show support and keep the thread clean and useful for maintainers.

Thanks!

rabyj avatar Nov 27 '25 19:11 rabyj