From 4120e431a8ccf438190f9d852774130ac853201b Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Sat, 18 Mar 2017 20:57:26 +0300 Subject: [PATCH] Remove duplicate conversion from class type to instance type in PyTypeAssertionEvaluator Also special handling for "x = Sub(); assert isinstance(x, Super)" doesn't conflict anymore with the support of cases like "x = Sub(); assert not isinstance(x, Super)", i.e. we distinguish between positive and negative type assertions when the actual type is a subclass of the expected type. Though, strictly speaking, it hasn't broken anything (yet). --- .../controlflow/PyTypeAssertionEvaluator.java | 23 ++++++------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/python/src/com/jetbrains/python/codeInsight/controlflow/PyTypeAssertionEvaluator.java b/python/src/com/jetbrains/python/codeInsight/controlflow/PyTypeAssertionEvaluator.java index 377d5b4520b3..2eea3ed647ff 100644 --- a/python/src/com/jetbrains/python/codeInsight/controlflow/PyTypeAssertionEvaluator.java +++ b/python/src/com/jetbrains/python/codeInsight/controlflow/PyTypeAssertionEvaluator.java @@ -68,11 +68,7 @@ public class PyTypeAssertionEvaluator extends PyRecursiveElementVisitor { final PyReferenceExpression target = (PyReferenceExpression)args[0]; final PyExpression typeElement = args[1]; - // TODO support tuple of types as the second argument of isinstance() - pushAssertion(target, myPositive, context -> { - final PyType type = context.getType(typeElement); - return type instanceof PyClassType ? ((PyClassType)type).toInstance() : type; - }); + pushAssertion(target, myPositive, context -> context.getType(typeElement)); } } else if (node.isCalleeText(PyNames.CALLABLE_BUILTIN)) { @@ -150,6 +146,11 @@ public class PyTypeAssertionEvaluator extends PyRecursiveElementVisitor { @NotNull TypeEvalContext context) { final PyType transformedType = transformTypeFromAssertion(suggested); if (positive) { + if (!(initial instanceof PyUnionType) && + !PyTypeChecker.isUnknown(initial) && + PyTypeChecker.match(transformedType, initial, context)) { + return initial; + } return transformedType; } else if (initial instanceof PyUnionType) { @@ -184,17 +185,7 @@ public class PyTypeAssertionEvaluator extends PyRecursiveElementVisitor { final InstructionTypeCallback typeCallback = new InstructionTypeCallback() { @Override public PyType getType(TypeEvalContext context, @Nullable PsiElement anchor) { - final PyType initial = context.getType(target); - final PyType suggested = suggestedType.apply(context); - - if (!(initial instanceof PyUnionType) && - !PyTypeChecker.isUnknown(initial) && - PyTypeChecker.match(suggested, initial, context)) { - return initial; - } - else { - return createAssertionType(initial, suggested, positive, context); - } + return createAssertionType(context.getType(target), suggestedType.apply(context), positive, context); } };