pylance-release icon indicating copy to clipboard operation
pylance-release copied to clipboard

How to configure with multiple packages and uv

Open dantetemplar opened this issue 8 months ago • 11 comments

I have such project layout:

/
   projects/
       api/
            .venv
            pyproject.toml
       parser/
           .venv
            pyproject.toml
       shared/
           .venv
            pyproject.toml  

Shared project installed to other projects as editable module, f.e. in api:

[project]
name = "api"
version = "0.0.1"
requires-python = "~=3.12"
dependencies = [
    "shared",

]

[tool.uv.sources]
shared = { path = "../shared", editable = true }

It mostly works, but pylance failed to analyze code today. I guess environments do not switch when I change folders. Yet openning terminal in folder works properly (I see (ml) prefix when open ml folder).

Image

Image

Image

Image

What can be done to improve hints and suggestions?

dantetemplar avatar Apr 23 '25 16:04 dantetemplar

pylance failed to analyze code today

Could you elaborate on what you mean by this?

In any case, Pylance doesn't provide much support for monorepos (repositories with multiple Python projects / venvs) out of the box, see also https://github.com/microsoft/pyright/issues/10498 .

Personally, I have been using https://marketplace.visualstudio.com/items?itemName=teticio.python-envy in addition to Pylance to automatically set the right .venv, depending on which file I'm looking at. Unfortunately, even with the venv set correctly, Pylance will still get auto imports wrong, see https://github.com/microsoft/pylance-release/blob/main/TROUBLESHOOTING.md#unresolved-import-warnings . Adjusting python.analysis.extraPaths globally for your workspace/repo (like you did) probably won't exactly do the right thing here.[0] One way out might be to define different execution environments in a top-level /pyrightconfig.json or something.


[0]: Setting python.analysis.extraPaths globally will have Pylance suggest cross-project imports which will not work well if the projects use separate venvs / separate sets of dependencies like in your case. (This is not NodeJS, after all, which will look for the closest node_modules folder to resolve imports in a given file!) If you really need imports across projects while the projects should use different sets of dependencies, a much better way would be to add e.g. project A to the dependencies (pyproject.toml) of project B, like you did with the shared package, and then let uv handle the rest. Since shared will get installed in the venvs of api and parser, Pylance/Pyright should be able to pick it up automatically as long as the venv / python.pythonPath is set correctly.

codethief avatar May 21 '25 22:05 codethief

I have a similar issue and the core problem seems to be that Pylance does not understand/respect either the [tool.uv.sources] directive in pyproject.toml, or the results of it, not sure which.

I have a monorepo like:

infra/
  pyproject.toml
  ...
libs/
  lib-a/
    pyproject.toml
    ...
  lib-b/
    pyproject.toml
    ...

I couldn't work out from the docs how to configure VS Code for a monorepo so I just cd into either infra/ or libs/ and launch it from there depending on what I'm working on.

Recently I added a lib dependency in infra/pyproject.toml:

[tool.uv.sources]
lib-a = { path = "../libs/lib-a", editable = true }

From the infra/ dir I do uv lock and uv sync to make sure the venv is updated

I can do:

$ uv run ipython
Python 3.13.5 (main, Jun 12 2025, 12:22:43) [Clang 20.1.4 ]
Type 'copyright', 'credits' or 'license' for more information
IPython 9.6.0 -- An enhanced Interactive Python. Type '?' for help.
Tip: Put a ';' at the end of a line to suppress the printing of output.

In [1]: from lib_a.module import Member

In [2]:

...so at the uv level it's all working fine.

But in VS Code for infra/ I get complaints from Pylance when I do the same import statement:

Import "lib_a.module" could not be resolved Pylance(reportMissingImports)

I confirmed I have the correct venv activated (non local+editable dependencies are present)

Inside infra/.venv/lib/python3.13/site-packages there is a lib_a-0.1.0.dist-info dir:

direct_url.json
INSTALLER
METADATA
RECORD
REQUESTED
top level.txt
uv build.ison
uv_cache.json
WHEEL

and inside direct_url.json is:

{"url":"file:///Users/anaentropic/dev/mymonorepo/libs/lib-a","dir_info":{"editable":true}}

So this is everything the uv needs to work, but Pylance is not resolving it.

(I have tried closing and reopening VS Code but problem persists)

Notably I think the problem does not require 'monorepo' support in Pylance (that's just my context where I need it)... the problem seems to be an unsupported type of Python package installed by uv. But I think that's a standard Python packaging feature and something that probably could be supported?

anentropic avatar Oct 16 '25 17:10 anentropic

I saw this: https://github.com/microsoft/pylance-release/issues/7024#issuecomment-2898701117 (issue which also involves unsupported editable installs)

But I already have that option set:

Image

in a Python 3.13 project

Image

anentropic avatar Oct 16 '25 17:10 anentropic

@anentropic is there a .pth file? Pylance should look for and run .pth files. There is no support for reading direct_url.json in Pylance or Pyright though. The only thing added in 3.13 was the ability to run .pth files.

rchiodo avatar Oct 16 '25 18:10 rchiodo

there is no .pth file in infra/.venv/lib/python3.13/site-packages/lib_a-0.1.0.dist-info ...is that where to look?

anentropic avatar Oct 16 '25 18:10 anentropic

I believe it ends up in the site-packages folder.

rchiodo avatar Oct 16 '25 18:10 rchiodo

ah, yes there is a infra/.venv/lib/python3.13/site-packages/__editable__.lib_a-0.1.0.pth

anentropic avatar Oct 16 '25 18:10 anentropic

and also a infra/.venv/lib/python3.13/site-packages/__editable___lib_a_0_1_0_finder.py

anentropic avatar Oct 16 '25 18:10 anentropic

and both of those files are listed in infra/.venv/lib/python3.13/site-packages/lib_a-0.1.0.dist-info/RECORD

anentropic avatar Oct 16 '25 18:10 anentropic

Okay that sounds like it should be reproducible. It might be the sandbox isn't working or there's a pattern we haven't seen before. The __editable__.lib_a-0.1.0.pth should be what we use to find the path for the lib.a module.

rchiodo avatar Oct 16 '25 18:10 rchiodo

@anentropic In the interest of keeping separate issues separate, would you mind opening a new ticket? :)

codethief avatar Oct 17 '25 08:10 codethief