diff --git a/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java b/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java index 8ce29a200eda..a4d3cbe76422 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java +++ b/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java @@ -395,7 +395,8 @@ public class PyBuiltinCache { } } - private PyType getStrOrUnicodeType() { + @Nullable + public PyType getStrOrUnicodeType() { return PyUnionType.union(getObjectType("str"), getObjectType("unicode")); } diff --git a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java index d6862d48bbaa..2a60dd6f54c4 100644 --- a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java +++ b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java @@ -61,6 +61,14 @@ public class PyTypeChecker { private static boolean match(@Nullable PyType expected, @Nullable PyType actual, @NotNull TypeEvalContext context, @Nullable Map substitutions, boolean recursive) { // TODO: subscriptable types?, module types?, etc. + if (actual instanceof PyClassType) { + final PyClassType classType = (PyClassType)actual; + final PyBuiltinCache builtinCache = PyBuiltinCache.getInstance(classType.getPyClass()); + + if (actual == builtinCache.getObjectType(PyNames.BASESTRING)) { + return match(expected, builtinCache.getStrOrUnicodeType(), context, substitutions, recursive); + } + } if (expected instanceof PyGenericType && substitutions != null) { final PyGenericType generic = (PyGenericType)expected; final PyType subst = substitutions.get(generic); diff --git a/python/testData/inspections/PyTypeCheckerInspection/ActualBasestringExpectedUnionStrUnicode.py b/python/testData/inspections/PyTypeCheckerInspection/ActualBasestringExpectedUnionStrUnicode.py new file mode 100644 index 000000000000..8e1907b57b18 --- /dev/null +++ b/python/testData/inspections/PyTypeCheckerInspection/ActualBasestringExpectedUnionStrUnicode.py @@ -0,0 +1,5 @@ +def hello(filename): + """ + :type filename: basestring + """ + open(filename) \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/inspections/PyTypeCheckerInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyTypeCheckerInspectionTest.java index be038d980254..9508c405bd1b 100644 --- a/python/testSrc/com/jetbrains/python/inspections/PyTypeCheckerInspectionTest.java +++ b/python/testSrc/com/jetbrains/python/inspections/PyTypeCheckerInspectionTest.java @@ -331,4 +331,9 @@ public class PyTypeCheckerInspectionTest extends PyTestCase { public void testCsvRegisterDialect() { doMultiFileTest(); } + + // PY-20364 + public void testActualBasestringExpectedUnionStrUnicode() { + doTest(); + } }