pyright
🪨It turned out that pylsp
wasn't all that I thought it was, and I've switch to Microsoft's LSP,
pyright
. It's job is to do, in addition to a limited amount of linting (which I'll
probably turn off), the static type-checking that I was using mypy
for, except even better:
finally match
statement support! This left me to re-include null-ls
for formatting with black
and isort
, and diagnostics with pylama
. But there were a few problems.
null-ls
and pylama
🦙Firstly, the problem with pylama
was that it only looks for a configuration file
pylama.ini within the current working directory (cwd), or else a user configuration file
~/.pylama.ini. I have a feeling this does the job for many IDE whose linting program
command runners always start at the project root, but the problem for me was two-fold:
I'm not using an IDE and the working directory is a subfolder where the file I'm working on is;
and null-ls
seems to have its own thoughts on where to place the root/cwd.
To fix pylama
, I forked it and changed how it looks for configuration files to having it traverse
up the cwd
parent tree until it reaches ~
, looking for any config file along the way. I might
want to change this to have it in general stop at the base of the nearest module, but then it
wouldn't work for this particular project.
diff --git a/pylama/config.py b/pylama/config.py
index f946619..08b2a29 100644
--- a/pylama/config.py
+++ b/pylama/config.py
@@ -16,7 +16,8 @@
DEFAULT_LINTERS = "pycodestyle", "pyflakes", "mccabe"
CURDIR = Path.cwd()
-HOMECFG = Path.home() / ".pylama.ini"
+HOMEDIR = Path.home()
+HOMECFG = HOMEDIR / ".pylama.ini"
CONFIG_FILES = "pylama.ini", "setup.cfg", "tox.ini", "pytest.ini"
# Setup a logger
@@ -62,10 +63,13 @@ def get_default_config_file(rootdir: Path = None) -> Optional[str]:
if rootdir is None:
return DEFAULT_CONFIG_FILE
- for filename in CONFIG_FILES:
- path = rootdir / filename
- if path.is_file() and os.access(path, os.R_OK):
- return path.as_posix()
+ while HOMEDIR in rootdir.parents:
+ for filename in CONFIG_FILES:
+ path = rootdir / filename
+ if path.is_file() and os.access(path, os.R_OK):
+ return path.as_posix()
+ rootdir = rootdir.parent
+
return None
Running pylama
from the terminal while in a subdirectory now finds the project config, hooray!
But it didn't work within nvim
; the problem was that null-ls
gives its sources a particular root
directory, and in this case it was giving the repository directory project, and
not the path of the current working directory, nor the Python project project/python.
I haven't figured out where exactly it's choosing to do this, or why, but it's probably to do with
the git root. To fix this we thankfully don't need to go forking null-ls
and changing things, but
instead provide an override to cwd
for the pylama
source in our null-ls
config, and the
simplest is just to provide the neovim evenloop cwd.
local null_ls = require("null-ls")
local diagnostics = null_ls.builtins.diagnostics
local formatting = null_ls.builtins.formatting
null_ls.setup({
sources = {
-- Python
diagnostics.pylama.with({
-- NOTE: for some reason pylama wants to start at the repository root?
-- this means it'll miss a pylama.ini in a nested directory
-- e.g. project/python/pylama.ini
cwd = vim.loop.cwd,
}),
formatting.black,
formatting.isort,
},
})
And now everything works just the way I've wanted it to!