mirror of
https://github.com/microsoft/pyright.git
synced 2024-11-03 21:30:08 +03:00
Fixed a bug that led to a false negative when analyzing code with an async context manager that swallows exceptions.
This commit is contained in:
parent
b953f79228
commit
312667173c
@ -1686,7 +1686,22 @@ export function getCodeFlowEngine(
|
||||
const exitType = evaluator.getTypeOfObjectMember(node, cmType, exitMethodName)?.type;
|
||||
|
||||
if (exitType && isFunction(exitType) && exitType.details.declaredReturnType) {
|
||||
const returnType = exitType.details.declaredReturnType;
|
||||
let returnType = exitType.details.declaredReturnType;
|
||||
|
||||
// If it's an __aexit__ method, its return type will typically be wrapped
|
||||
// in a Coroutine, so we need to extract the return type from the third
|
||||
// type argument.
|
||||
if (isAsync && FunctionType.isAsync(exitType)) {
|
||||
if (
|
||||
isClassInstance(returnType) &&
|
||||
ClassType.isBuiltIn(returnType, 'Coroutine') &&
|
||||
returnType.typeArguments &&
|
||||
returnType.typeArguments.length >= 3
|
||||
) {
|
||||
returnType = returnType.typeArguments[2];
|
||||
}
|
||||
}
|
||||
|
||||
cmSwallowsExceptions = false;
|
||||
if (isClassInstance(returnType) && ClassType.isBuiltIn(returnType, 'bool')) {
|
||||
if (returnType.literalValue === undefined || returnType.literalValue === true) {
|
||||
|
@ -164,7 +164,7 @@ test('With2', () => {
|
||||
test('With3', () => {
|
||||
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['with3.py']);
|
||||
|
||||
TestUtils.validateResults(analysisResults, 4);
|
||||
TestUtils.validateResults(analysisResults, 5);
|
||||
});
|
||||
|
||||
test('With4', () => {
|
||||
|
@ -2,7 +2,7 @@
|
||||
# that suppress exceptions, as indicated by a return type of "bool"
|
||||
# for the __exit__ or __aexit__ method.
|
||||
|
||||
from contextlib import suppress
|
||||
from contextlib import suppress, AsyncExitStack
|
||||
|
||||
|
||||
def test1() -> None:
|
||||
@ -64,3 +64,10 @@ def test4() -> None:
|
||||
# This should generate an error because the
|
||||
# code is reachable.
|
||||
return 1
|
||||
|
||||
|
||||
# This should generate an error because AsyncExitStack
|
||||
# may swallow exceptions.
|
||||
async def test5() -> str:
|
||||
async with AsyncExitStack():
|
||||
return "from exit stack"
|
||||
|
Loading…
Reference in New Issue
Block a user