microsoft / pyright

Static Type Checker for Python
Other
13.12k stars 1.4k forks source link

False positive `reportIndexIssue` for typings in `v1.1.376` when `pyproject.toml` contains `[tool.pyright]` section (even if this section is empty) #8797

Closed chegoryu closed 2 weeks ago

chegoryu commented 3 weeks ago

Describe the bug

I gets false positive Subscript for class "list" will generate runtime exception; enclose type annotation in quotes (reportIndexIssue) error with pyright v1.1.376+ when [tool.pyright] is present in pyproject.toml on this code (even if this section is empty):

def f(_: int) -> list[int]:
    return []

Works fine with v.1.1.375:

$ cat pyproject.toml 
[tool.pyright]
$ PYRIGHT_PYTHON_FORCE_VERSION=v1.1.375 python3.11 -m pyright --pythonpath /usr/bin/python3.11 test.py --project pyproject.toml 
WARNING: there is a new pyright version available (vv1.1.375 -> v1.1.377).
Please install the new version or set PYRIGHT_PYTHON_FORCE_VERSION to `latest`

up to date, audited 2 packages in 599ms

found 0 vulnerabilities
0 errors, 0 warnings, 0 informations

False positive error with v1.1.376:

$ cat pyproject.toml 
[tool.pyright]
$ PYRIGHT_PYTHON_FORCE_VERSION=v1.1.376 python3.11 -m pyright --pythonpath /usr/bin/python3.11 test.py --project pyproject.toml 
WARNING: there is a new pyright version available (vv1.1.376 -> v1.1.377).
Please install the new version or set PYRIGHT_PYTHON_FORCE_VERSION to `latest`

up to date, audited 2 packages in 778ms

found 0 vulnerabilities
/home/echunaev/junk/test/test.py
  /home/echunaev/junk/test/test.py:1:18 - error: Subscript for class "list" will generate runtime exception; enclose type annotation in quotes (reportIndexIssue)
1 error, 0 warnings, 0 informations

Removing [tool.pyright] section solves the issue:

$ rm pyproject.toml && touch pyproject.toml
$ PYRIGHT_PYTHON_FORCE_VERSION=v1.1.376 python3.11 -m pyright --pythonpath /usr/bin/python3.11 test.py --project pyproject.toml 
WARNING: there is a new pyright version available (vv1.1.376 -> v1.1.377).
Please install the new version or set PYRIGHT_PYTHON_FORCE_VERSION to `latest`

up to date, audited 2 packages in 604ms

found 0 vulnerabilities
0 errors, 0 warnings, 0 informations

Python version:

$ python3.11 --version
Python 3.11.7
erictraut commented 3 weeks ago

The error you're reporting is correct if the pythonVersion is 3.8 or older. That means pyright somehow thinks that it's being asked to assume Python 3.8. Let's see if we can figure out what that's the case.

If you manually add a pythonVersion: "3.11" to the config file, I'm guessing that will fix the issue. Could you confirm that theory?

chegoryu commented 3 weeks ago

Adding an explicit version fixes the issue:

$ cat pyproject.toml
[tools.pyright]
pythonVersion = "3.11"
$ PYRIGHT_PYTHON_FORCE_VERSION=v1.1.376 python3.11 -m pyright --pythonpath /usr/bin/python3.11 test.py --project pyproject.toml
WARNING: there is a new pyright version available (vv1.1.376 -> v1.1.377).
Please install the new version or set PYRIGHT_PYTHON_FORCE_VERSION to `latest`

up to date, audited 2 packages in 516ms

found 0 vulnerabilities
0 errors, 0 warnings, 0 informations
erictraut commented 3 weeks ago

I'm guessing that you haven't configured your shell environment to use Python 3.11 by default. Pyright determines the default python version by running python3 --version. The recommended approach used by most pyright users is to activate a virtual environment in their shell before invoking pyright. This virtual environment will then become the default (target) Python environment, and pyright will get its import paths, pythonVersion, and pythonPlatform from this.

Which Python environment do you have configured in your shell?

@rchiodo, I'm guessing that this behavior is fallout from the recent change you made to the config code paths. It seems strange that the behavior changes here depending on whether there is a "[tools.pyright]" section present in the config file. Note that there are no language server settings involved.

chegoryu commented 3 weeks ago

Which Python environment do you have configured in your shell?

