Pylance-release: Goto definition goes to stub files instead of actual definitions

Created on 7 Jul 2020  路  34Comments  路  Source: microsoft/pylance-release

Expected behaviour

Goto definition goes to actual code even if types are defined in a stub file

Actual behaviour

Goto definition goes to stub files instead of actual code

Code Snippet / Additional information

from http import HTTPStatus

print(HTTPStatus.GATEWAY_TIMEOUT)

Try goto definition (F12) on either HTTPStatus in line 1 or GATEWAY_TIMEOUT in line 3

enhancement fixed in next version

Most helpful comment

The next release includes a change to go-to-definition's behavior and adds go-to-declaration. Go-to-definition prefers source files, while go-to-declaration prefers stubs.

Here's an example jumping to Flask:

gotothing2

If either of these calls would otherwise return no results (e.g. go-to-def when only a stub is available), then the old behavior is used so that you don't mysteriously jump nowhere.

All 34 comments

Goto definition on HTTPStatus results include both the .py and .pyi, which is currently the expected result. As discussed in the linked topic on pyright, we have no control on which of the multiple results appears first.

Goto definition on GATEWAY_TIMEOUT results only include the .pyi, which is a bug, it should be able to find it in sources as well but it doesn't right now.

As a suggestion, if you couldn't control the order of displayed results, it would be nice to have an option turn off displaying *.pyi files in all the results as whole or only display results from *.pyi files when there are no *.py files.

@jahan01 Thanks for the suggestion. We're looking into solutions and will update here soon.

Could we have two separate commands like Go To Declaration/Go To Definition for C/C++ in Visual Studio?

  • Go To Declaration goes to .h files for C/C++, for Python we can go to the .pyi files
  • Go To Definition goes to .cpp files for C++, for Python we can go to the .py files
  • If one of the .pyi file and .py file is missing, the other command could still go to the existing file

hello, is this a bug in below gif?
websocket_firefox

At the moment, that is expected behavior.

I am trying to annotate tqdm. So I did the following:

  1. Created a file typings/tqdm/__init__.pyi with:
from typing import Any, Generic, Iterable, Iterator, TypeVar
T = TypeVar('T')
class tqdm(Generic[T]):
    def __init__(self, iterable: Iterable[T], *args: Any, **kwargs: Any): ...
    def __iter__(self) -> Iterator[T]: ...
  1. Added "python.analysis.stubPath": "${workspaceFolder}/typings" to .vscode/settings.json

