From 2898448021376356849372f5e321b43946cae35f Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Tue, 9 Aug 2011 21:23:23 +0400 Subject: [PATCH] Ignore Python union types with unknown components during type checking --- .../python/psi/types/PyTypeChecker.java | 12 +++- .../python/psi/types/PyTypeParser.java | 4 +- .../PyTypeCheckerInspection/test.py | 63 ++++++++++++++++++- 3 files changed, 73 insertions(+), 6 deletions(-) diff --git a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java index 95f8408722ba..f687a0147188 100644 --- a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java +++ b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java @@ -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 members = ((PyUnionType)actual).getMembers(); + for (PyType m : members) { + if (m == null) { + return true; + } + } + for (PyType m : members) { + if (!match(expected, m, context)) { return false; } } diff --git a/python/src/com/jetbrains/python/psi/types/PyTypeParser.java b/python/src/com/jetbrains/python/psi/types/PyTypeParser.java index d541496f1cc6..83fd47d9c3de 100644 --- a/python/src/com/jetbrains/python/psi/types/PyTypeParser.java +++ b/python/src/com/jetbrains/python/psi/types/PyTypeParser.java @@ -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; } diff --git a/python/testData/inspections/PyTypeCheckerInspection/test.py b/python/testData/inspections/PyTypeCheckerInspection/test.py index e1111cb9740c..b49e4b8cc137 100644 --- a/python/testData/inspections/PyTypeCheckerInspection/test.py +++ b/python/testData/inspections/PyTypeCheckerInspection/test.py @@ -220,4 +220,65 @@ def test_old_style_classes(): :type x: object """ pass - f(C()) #pass \ No newline at end of file + 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(x_1) + print_int_or_str(x_1) + 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) \ No newline at end of file