Using contextlib.suppress should not result in following code being marked as unreachable.
Code following the suppress context block is marked as unreachable if there is a return statement in the block.

from contextlib import suppress
def test():
class A():
b: str
a = A()
with suppress(AttributeError):
return a.b
return "I am reachable"
User belongs to experiment group 'AlwaysDisplayTestExplorer - control'
User belongs to experiment group 'ShowPlayIcon - start'
User belongs to experiment group 'DebugAdapterFactory - experiment'
User belongs to experiment group 'PtvsdWheels37 - experiment'
User belongs to experiment group 'UseTerminalToGetActivatedEnvVars - control'
User belongs to experiment group 'LocalZMQKernel - experiment'
User belongs to experiment group 'CollectLSRequestTiming - control'
User belongs to experiment group 'CollectNodeLSRequestTiming - experiment'
User belongs to experiment group 'EnableIPyWidgets - experiment'
User belongs to experiment group 'RunByLine - experiment'
User belongs to experiment group 'CustomEditorSupport - control'
User belongs to experiment group 'pythonaacf'
Error 2020-10-15 12:57:23: Exception while attempting zmq : [Error: /snap/core/current/usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.22' not found (required by /home/user/.vscode/extensions/ms-python.python-2020.9.114305/out/client/node_modules/zeromq/prebuilds/linux-x64/electron.napi.glibc.node)
at process.func [as dlopen] (electron/js2c/asar.js:140:31)
at Object.Module._extensions..node (internal/modules/cjs/loader.js:1081:18)
at Object.func [as .node] (electron/js2c/asar.js:140:31)
at Module.load (internal/modules/cjs/loader.js:862:32)
at Module._load (internal/modules/cjs/loader.js:774:14)
at Function.Module._load (electron/js2c/asar.js:769:28)
at Function.t._load (/snap/code/47/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:1057:776)
at Function.i._load (/snap/code/47/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:1027:486)
at Function.n._load (/snap/code/47/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:1023:767)
at Module.require (internal/modules/cjs/loader.js:899:19)
at r (/snap/code/47/usr/share/code/resources/app/out/vs/loader.js:17:346)
at load (/home/user/.vscode/extensions/ms-python.python-2020.9.114305/out/client/node_modules/node-gyp-build/index.js:21:10)
at Object.<anonymous> (/home/user/.vscode/extensions/ms-python.python-2020.9.114305/out/client/node_modules/zeromq/lib/native.js:6:43)
at Module.i._compile (/snap/code/47/usr/share/code/resources/app/out/vs/loader.js:17:571)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1051:10)
at Module.load (internal/modules/cjs/loader.js:862:32)
at Module._load (internal/modules/cjs/loader.js:774:14)
at Function.Module._load (electron/js2c/asar.js:769:28)
at Function.t._load (/snap/code/47/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:1057:776)
at Function.i._load (/snap/code/47/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:1027:486)
at Function.n._load (/snap/code/47/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:1023:767)
at Module.require (internal/modules/cjs/loader.js:899:19)
at r (/snap/code/47/usr/share/code/resources/app/out/vs/loader.js:17:346)
at Object.<anonymous> (/home/user/.vscode/extensions/ms-python.python-2020.9.114305/out/client/node_modules/zeromq/lib/index.js:3:16)
at Module.i._compile (/snap/code/47/usr/share/code/resources/app/out/vs/loader.js:17:571)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1051:10)
at Module.load (internal/modules/cjs/loader.js:862:32)
at Module._load (internal/modules/cjs/loader.js:774:14)
at Function.Module._load (electron/js2c/asar.js:769:28)
at Function.t._load (/snap/code/47/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:1057:776)
at Function.i._load (/snap/code/47/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:1027:486)
at Function.n._load (/snap/code/47/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:1023:767)
at Module.require (internal/modules/cjs/loader.js:899:19)
at r (/snap/code/47/usr/share/code/resources/app/out/vs/loader.js:17:346)
at Object.<anonymous> (/home/user/.vscode/extensions/ms-python.python-2020.9.114305/out/client/extension.js:24:302772)
at n (/home/user/.vscode/extensions/ms-python.python-2020.9.114305/out/client/extension.js:1:186)
at /home/user/.vscode/extensions/ms-python.python-2020.9.114305/out/client/extension.js:56:731654
at processTicksAndRejections (internal/process/task_queues.js:94:5)
at async d.zmqSupportedImpl (/home/user/.vscode/extensions/ms-python.python-2020.9.114305/out/client/extension.js:56:731621)]
> conda --version
> pyenv root
> python3.7 ~/.vscode/extensions/ms-python.python-2020.9.114305/pythonFiles/pyvsc-run-isolated.py -c "import sys;print(sys.executable)"
> python3.6 ~/.vscode/extensions/ms-python.python-2020.9.114305/pythonFiles/pyvsc-run-isolated.py -c "import sys;print(sys.executable)"
> python3 ~/.vscode/extensions/ms-python.python-2020.9.114305/pythonFiles/pyvsc-run-isolated.py -c "import sys;print(sys.executable)"
> python2 ~/.vscode/extensions/ms-python.python-2020.9.114305/pythonFiles/pyvsc-run-isolated.py -c "import sys;print(sys.executable)"
> python ~/.vscode/extensions/ms-python.python-2020.9.114305/pythonFiles/pyvsc-run-isolated.py -c "import sys;print(sys.executable)"
> /usr/bin/python3.7 ~/.vscode/extensions/ms-python.python-2020.9.114305/pythonFiles/pyvsc-run-isolated.py -c "import sys;print(sys.executable)"
> conda info --json
> conda env list
> conda env list
Starting Pylance language server.
Python interpreter path: /usr/bin/python3.7
> /usr/bin/python3.7 ~/.vscode/extensions/ms-python.python-2020.9.114305/pythonFiles/testing_tools/run_adapter.py discover pytest -- --rootdir ~/Documents/Code/vscode-bugs -s --cache-clear
cwd: ~/Documents/Code/vscode-bugs
> /usr/bin/python3.7 ~/.vscode/extensions/ms-python.python-2020.9.114305/pythonFiles/testing_tools/run_adapter.py discover pytest -- --rootdir ~/Documents/Code/vscode-bugs -s --cache-clear
cwd: ~/Documents/Code/vscode-bugs
Error 2020-10-15 12:57:25: Failed to parse discovered Test [r [Error]: Traceback (most recent call last):
File "/home/user/.vscode/extensions/ms-python.python-2020.9.114305/pythonFiles/testing_tools/run_adapter.py", line 17, in <module>
from testing_tools.adapter.__main__ import parse_args, main
File "/home/user/.vscode/extensions/ms-python.python-2020.9.114305/pythonFiles/testing_tools/adapter/__main__.py", line 9, in <module>
from . import pytest, report
File "/home/user/.vscode/extensions/ms-python.python-2020.9.114305/pythonFiles/testing_tools/adapter/pytest/__init__.py", line 7, in <module>
from ._discovery import discover
File "/home/user/.vscode/extensions/ms-python.python-2020.9.114305/pythonFiles/testing_tools/adapter/pytest/_discovery.py", line 8, in <module>
import pytest
ModuleNotFoundError: No module named 'pytest'
at ChildProcess.<anonymous> (/home/user/.vscode/extensions/ms-python.python-2020.9.114305/out/client/extension.js:9:53541)
at Object.onceWrapper (events.js:313:26)
at ChildProcess.emit (events.js:223:5)
at maybeClose (internal/child_process.js:1021:16)
at Socket.<anonymous> (internal/child_process.js:430:11)
at Socket.emit (events.js:223:5)
at Pipe.<anonymous> (net.js:664:12)]
> /usr/bin/python3.7 ~/.vscode/extensions/ms-python.python-2020.9.114305/pythonFiles/pyvsc-run-isolated.py -c "import pytest"
> /usr/bin/python3.7 ~/.vscode/extensions/ms-python.python-2020.9.114305/pythonFiles/pyvsc-run-isolated.py -c "import pytest"
> /usr/bin/python3.7 ~/.vscode/extensions/ms-python.python-2020.9.114305/pythonFiles/pyvsc-run-isolated.py mypy --ignore-missing-imports --follow-imports=silent --show-column-numbers ~/Documents/Code/vscode-bugs/test.py
cwd: ~/Documents/Code/vscode-bugs
> /usr/bin/python3.7 ~/.vscode/extensions/ms-python.python-2020.9.114305/pythonFiles/pyvsc-run-isolated.py mypy --ignore-missing-imports --follow-imports=silent --show-column-numbers ~/Documents/Code/vscode-bugs/test.py
cwd: ~/Documents/Code/vscode-bugs
> /usr/bin/python3.7 ~/.vscode/extensions/ms-python.python-2020.9.114305/pythonFiles/pyvsc-run-isolated.py -c "import mypy"
> /usr/bin/python3.7 ~/.vscode/extensions/ms-python.python-2020.9.114305/pythonFiles/pyvsc-run-isolated.py -c "import mypy"
> /usr/bin/python3.7 ~/.vscode/extensions/ms-python.python-2020.9.114305/pythonFiles/pyvsc-run-isolated.py -c "import mypy"
> /usr/bin/python3.7 ~/.vscode/extensions/ms-python.python-2020.9.114305/pythonFiles/pyvsc-run-isolated.py -c "import mypy"
Linter 'mypy' is not installed. Please install it or select another linter".
Error: Module 'mypy' not installed.
@erictraut I may be misremembering, but I had thought the code flow analysis had been modified to treat context managers with an __exit__ that returns bool as swallowing exceptions. Is that not the case? I know that's the assumption that typeshed makes.
Yeah, that's not the case. That's a very large change and will have impacts on perf and (potentially) correctness in some cases. It effectively means that every with statement needs to be treated as a try/catch/finally statement in the code flow graph, which is built prior to knowing any type information. We'd be trading off what is a relatively minor annoyance (grayed-out code in some rare cases) for false positive errors in some cases.
Since this convention was never ratified in a PEP — and because of the tradeoffs it entails, I haven't implemented it.
If the grayed-out code bothers users, there is an easy workaround — use a try/catch block rather than relying on a context manager to handle exceptions.
We'd be trading off what is a relatively minor annoyance (grayed-out code in some rare cases) for false positive errors in some cases.
The catch here to me is that because the code flow is "proving" that the code below is unreachable, it's not just a visual problem but impacts the code below. It was my impression that LSP features, inference, additional flow, etc, inside grayed-out code is limited because the analysis believes the code to be dead.
Yeah, there are potentially false negatives — actual errors in that code that are not reported. In general, false positives are worse than false negatives, but I agree that both are undesirable.
I'll mark it as an enhancement for now; I think there's some discussion across type checkers to be had here as to what is expected from them, especially if this isn't in any specification.
Adding a "Me too" here. and yes using a try/except is a workaround, but just dropping exceptions with with suppress is far cleaner.
This will be addressed in the next release.
This issue has been fixed in version 2020.12.1, which we've just released. You can find the changelog here: https://github.com/microsoft/pylance-release/blob/master/CHANGELOG.md#2020121-9-december-2020
This issue just came back for me with version 2021.1.1.
I downloaded the VSIX file for the last 5 versions and from 2020.12.1 to 2021.1.0 everything was fine. Interestingly enough I also do not have the issue with 2020.12.0.
@Cielquan, I agree with you. It reappeared in version 2021.1.1, but not in version 2021.1.0.
Thanks for the bug report. You are correct, I introduced a regression in this code when fixing another bug. The nature of the regression was such that it eluded our unit tests. I've fixed the regression and improved our unit tests so this won't happen again in the future. This will be fixed in the next release. Apologies for any inconvenience.
This issue has been fixed in version 2021.1.2, which we've just released. You can find the changelog here: https://github.com/microsoft/pylance-release/blob/main/CHANGELOG.md#202112-20-january-2021
Most helpful comment
Thanks for the bug report. You are correct, I introduced a regression in this code when fixing another bug. The nature of the regression was such that it eluded our unit tests. I've fixed the regression and improved our unit tests so this won't happen again in the future. This will be fixed in the next release. Apologies for any inconvenience.