Now when I click on tqdm -> "Go to Definition" on another piece of code (like `from tqdm import tqdm') it jumps straight to the stub file. Also if I try to see the references on "Go to References" the source code is not listed (it was before adding the stub file). Selecting Peek -> "Peek Definition" only display the stub file as well.

I would expect it to show the source code (or at least give an option to it) when clicking "Go to Definition"

This is a major bug. Navigation into stdlib and 3rd party libraries is basically broken. .pyi files are an implementation detail of a typechecker, please don't put them above the real code.

Anybody thought there is an ambiguous meaning between goto definition and goto stubs? My temp solution is to remove .pyi files but is not very smart.

Well alright. Thanks @jakebailey . I was looking thoroughly but didn't use the word "stub" just .pyi ... 馃槃
So, what about WIP? How is this supposed to work in the future? Is there a plan? is there a blog post about this? anything?

For me this is simply broken atm and it was fine in the past.
There could be another shortcut like Shift+Ctrl+Click to Goto the stub. Actual definition should always be first!, no?

I mean I wanna be fair here: You're doing awesome work already and when doing progress things need to break here and there but I'd at least wanna know how to backup.

That default preference for pyi drives me insane as it is killing the entire code browsing experience for any library that happens to keep type hints outside the source files. I do not want to browse the stubs when the source files exist and we clearly need and option to tell it to respect that preference.

Our only luck is that very few libraries decided to put keep type hints in pyi files.

This is a sound solution, your rarely are interested in definition or type stubs at the same time.
There should be a separate option to go to either of them.

Could we have two separate commands like Go To Declaration/Go To Definition for C/C++ in Visual Studio?

  • Go To Declaration goes to .h files for C/C++, for Python we can go to the .pyi files
  • Go To Definition goes to .cpp files for C++, for Python we can go to the .py files
  • If one of the .pyi file and .py file is missing, the other command could still go to the existing file

My C/++ years precede the existence of vscode so I do not know what is current behavior on Cmd+click as I would wish to be Go To Definition by default.

There is a slight issue with having two options because what if you do not have a definition and you only have access to the declaration? in that case I suppose it should send you to the only one available

Apparently the UI is bit confused about what is a definition and declaration as I right click on the method and choose "Go To Definition" and instead it opens the in-line preview of the declaration:

This was happened accesing "Go To Definition":

Also having trouble with this. Previously i at least got both the stub and implementation, but now I only get the stub when using F12...

I am also experiencing this issue. My current solution involves renaming my /typings folder whenver I need goto impl. I've had it occasionally recognize both the pyi stub and the library .py implementation, but I have no way of consistently reproducing that behavior. Seems a bit odd that a stub would completely obfuscate the implementation.

Started happening to me today. No workaround for this at least?

We are currently investigating solutions to address this.

I believe a solution here would be the approach Pycharm takes. Providing a clickable widget in the gutter if a corresponding .py or .pyi is available. See screenshots below.

image

image

@savannahostrowski any new news on this?

We've spec'd out and planned an enhancement to go to def/go to declaration to improve this behaviour. Stay tuned!

Is this actually connected that one cannot get documentation from hovering over functions?
You only get stub info when there is a stub: 馃檮
image

This is not strictly related, no. We'd appreciate a new issue for that, but I would expect it to either be an issue with the source mapper, or that os.path contains compiled code that isn't shown.

For the meantime I've downgraded pylance extension to v2020.11.1 . It now shows the documentation properly and a click will follow to the source. Unfortunately, I don't exactly know which version broke the behaviour, therefore I just tried an older version. Hope I don't have to use the older version for long, as some people are already working to resolve this issue.

Update: unfortunately, the mentioned version is also not working after restarting vscode, sorry for confusion..

This is not strictly related, no. We'd appreciate a new issue for that, but I would expect it to either be an issue with the source mapper, or that os.path contains compiled code that isn't shown.

Seems there are already some related issues: #844, #170 ? Or would you rather have another one dedicated to build-in libs?

844 is about the bundled matplotlib stubs, and #170 is a problem with Jupyter, neither are related to isfile missing its documentation. The builtins already have docs, but other stdlib code may not if they are compiled, but I would have expected this one to work.

The next release includes a change to go-to-definition's behavior and adds go-to-declaration. Go-to-definition prefers source files, while go-to-declaration prefers stubs.

Here's an example jumping to Flask:

gotothing2

If either of these calls would otherwise return no results (e.g. go-to-def when only a stub is available), then the old behavior is used so that you don't mysteriously jump nowhere.

This issue has been fixed in version 2021.2.1, which we've just released. You can find the changelog here: https://github.com/microsoft/pylance-release/blob/main/CHANGELOG.md#202121-10-february-2021

For me is not fixed.

Example:

from operator import attrgetter

If I try Go to Definition or Go to Declaration for attrgetter, both goes to stub file.

Not fixed for me either.

For me it fails with the following:

from django.urls import include, path

It correctly takes me to the source of include, but for path it takes me to stub.

Whow! I thought it was working! But obviously not always

import pipes
pipes.quote()

Ctrl+Clicking pipes goes to the stub while quotes takes me to the source! :|

Please report these as individual bugs. We won't be reopening this issue for every case, as the primary functionality for filtering the results is in place. Not being able to jump to certain files or going to the wrong place are different issues and existed before this was fixed. (This fix is just a filter over previous results.)

This still jumps me to the stubs most of the time on v2021.2.3, especially in Django projects.

Please file a new issue for those cases, but you may want to wait for the next release, which includes a good number of improvements to the way we map stubs to their source files.

Was this page helpful?
0 / 5 - 0 ratings