zed
zed copied to clipboard
Python lsp: Pyright isn't good
Check for existing issues
- [X] Completed
Describe the feature
it should be pylsp. The pyright has issues about recognize libraries installed
If applicable, add mockups / screenshots to help present your vision of the feature
No response
Yeah, pyright
has been a big source of pain for us in the Zed-Python intersection. I think we should def swap out to something better. I've not heard of pylsp
, but we should def add it to the list of ones to check out:
We are working on language plugins at the moment, so, in the not-so-distant future, someone can just add these servers as plugins, but I do think we should swap out our provided one for a bettter one.
Yeah,
pyright
has been a big source of pain for us in the Zed-Python intersection. I think we should def swap out to something better. I've not heard ofpylsp
, but we should def add it to the list of ones to check out:We are working on language plugins at the moment, so, in the not-so-distant future, someone can just add these servers as plugins, but I do think we should swap out our provided one for a bettter one.
Indeed they did build a language server protocol for Ruff already ruff-lsp
@JosephTLyons 🔥
Yeah,
pyright
has been a big source of pain for us in the Zed-Python intersection. I think we should def swap out to something better. I've not heard ofpylsp
, but we should def add it to the list of ones to check out:We are working on language plugins at the moment, so, in the not-so-distant future, someone can just add these servers as plugins, but I do think we should swap out our provided one for a bettter one.
Indeed they did build a language server protocol for Ruff already
ruff-lsp
@JosephTLyons 🔥
AFAICT, ruff-lsp
only support formatting and linting as of right now, as they haven't gotten to building things out like go to def
and auto-completion, but I read they will be doing that at some point.
https://github.com/pappasam/jedi-language-server
Yeah. I love Zed but when I open a Python project it's just strange. I will activate my .venv in my project directory and the script will run but when you look at the python file the imports are all red and can't be resolved.
See that python-dotenv is installed, along with pydantic in my env - (pip list) but I guess pyright is not checking for packages in the project-directory/.venv ???
You need this file.
$ cat pyrightconfig.json
{
"venvPath": ".",
"venv": ".venv"
}
There's an issue #8541 about resolving modules with Pyright.
I see this problem last for months, but there's still no real solution?
You need this file.
$ cat pyrightconfig.json { "venvPath": ".", "venv": ".venv" }
This should actually solve the problem - for some reason, during the migration of our documentation, we lost our Python docs that mentions this config file. I've quickly dumped the old Python docs contents into the configuration
section of our website, here. I need to bring back more documentation, so I will organize this better later on.
As a side note, I want to say that we are going to be doing more for Python here shortly - we recognize just how important this language is, being one of the top most-used languages, and we want to improve for Python devs in Zed.
You need this file.
$ cat pyrightconfig.json { "venvPath": ".", "venv": ".venv" }
This should actually solve the problem - for some reason, during the migration of our documentation, we lost our Python docs that mentions this config file. I've quickly dumped the old Python docs contents into the
configuration
section of our website, here. I need to bring back more documentation, so I will organize this better later on.As a side note, I want to say that we are going to be doing more for Python here shortly - we recognize just how important this language is, being one of the top most-used languages, and we want to improve for Python devs in Zed.
I tried it, but no luck. I use poetry in my python project, does it matter?
To add to the corpus of Pyright issues, in is_24hour = models.BooleanField(default=False)
, False
is red-underlined for
Argument of type "Literal[False]" cannot be assigned to parameter "default" of type "type[NOT_PROVIDED]" in function "_init_" Type "Literal[False]" cannot be assigned to type "type[NOT_PROVIDED]"
Additionally, in def __str__(self):
, __str__
is red-underlined for
Method "_str_" overrides class "Model" in an incompatible manner Return type mismatch: base method returns type "str", override returns type "CharField" "CharField" is incompatible with "str"
I have done no custom configuration. I believe these shouldn't be showing issues as they work as expected and are standard practices.
I tried it, but no luck. I use poetry in my python project, does it matter?
@newtome8888 run poetry env info
to find the path to your virtualenv, then add that to your pyrightconfig. Worth noting, this path will be different per machine, so don't add pyrightconfig.json
to any version control. Mine looks something like this:
{
"venvPath": "/Users/username/Library/Caches/pypoetry/virtualenvs",
"venv": "projectname-p0LYZhue-py3.11"
}
I tried it, but no luck. I use poetry in my python project, does it matter?
@newtome8888 run
poetry env info
to find the path to your virtualenv, then add that to your pyrightconfig. Worth noting, this path will be different per machine, so don't addpyrightconfig.json
to any version control. Mine looks something like this:{ "venvPath": "/Users/username/Library/Caches/pypoetry/virtualenvs", "venv": "projectname-p0LYZhue-py3.11" }
Just to mention, there is a setting in poetry tells poetry to install the venv within the project:
- https://python-poetry.org/docs/configuration#virtualenvsin-project
Which would stabilize where the pyrightconfig.json
points to, when running the project on multiple machines.
Using pyright is literally painful.
To add to the corpus of Pyright issues, in
is_24hour = models.BooleanField(default=False)
,False
is red-underlined forArgument of type "Literal[False]" cannot be assigned to parameter "default" of type "type[NOT_PROVIDED]" in function "init" Type "Literal[False]" cannot be assigned to type "type[NOT_PROVIDED]"
Additionally, in
def __str__(self):
,__str__
is red-underlined forMethod "str" overrides class "Model" in an incompatible manner Return type mismatch: base method returns type "str", override returns type "CharField" "CharField" is incompatible with "str"
I have done no custom configuration. I believe these shouldn't be showing issues as they work as expected and are standard practices.
I am running into the same issue. it's hurting more than its helping.
@JosephTLyons I'd like to offer a counter proposal - pyright is actually really good... assuming it gets pointed to the right thing. Expanding on https://github.com/zed-industries/zed/issues/7808#issuecomment-2012710492
-
Putting aside the config / invocation of pyright for a moment, I believe the approach to how the type system was implemented in the pyright type-checker leads to the best editor experience. There's a few subtle choices e.g. how bi-directly type inference within a method with partial type annotations are handled compared to mypy that make a much better dev experience while editing python code. It's also faster than mypy and more complete than any other option currently available in my experience.
-
robustly invoking pyright is the key. I think the docs are clunky but the most robust approach effectively boils down to the following
pyright --pythonpath $ABS_PATH_TO_PYTHON --project $ABS_PATH_TO_PROJECT_ROOT
For example, if I have a workspace pointed at the following folders
api
- pyproject.toml # poetry project
- src/
- tests/
backend
- pyproject.toml # poetry project
- src/
- tests/
frontend
- yarn / node...
To get pyright working for backend
I would do cd backend && pyright --pythonpath $(poetry env info --executable) --project $PWD
Why not use the venv
venvPath
options? If you scrutinize the pyright docs, they mention that this isn't really scalable because it's hard to enforce that every dev creates a venv in the same location by default. The pythonpath
option is how vscode invokes the pyright lsp.
Why not use the execution environments option? In practice, while you can have a pyright config file in the project root, you might want to open multiple different folders in a single editor workspace.
@strangemonad Can you share the "actually really good" parts? I don't really get it...
@Yevgnen sure, I can give it a shot. I think it's helpful to break this up into a few categories:
everything below being said I do think the ease of use of pyright could be improved. I'd also like to remind folks that even though pyright comes out of Microsoft, for reasons I don't understand it's primarily the work of only a single person - including documentation and triaging of bugs
- choice of LSP
- LSP vs type checker vs linter
- Speed
- PyRight's type system
1 I'm still very much in favor of user choice of LSP. Folks should be able to pick what's currently best at their current project's needs. I primarily do python work in a single editor workspace that contains many python projects in various workspace directors (e.g. VSCode's add folder to workspace). Most of these are CLIs, services, or ML model pipelines. This is probably pretty different than the needs of someone who works on, say, a single python open source library at a time.
2 There might be some LSPs that work separately from a downstream type checker. Personally, I like a couple invariants a) I want anything that would fail a type checking command or lint command to show up inline (red / yellow squiggles) as I'm writing the code. b) I don't find it personally acceptable if symbol completion suggests something that's not a valid symbol and I end up getting method not found or what not when I run the code I practice, that pretty much means that whatever the LSP is calling out to needs to be equivalent to the same type checker implementation. E.g. if someone were able to make a better python LSP front end that called out to pyright + ruff and combined results, that would be great (assuming they could get it working reliably which would be no small feat given the current state of the world).
Speed Once PyRight is up and running, responses and updates feel faster to me than other approaches. I don't have empirical evidence for this, just what it feels like to me.
Type system This is probably the most nuanced but I think it makes a big difference, especially around producing false-negatives and suggesting type hint corrections while typing. Some back context: As type hints have been gradually added to Python it's been done differently than other languages that have added progressive optional typing (e.g. typescript). Effectively, when taken together, the various python type hint PEPs don't really define a type system, but rather provide the guidelines and specifications for a possible type system. Rather than talk about the "python type system" it would probably be more correct to say that MyPy, Pyright, pytypre, pyre have each implemented "a python type system" with different design constraints to suit specific needs. I'd consider MyPy and PyRight to be the 2 most general implementations. Pytype has made choices that make it more applicable to Google's large (and older) python code base. Pyre has learned a lot from flowtype but is aimed a bit more at finding security vulnerabilities.
Putting aside the speed difference between pyright and mypy, there's a bunch of subtle design differences that might seem insignificant but I think end up mattering a lot when editing code. To boil it down to just 2:
- How missing type hints are handled
- Limited-scope type inference.
MyPy interprets the PEP quite literally. e.g. if a function has no return type hint, pyright treats it as if it had the Any
return type. Pyright, however treat's it as "untyped" and then treats this "Untyped" fictitious type as being equivalent to Any
.
Within bounded scopes (e.g. the scope of a method) pyright implements bi-direction type checking (in the style of Pierce) e.g. even though def foo(a, b):
has no type hints, if the first line is a + b
we know we at the very least expect a
to implement __add__
all these bits of information within a method to either catch errors that can't be caught if you don't do type inference or suggest type hints for parameters or the return type.
Is it possible to add a global setting in Zed like pylance in vscode?
It's really a pain to have to manually add pyrightconfig.json
every time creating a Python project.https://github.com/zed-industries/zed/issues/10587
@geoqiao pyright can be configured in the pyproject.toml
directly as documented here, for example like this:
[tool.pyright]
venv = ".venv"
venvPath = "."
@geoqiao pyright can be configured in the
pyproject.toml
directly as documented here, for example like this:[tool.pyright] venv = ".venv" venvPath = "."
It still needs to be manually configured.
item_icon : Optional[FileStorage] = request.files.get('item_icon')
if item_icon:
file_name : str = item_id + '.' + item_icon.filename.rsplit('.', 1)[1].lower()
Pyright: "rsplit" is not a known attribute of "None"
Good typing system? It doesn't even do TypedDict correctly
So, will there be an option system or extensions soon? I'd like Pylance but I'm not sure if it can be an extension. I've tried MyPy, but cannot remember if it was good
I'd like Pylance but I'm not sure if it can be an extension.
Pylance is just pyright with a few small added features. Here is a list of differences: https://github.com/microsoft/pylance-release/issues/3838#issuecomment-1387510630
Pyright can definitely handle TypedDict. If you give more context, I can tell you what the problem is.
I agree that pyright is currently hard to set up with Zed. But with
[tool.pyright]
venvPath = "."
venv = ".venv"
# typeCheckingMode = "off" # uncomment this if you don't want type checking
in my pyproject.toml
and poetry configured with
poetry config virtualenvs.in-project true
it works very well.
item_icon : Optional[FileStorage] = request.files.get('item_icon') if item_icon: file_name : str = item_id + '.' + item_icon.filename.rsplit('.', 1)[1].lower()
Pyright: "rsplit" is not a known attribute of "None"
Good typing system? It doesn't even do TypedDict correctly
Off-topic, but @vladimir-sama your example is simply user error: FileStorage.filename
can be None
. See https://github.com/pallets/werkzeug/blob/3.0.3/src/werkzeug/datastructures/file_storage.pyi#L12.
Does Zed support to config pyright to make it work with workspaces?
yes, i am also having this issue :(
Just simply open the project form the terminal with env activated!!!
I faced the same issue when opening project directory directly in zed, pyright started to yell "missing libraries".
Solution:
- Open terminal
-
cd YOUR_PROJECT_DIRECTORY
-
source .venv/bin/activate
-
zed .
now it should work smoothly
Just simply open the project form the terminal with env activated!!!
I faced the same issue when opening project directory directly in zed, pyright started to yell "missing libraries".
Solution:
- Open terminal
cd YOUR_PROJECT_DIRECTORY
source .venv/bin/activate
zed .
now it should work smoothly
doesn't work. activated the environment with poetry and still get unresolved imports.
Just simply open the project form the terminal with env activated!!!
I faced the same issue when opening project directory directly in zed, pyright started to yell "missing libraries".
Solution:
- Open terminal
cd YOUR_PROJECT_DIRECTORY
source .venv/bin/activate
zed .
now it should work smoothly
doesn't work. activated the environment with poetry and still get unresolved imports.
This is a problem with pyright config, which has nothing to do with whether to activate the python virtual environment.
We need a better way to make pyright work without generating pyryghtconfig.json every time opening a new project.