Oh, python3 is python3.8 in my case... In my company we use our twix-python binary (all shellbags are #!/usr/bin/env twix-python), so I didn't event notice that. After enabling venv everything works fine.

By the way why do you use python3 --version when explicit --pythonpath /usr/bin/python3.11 is provided? It might be better to use /usr/bin/python3.11 --version in this case.

Anyway thanks for help, I just added explicit pythonVersion to our pyproject.toml to avoid such confusion in the future.

rchiodo commented 3 weeks ago

There could be a bug with the default python version when a config file is present. Let me do some digging.

erictraut commented 3 weeks ago

why do you use python3 --version when explicit --pythonpath /usr/bin/python3.11 is provided?

If you specify the pythonpath directly, we should use that binary. I didn't notice that you were using that option. We should fall back on "python3" only if there is no pythonpath configured.

rchiodo commented 3 weeks ago

I'm having trouble reproducing. The python version is always computed from the python path AFAICT. Config file has no impact on that.

rchiodo commented 3 weeks ago

@chegoryu can you run the error condition again with the '--verbose' flag and report the output?

erictraut commented 3 weeks ago

Unfortunately, the --verbose flag probably won't tell us much because of this bug that I just fixed in the main branch.

chegoryu commented 3 weeks ago
$ PYRIGHT_PYTHON_FORCE_VERSION=v1.1.375 python3.11 -m pyright --pythonpath /usr/bin/python3.11 test.py --verbose 
WARNING: there is a new pyright version available (vv1.1.375 -> v1.1.377).
Please install the new version or set PYRIGHT_PYTHON_FORCE_VERSION to `latest`

up to date, audited 2 packages in 620ms

found 0 vulnerabilities
Setting pythonPath for service "<default>": "/usr/bin/python3.11"
Loading pyproject.toml file at /home/echunaev/junk/test/pyproject.toml
Assuming Python version 3.11.7.final.0
No include entries specified; assuming /home/echunaev/junk/test
Auto-excluding **/node_modules
Auto-excluding **/__pycache__
Auto-excluding **/.*
Search paths for file:///home/echunaev/junk/test
  /home/echunaev/.cache/pyright-python/v1.1.375/node_modules/pyright/dist/typeshed-fallback/stdlib
  /home/echunaev/junk/test
  /home/echunaev/junk/test/typings
  /home/echunaev/.cache/pyright-python/v1.1.375/node_modules/pyright/dist/typeshed-fallback/stubs/...
  /usr/twix/python3.11/lib/python3.11
  /usr/twix/python3.11/lib/python3.11/lib-dynload
  /home/echunaev/.local/lib/python3.11/site-packages
  /usr/twix/python3.11/lib/python3.11/site-packages
Found 1 source file
pyright 1.1.375
0 errors, 0 warnings, 0 informations
Completed in 0.553sec

$ PYRIGHT_PYTHON_FORCE_VERSION=v1.1.376 python3.11 -m pyright --pythonpath /usr/bin/python3.11 test.py --verbose   
WARNING: there is a new pyright version available (vv1.1.376 -> v1.1.377).
Please install the new version or set PYRIGHT_PYTHON_FORCE_VERSION to `latest`

up to date, audited 2 packages in 609ms

found 0 vulnerabilities
Loading pyproject.toml file at /home/echunaev/junk/test/pyproject.toml
Assuming Python version 3.8.10.final.0
Setting pythonPath for service "<default>": "/usr/bin/python3.11"
Auto-excluding **/node_modules
Auto-excluding **/__pycache__
Auto-excluding **/.*
Search paths for file:///home/echunaev/junk/test
  /home/echunaev/.cache/pyright-python/v1.1.376/node_modules/pyright/dist/typeshed-fallback/stdlib
  /home/echunaev/junk/test
  /home/echunaev/junk/test/typings
  /home/echunaev/.cache/pyright-python/v1.1.376/node_modules/pyright/dist/typeshed-fallback/stubs/...
  /usr/twix/python3.11/lib/python3.11
  /usr/twix/python3.11/lib/python3.11/lib-dynload
  /home/echunaev/.local/lib/python3.11/site-packages
  /usr/twix/python3.11/lib/python3.11/site-packages
Found 1 source file
pyright 1.1.376
/home/echunaev/junk/test/test.py
  /home/echunaev/junk/test/test.py:1:18 - error: Subscript for class "list" will generate runtime exception; enclose type annotation in quotes (reportIndexIssue)
1 error, 0 warnings, 0 informations
Completed in 0.527sec
chegoryu commented 3 weeks ago

I see something like this with strace for v1.1.376: https://pastebin.com/KDskRkie And this for v1.1.375: https://pastebin.com/99KmaCiV

Command is

$ PYRIGHT_PYTHON_FORCE_VERSION=v1.1.375 strace -F python3.11 -m pyright --pythonpath /usr/bin/python3.11 test.py --verbose 2>&1 | grep -e 'exec\|Assuming'
rchiodo commented 3 weeks ago

This output makes me think we don't recognize the pythonPath when the pyproject.toml is present for some reason:

[pid 82452] execve("/home/echunaev/.cargo/bin/python3", ["python3", "-I", "-c", "import os, os.path, sys; normali"...], 0x7f0cc1473d90 /* 53 vars */) = -1 ENOENT (No such file or directory)
[pid 82452] execve("/usr/local/sbin/python3", ["python3", "-I", "-c", "import os, os.path, sys; normali"...], 0x7f0cc1473d90 /* 53 vars */) = -1 ENOENT (No such file or directory)
[pid 82452] execve("/usr/local/bin/python3", ["python3", "-I", "-c", "import os, os.path, sys; normali"...], 0x7f0cc1473d90 /* 53 vars */) = -1 ENOENT (No such file or directory)
[pid 82452] execve("/usr/sbin/python3", ["python3", "-I", "-c", "import os, os.path, sys; normali"...], 0x7f0cc1473d90 /* 53 vars */) = -1 ENOENT (No such file or directory)
[pid 82452] execve("/usr/bin/python3", ["python3", "-I", "-c", "import os, os.path, sys; normali"...], 0x7f0cc1473d90 /* 53 vars */ <unfinished ...>

That looks like it's searching for a python3 match.

rchiodo commented 3 weeks ago

These two messages show why that's happening. I think I've found the bug. We're ensuring the version before we have a pythonPath if there's a config file.

Assuming Python version 3.8.10.final.0
Setting pythonPath for service "<default>": "/usr/bin/python3.11"
chegoryu commented 3 weeks ago

Shouldn't it be configSettings here?

https://github.com/microsoft/pyright/compare/1.1.375...1.1.376#diff-0a6cab623051b661e7b7f71bb6db134b1f37123b36e447c69fffd51baf5b937eR130

Because here it is configSettings:

https://github.com/microsoft/pyright/compare/1.1.375...1.1.376#diff-c3f0fa903325059f6e7dda1116458aafa72061ac3d1a51ddfd077a5dc0801030R326

rchiodo commented 3 weeks ago

@chegoryu this should be fixed in the next version.

chegoryu commented 3 weeks ago

Thank you so much.

erictraut commented 2 weeks ago

This is addressed in pyright 1.1.378.