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