Pylance-release: How to get verbose/debugging output from Pylance?

Created on 20 Aug 2020  Â·  5Comments  Â·  Source: microsoft/pylance-release

While using pylance with PyTorch, I've found a lot of methods are missing. For example,

import torch
torch.ones((1,))

gets me a

"ones" is not a known member of module

error from pylance. But when I run pyright on the same file, it reports everything is a-okay:

root@5049e7c0c119:/code# pyright tmp.py
stubPath /code/typings is not a valid directory.
Assuming Python platform Linux
Searching for source files
Found 1 source file
0 errors, 0 warnings 
Completed in 0.694sec

This leaves me with a couple of questions:

  1. Why does Pylance not pick up on some torch methods?

    • I suspect that it's because that method is missing from pytorch's stubs, but I'd like to be able to check that's the case.

  2. Why is Pylance giving me different results to Pyright?

    • I suspect it's some extra parameter that Pylance is passing to its own instance of Pyright, but again I'd like to be able to verify that's the case.

but really I haven't given you detailed enough information to give me a concrete answer to either of those. I'm running this in a fairly vanilla container, but some random configuration value might be messing with things. So my ultimate question is

  1. How can I get Pylance to emit more verbose/debugging output so that I could figure out the answer to (1, 2) on my own?
triage

Most helpful comment

In this case, the difference you're seeing is because Pyright and Pylance use a different default value for one particular setting: "useLibraryCodeForTypes". Pyright defaults this setting to false, and Pylance defaults it to true. We generally like to keep the settings defaults the same between the two, but there are a couple of exceptions. We should probably document these explicitly. The other setting that differs is "typeCheckingMode". Pyright defaults to "basic" and Pylance defaults to "off".

The justification for these differences is that most Pylance users are not interested in type checking. They are instead interested primarily in language server features like completion suggestions. Users of Pyright — especially the CLI version — are primarily interested in type checking.

The "useLibraryCodeForTypes" setting is disabled in Pyright by default because type checking is dependent on high-quality type stubs. Type information inferred from library code is often incomplete and leads to false positives. The error you're seeing is an example of this.

So if you want to use the CLI version of Pyright alongside the Pylance extension, I recommend configuring them in the same manner, whatever is most appropriate for your use case. You should then get consistent results for both.

All 5 comments

Make sure you dont have both extensions installed at the same time.

to enable tracing add this to your settings.json
"python.analysis.logLevel": "Trace",

In this case, the difference you're seeing is because Pyright and Pylance use a different default value for one particular setting: "useLibraryCodeForTypes". Pyright defaults this setting to false, and Pylance defaults it to true. We generally like to keep the settings defaults the same between the two, but there are a couple of exceptions. We should probably document these explicitly. The other setting that differs is "typeCheckingMode". Pyright defaults to "basic" and Pylance defaults to "off".

The justification for these differences is that most Pylance users are not interested in type checking. They are instead interested primarily in language server features like completion suggestions. Users of Pyright — especially the CLI version — are primarily interested in type checking.

The "useLibraryCodeForTypes" setting is disabled in Pyright by default because type checking is dependent on high-quality type stubs. Type information inferred from library code is often incomplete and leads to false positives. The error you're seeing is an example of this.

So if you want to use the CLI version of Pyright alongside the Pylance extension, I recommend configuring them in the same manner, whatever is most appropriate for your use case. You should then get consistent results for both.

Thanks very much for the fast response folks!

Pyright and Pylance use a different default value for one particular setting: "useLibraryCodeForTypes".

Great - running pyright tmp.py --lib replicates the error I'm seeing in pylance.

The other setting that differs is "typeCheckingMode". Pyright defaults to "basic" and Pylance defaults to "off".

And yup, turns out I have type-checking set to basic. I don't remember setting that, which is either because pyright set it when I had it installed previously, or more likely because I've forgotten that I messed with it.

to enable tracing add this to your settings.json
"python.analysis.logLevel": "Trace",

And hooray!

[BG] analyzing: /code/tmp.py (329ms)
[BG] analyzing: /code/tmp.py ...
[BG]   parsing: /code/tmp.py (14ms)
[BG]   parsing: /root/.vscode-server/extensions/ms-python.vscode-pylance-2020.8.1/server/typeshed-fallback/stdlib/2and3/builtins.pyi (194ms)
[BG]   binding: /root/.vscode-server/extensions/ms-python.vscode-pylance-2020.8.1/server/typeshed-fallback/stdlib/2and3/builtins.pyi (30ms)
[BG]   binding: /code/tmp.py (0ms)
[BG]   checking: /code/tmp.py ...
[BG]     parsing: /opt/conda/lib/python3.8/site-packages/torch/__init__.py (91ms)
[BG]     binding: /opt/conda/lib/python3.8/site-packages/torch/__init__.py ...
[BG]       parsing: /opt/conda/lib/python3.8/site-packages/torch/_C/__init__.pyi (16ms)
[BG]       binding: /opt/conda/lib/python3.8/site-packages/torch/_C/__init__.pyi (24ms)
[BG]       parsing: /opt/conda/lib/python3.8/site-packages/torch/functional.py (13ms)
[BG]       binding: /opt/conda/lib/python3.8/site-packages/torch/functional.py (3ms)
[BG]     binding: /opt/conda/lib/python3.8/site-packages/torch/__init__.py (60ms)
[BG]   checking: /code/tmp.py (152ms)
[BG] analyzing: /code/tmp.py (391ms)

This is exactly what I was after, thanks. It looks like it's pulling in torch/_C/__init__.pyi, but omitting torch/_C/_VariableFunctions.pyi, which - looking at the file - is where the stub for torch.ones is.

Curiously, mypy does find this file, along with the definition:

root@5049e7c0c119:/code# mypy tmp.py --verbose 2>&1 | grep Variable 
LOG:  Metadata fresh for torch._C._VariableFunctions: file /opt/conda/lib/python3.8/site-packages/torch/_C/_VariableFunctions.pyi

but it looks like the pytorch devs hacked this in with a if False: import. Or at least I think that's what they did; I'm a bit out of my depth at this point.

I think this is now more of a pyright issue than a pylance issue, but do either of you know if there's another setting I can flip to get pylance/pyright to correctly find this _VariableFunctions.pyi file?

Pytorch 1.5 worked fine for me. With Pytorch 1.6, they have made some modifications that broke things.

I don't understand why they chose to place that import under an if False: condition. Type checkers need to honor provably-false conditions, and Pyright does so in this case. If they want to hide the import at runtime but make it available to type checkers, they should change if False: to if TYPE_CHECKING:. If I make that change in my local copy of torch/__init__.py, the ones symbol (and other symbols declared in torch/_C/_VariableFunctions.pyi) become visible to the type checker.

Works for me too, thanks again!

I'll open a PR with pytorch to fix this.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

fbidu picture fbidu  Â·  3Comments

ynouri picture ynouri  Â·  3Comments

yankyhoffman picture yankyhoffman  Â·  5Comments

BrunoBlanes picture BrunoBlanes  Â·  4Comments

iwoloschin picture iwoloschin  Â·  3Comments