diff --git a/python/src/com/jetbrains/python/codeInsight/controlflow/PyTypeAssertionEvaluator.java b/python/src/com/jetbrains/python/codeInsight/controlflow/PyTypeAssertionEvaluator.java index 464b905615a8..064a55dcfaac 100644 --- a/python/src/com/jetbrains/python/codeInsight/controlflow/PyTypeAssertionEvaluator.java +++ b/python/src/com/jetbrains/python/codeInsight/controlflow/PyTypeAssertionEvaluator.java @@ -167,7 +167,7 @@ public class PyTypeAssertionEvaluator extends PyRecursiveElementVisitor { else if (initial instanceof PyUnionType) { return Ref.create(((PyUnionType)initial).exclude(transformedType, context)); } - else if (PyTypeChecker.match(transformedType, initial, context)) { + else if (initial != null && PyTypeChecker.match(transformedType, initial, context)) { return null; } return Ref.create(initial); diff --git a/python/testSrc/com/jetbrains/python/PyTypeTest.java b/python/testSrc/com/jetbrains/python/PyTypeTest.java index 3abba779fdfb..080e984a8585 100644 --- a/python/testSrc/com/jetbrains/python/PyTypeTest.java +++ b/python/testSrc/com/jetbrains/python/PyTypeTest.java @@ -2012,6 +2012,26 @@ public class PyTypeTest extends PyTestCase { " expr = var"); } + // PY-21626 + public void testNestedConflictingIsNoneChecksInitialAny() { + doTest("Optional[Any]", + "def f(x):\n" + + " if x is None:\n" + + " if x is not None:\n" + + " pass\n" + + " expr = x"); + } + + // PY-21626 + public void testNestedConflictingIsNoneChecksInitialKnown() { + doTest("Optional[str]", + "x = 'foo'\n" + + "if x is None:\n" + + " if x is not None:\n" + + " pass\n" + + "expr = x"); + } + private static List getTypeEvalContexts(@NotNull PyExpression element) { return ImmutableList.of(TypeEvalContext.codeAnalysis(element.getProject(), element.getContainingFile()).withTracing(), TypeEvalContext.userInitiated(element.getProject(), element.getContainingFile()).withTracing());