PY-23623 Fixed: False positive: __getitem__ not being defined for list after isinstance check

While calculating severity, we infer type for qualifier in `v[0]` subscription expression.
While inferring type for qualifier, we infer type for `test_if_list` function.
While inferring type for `test_if_list` function, we infer `Any` type for `v` in `v[0]` to prevent recursion and resolve `[]` to nothing.
Unresolved `[]` is cached so when we ask for `[]` on `v[0]`, we receive nothing but at this moment we know type of `v` (`List[Any]`).
This commit is contained in:
Semyon Proshev
2017-06-09 15:41:22 +03:00
parent d70ba44a8c
commit 7d99b930a3
3 changed files with 20 additions and 7 deletions
@@ -356,12 +356,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
if (!isEnabled(node) || reference == null || reference.isSoft()) {
return;
}
HighlightSeverity severity = HighlightSeverity.ERROR;
if (reference instanceof PsiReferenceEx) {
severity = ((PsiReferenceEx)reference).getUnresolvedHighlightSeverity(myTypeEvalContext);
if (severity == null) return;
}
PyExceptPart guard = getImportErrorGuard(node);
final PyExceptPart guard = getImportErrorGuard(node);
if (guard != null) {
processReferenceInImportGuard(node, guard);
return;
@@ -375,7 +370,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
}
}
PsiElement target = null;
boolean unresolved;
final boolean unresolved;
if (reference instanceof PsiPolyVariantReference) {
final PsiPolyVariantReference poly = (PsiPolyVariantReference)reference;
final ResolveResult[] resolveResults = poly.multiResolve(false);
@@ -405,6 +400,10 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
}
}
if (!ignoreUnresolved) {
final HighlightSeverity severity = reference instanceof PsiReferenceEx
? ((PsiReferenceEx)reference).getUnresolvedHighlightSeverity(myTypeEvalContext)
: HighlightSeverity.ERROR;
if (severity == null) return;
registerUnresolvedReferenceProblem(node, reference, severity);
}
// don't highlight unresolved imports as unused
@@ -0,0 +1,9 @@
def test_if_list(value):
if isinstance(value, list):
v = [test_if_list(x) for x in value]
if len(v) > 1:
return v
else:
return v[0]
return value
@@ -603,6 +603,11 @@ public class PyUnresolvedReferencesInspectionTest extends PyInspectionTestCase {
doTest();
}
// PY-23623
public void testCachedOperatorInRecursivelyTypeInference() {
doTest();
}
@NotNull
@Override
protected Class<? extends PyInspection> getInspectionClass() {