I’m running neovim with nvim-lspconfig plugin with pyright. The structure of the repo is a little strange, so I’ve got a PYTHONPATH
environment variable set up to help python find all the code. Here’s a simple example:
$ mkdir demo; cd demo
$ git init # necessary to get lspconfig's root_dir automatically set, this is discussed later
$ cat test.py
import foo
print(foo)
$ cat subdir/foo.py
PI=22/7
Note how that import foo
shouldn’t work (without a custom PYTHONPATH
) because foo.py is in a subdirectory. And indeed, it doesn’t:
$ pyright
No configuration file found.
No pyproject.toml file found.
Assuming Python platform Linux
Searching for source files
Found 2 source files
/home/jeremy/tmp/pyright-demo/test.py
/home/jeremy/tmp/pyright-demo/test.py:1:8 - error: Import "foo" could not be resolved (reportMissingImports)
1 error, 0 warnings, 0 infos
Completed in 0.625sec
Fortunately, pyright does know how to read the PYTHONPATH
env var: Support for PYTHONPATH · Issue #8 · microsoft/pyright · GitHub), so if I set one, things work fine:
$ PYTHONPATH=./subdir pyright
No configuration file found.
No pyproject.toml file found.
Assuming Python platform Linux
Searching for source files
Found 2 source files
0 errors, 0 warnings, 0 infos
Completed in 0.621sec
However, when I’m in neovim (with the PYTHONPATH
env var set!), I get an error about the “Import “foo” could not be resolved”!
I poked around /proc/
and could see that the PYTHONPATH
environment variable is set correctly:
$ pstree -apl 335756
zsh,335756
└─vim,337568
├─node,337621 /usr/bin/pyright-langserver --stdio
│ ├─{node},337622
│ ├─{node},337623
│ ├─{node},337624
│ ├─{node},337625
│ ├─{node},337626
│ └─{node},337628
├─python3,337615 -c import sys; sys.path = list(filter(lambda x: x != "", sys.path)); import neovim; neovim.start_host() script_host.py
└─{vim},337569
$ grep -Eao 'PYTHONPATH.{50}' /proc/337621/environ
PYTHONPATH=./subdir_=/usr/bin/vimVIMRUNTIME=/usr/share/nvi
But I also noticed that the cwd
of the pyright process is not what I’d expect:
$ ls -alh /proc/337621/cwd
lrwxrwxrwx 1 jeremy jeremy 0 Oct 26 17:54 /proc/337621/cwd -> /usr/lib/node_modules/pyright/dist
So I think this explains it: pyright
is looking for files relative to my /usr/lib/node_modules/pyright/dist
directory rather than my project’s directory.
I did some more reading on lspconfig, and I learned about this root_dir
setting. I checked that by running :lua print(vim.inspect(vim.lsp.buf_get_clients()))
, and do see that the root_dir
is correctly set to the root of the folder. I very briefly poked around the nvim-lspconfig source code, and couldn’t figure out what the root_dir
setting actually is used for. Maybe it’s just so we know if we should start a fresh language server as we open more files?
For the record, I can work around this issue by creating a pyrightconfig.json
file at the root of my repo with the following contents:
{
"extraPaths": ["./subdir"],
}
This also uses a relative path, but I think this works because pyright is smart enough to resolve any paths in the config relative to the location of the config file.
Am I understanding this all correctly? Is there some config setting for lspconfig to get it to start pyright with a working directory equal to the root_dir
?