Ignore Python union types with unknown components during type checking

This commit is contained in:
Andrey Vlasovskikh
2011-08-09 21:25:15 +04:00
parent 694dadf51a
commit 2898448021
3 changed files with 73 additions and 6 deletions
@@ -3,6 +3,8 @@ package com.jetbrains.python.psi.types;
import com.jetbrains.python.psi.PyClass;
import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* @author vlan
*/
@@ -22,8 +24,14 @@ public class PyTypeChecker {
return match(expected, ((PyTypeReference)actual).resolve(null, context), context);
}
if (actual instanceof PyUnionType) {
for (PyType t : ((PyUnionType)actual).getMembers()) {
if (!match(expected, t, context)) {
final List<PyType> members = ((PyUnionType)actual).getMembers();
for (PyType m : members) {
if (m == null) {
return true;
}
}
for (PyType m : members) {
if (!match(expected, m, context)) {
return false;
}
}
@@ -237,9 +237,7 @@ public class PyTypeParser {
PyType result = null;
for (TextRange range : ranges) {
final PyType t = parse(anchor, range.substring(type), types, fullRanges, offset + range.getStartOffset());
if (t != null) {
result = (result == null) ? t : PyUnionType.union(result, t);
}
result = (result == null) ? t : PyUnionType.union(result, t);
}
return result;
}
@@ -220,4 +220,65 @@ def test_old_style_classes():
:type x: object
"""
pass
f(C()) #pass
f(C()) #pass
def test_partly_unknown_type():
def f():
"""
:rtype: None or unknown or int or long
"""
def g(x):
"""
:type x: object
"""
g(f())
def test_type_assertions():
def f_1():
"""
:rtype: int or str or None
"""
def f_2():
"""
:rtype: int or None
"""
def f_3():
"""
:rtype: unknown
"""
def f_4():
"""
:rtype: object
"""
def f_5():
"""
:rtype: int or object
"""
def f_6():
"""
:rtype: int or unknown or float
"""
def f_7():
"""
:rtype: int or unknown
"""
def print_int(x):
"""
:type x: int
"""
print(x)
def print_int_or_str(x):
"""
:type x: int or str
"""
x_1 = f_1()
print_int(<warning descr="Expected type 'int', got 'one of (int, str, None)' instead">x_1</warning>)
print_int_or_str(<warning descr="Expected type 'one of (int, str)', got 'one of (int, str, None)' instead">x_1</warning>)
if isinstance(x_1, int):
print_int(x_1)
if isinstance(x_1, str):
print_int_or_str(x_1)
x_7 = f_7()
print_int(x_7)