zed icon indicating copy to clipboard operation
zed copied to clipboard

Python lsp: Pyright isn't good

Open lctzz540 opened this issue 1 year ago • 60 comments

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

lctzz540 avatar Feb 02 '24 19:02 lctzz540

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.

JosephTLyons avatar Feb 02 '24 20:02 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 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.

Indeed they did build a language server protocol for Ruff already ruff-lsp @JosephTLyons 🔥

plattenschieber avatar Feb 06 '24 15:02 plattenschieber

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.

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.

JosephTLyons avatar Feb 06 '24 18:02 JosephTLyons

https://github.com/pappasam/jedi-language-server

failable avatar Feb 28 '24 15:02 failable

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. Screenshot 2024-03-02 at 7 58 28 PM

JacobGoldenArt avatar Mar 03 '24 03:03 JacobGoldenArt

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 ???

JacobGoldenArt avatar Mar 03 '24 04:03 JacobGoldenArt

You need this file.

$ cat pyrightconfig.json
{
  "venvPath": ".",
  "venv": ".venv"
}

failable avatar Mar 03 '24 04:03 failable

There's an issue #8541 about resolving modules with Pyright.

Moshyfawn avatar Mar 03 '24 04:03 Moshyfawn

I see this problem last for months, but there's still no real solution?

newtome8888 avatar Mar 04 '24 00:03 newtome8888

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.

JosephTLyons avatar Mar 04 '24 05:03 JosephTLyons

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? 2024-03-04_23-04-32

newtome8888 avatar Mar 04 '24 15:03 newtome8888

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.

collinsinclair avatar Mar 04 '24 21:03 collinsinclair

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"
}

r-cha avatar Mar 05 '24 01:03 r-cha

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"
}

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.

JosephTLyons avatar Mar 05 '24 06:03 JosephTLyons

Using pyright is literally painful.

failable avatar Mar 05 '24 11:03 failable

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 am running into the same issue. it's hurting more than its helping.

myusuf3 avatar Mar 08 '24 23:03 myusuf3

@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

  1. 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.

  2. 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 avatar Mar 21 '24 17:03 strangemonad

@strangemonad Can you share the "actually really good" parts? I don't really get it...

Yevgnen avatar Mar 22 '24 02:03 Yevgnen

@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

  1. choice of LSP
  2. LSP vs type checker vs linter
  3. Speed
  4. 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:

  1. How missing type hints are handled
  2. 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.

strangemonad avatar Mar 23 '24 18:03 strangemonad

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 avatar Apr 27 '24 14:04 geoqiao

@geoqiao pyright can be configured in the pyproject.toml directly as documented here, for example like this:

[tool.pyright]
venv = ".venv"
venvPath = "."

didibear avatar May 02 '24 21:05 didibear

@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.

geoqiao avatar May 02 '24 23:05 geoqiao

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

vladimir-sama avatar May 17 '24 16:05 vladimir-sama

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.

tmke8 avatar May 23 '24 13:05 tmke8

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.

injust avatar May 29 '24 06:05 injust

Does Zed support to config pyright to make it work with workspaces?

failable avatar May 29 '24 09:05 failable

yes, i am also having this issue :(

jaanli avatar Jun 01 '24 12:06 jaanli

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:

  1. Open terminal
  2. cd YOUR_PROJECT_DIRECTORY
  3. source .venv/bin/activate
  4. zed .

now it should work smoothly

yash-desai-naik avatar Jun 15 '24 18:06 yash-desai-naik

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:

  1. Open terminal
  2. cd YOUR_PROJECT_DIRECTORY
  3. source .venv/bin/activate
  4. zed .

now it should work smoothly

doesn't work. activated the environment with poetry and still get unresolved imports.

andre0xFF avatar Jun 17 '24 15:06 andre0xFF

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:

  1. Open terminal
  1. cd YOUR_PROJECT_DIRECTORY
  1. source .venv/bin/activate
  1. 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.

geoqiao avatar Jun 18 '24 10:06 geoqiao