jedi-language-server icon indicating copy to clipboard operation
jedi-language-server copied to clipboard

Editor opens internal typeshed file instead of real file in venv

Open Morikko opened this issue 1 year ago • 1 comments

Expected vs. Actual

Expected: When Ctrl-clicking on a function from a given package, the editor opens the actual file in which the function definition is found in the virtual environment.

Actual: When Ctrl-clicking on a function from a given package, the editor opens the typeshed file matching the definition installed within the extension itself.

How to reproduce

  1. Create a new folder/workspace and open vscode;
  2. Create a new Python file with eg.:
import flask

assert flask.__version__ == "2.2.3"

class Route(flask.Blueprint):
    ...

r = Route("test", "test")
r.add_url_rule

(Using Flask here as an example)

  1. Create a new venv: python -m venv env && source env/bin/activate
  2. Install flask: pip install flask
  3. Mouse hover over from_app and click.

The editor will bring up the typeshed in the extension directory, ~/.vscode-oss/extensions/ms-python.python-2023.4.1-universal/pythonFiles/lib/jedilsp/jedi/third_party/typeshed/third_party/2and3/flask/blueprints.pyi instead of opening env/lib64/python3.X/site-packages/flask/blueprints.py, which is what eg. mypy will use to check the project against.

The hover I see:

flask-hover

Technical details

The Flask v2 signature: https://github.com/pallets/flask/blob/main/src/flask/blueprints.py#L408

    def add_url_rule(
        self,
        rule: str,
        endpoint: t.Optional[str] = None,
        view_func: t.Optional[ft.RouteCallable] = None,
        provide_automatic_options: t.Optional[bool] = None,
        **options: t.Any,
    ) -> None:

While it is the old Flask v1 here: https://github.com/davidhalter/typeshed/blob/jedi/third_party/2and3/flask/blueprints.pyi#L55

    def add_url_rule(self, rule: str, endpoint: Optional[str] = ..., view_func: _ViewFunc = ..., **options: Any) -> None: ...

Jedi looks to act normally, so I believe the problem is how it is used by jedi-language-server:

import jedi

assert jedi.__version__ == '0.18.2'

def filter_function_params(completions):
    return [c for c in completions if c.complete.endswith("=")]

def get_function_function_params_completion(func):
    return filter_function_params(
        jedi.Interpreter(
            f"{func.__name__}(",
            [
                {
                    func.__name__: func,
                }
            ],
        ).complete()
    )


print(get_function_function_params_completion(r.add_url_rule))
# [<Completion: endpoint=>, <Completion: provide_automatic_options=>, <Completion: rule=>, <Completion: view_func=>]

provide_automatic_options parameter is present and only Flask v2.

Note: The issue was originally open here: https://github.com/microsoft/vscode-python/issues/20988

Morikko avatar Apr 05 '23 22:04 Morikko