Skip to content

Commit 8c178ce

Browse files
authored
Fixed bug in code flow analysis that resulted in an incorrect type evaluation when a "NoReturn" call is made within a code block protected by an exception-suppressing context manager. This addresses #6850. (#6859)
1 parent 76b2e69 commit 8c178ce

File tree

3 files changed

+22
-4
lines changed

3 files changed

+22
-4
lines changed

packages/pyright-internal/src/analyzer/binder.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3240,6 +3240,8 @@ export class Binder extends ParseTreeWalker {
32403240

32413241
private _createCallFlowNode(node: CallNode) {
32423242
if (!this._isCodeUnreachable()) {
3243+
this._addExceptTargets(this._currentFlowNode!);
3244+
32433245
const flowNode: FlowCall = {
32443246
flags: FlowFlags.Call,
32453247
id: this._getUniqueFlowNodeId(),
@@ -3249,10 +3251,6 @@ export class Binder extends ParseTreeWalker {
32493251

32503252
this._currentFlowNode = flowNode;
32513253
}
3252-
3253-
if (!this._isCodeUnreachable()) {
3254-
this._addExceptTargets(this._currentFlowNode!);
3255-
}
32563254
}
32573255

32583256
private _createVariableAnnotationFlowNode() {

packages/pyright-internal/src/analyzer/codeFlowEngine.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,10 @@ export function getCodeFlowEngine(
492492
}
493493
}
494494

495+
if (flowTypeResult && !isFlowNodeReachable(flowNode)) {
496+
flowTypeResult = undefined;
497+
}
498+
495499
return setCacheEntry(curFlowNode, flowTypeResult?.type, !!flowTypeResult?.isIncomplete);
496500
}
497501

packages/pyright-internal/src/tests/samples/with3.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# for the __exit__ or __aexit__ method.
44

55
from contextlib import suppress, AsyncExitStack
6+
from typing import Never
67

78

89
def test1() -> None:
@@ -71,3 +72,18 @@ def test4() -> None:
7172
async def test5() -> str:
7273
async with AsyncExitStack():
7374
return "from exit stack"
75+
76+
77+
def no_return() -> Never:
78+
raise Exception()
79+
80+
81+
def test6():
82+
val = None
83+
with suppress():
84+
val = 1
85+
no_return()
86+
val = 2
87+
88+
assert val is not None
89+
reveal_type(val, expected_text="Literal[1]")

0 commit comments

Comments
 (0)