From c3b92c6c88d8c0e0c4c3576505e4f7cd72d6a5fb Mon Sep 17 00:00:00 2001 From: Semyon Proshev Date: Tue, 8 Nov 2016 21:24:54 +0300 Subject: [PATCH] PY-20409 Fixed: dict.get(..., None) is assumed to return None PyTypeChecker: if expected type is UnionType, try to match actual type with its non-generic members and then with generic ones --- .../src/com/jetbrains/python/psi/types/PyTypeChecker.java | 6 +++++- python/testSrc/com/jetbrains/python/PyTypeTest.java | 7 +++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java index 2a60dd6f54c4..0a315c4813a3 100644 --- a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java +++ b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java @@ -127,7 +127,11 @@ public class PyTypeChecker { return false; } if (expected instanceof PyUnionType) { - for (PyType t : ((PyUnionType)expected).getMembers()) { + final Collection expectedUnionTypeMembers = ((PyUnionType)expected).getMembers(); + final StreamEx notGenericTypes = StreamEx.of(expectedUnionTypeMembers).filter(type -> !PyGenericType.class.isInstance(type)); + final StreamEx genericTypes = StreamEx.of(expectedUnionTypeMembers).select(PyGenericType.class); + + for (PyType t : notGenericTypes.append(genericTypes)) { if (match(t, actual, context, substitutions, recursive)) { return true; } diff --git a/python/testSrc/com/jetbrains/python/PyTypeTest.java b/python/testSrc/com/jetbrains/python/PyTypeTest.java index 259eee353529..35f94842e56f 100644 --- a/python/testSrc/com/jetbrains/python/PyTypeTest.java +++ b/python/testSrc/com/jetbrains/python/PyTypeTest.java @@ -1398,6 +1398,13 @@ public class PyTypeTest extends PyTestCase { "expr = float.fromhex(\"0.5\")"); } + // PY-20409 + public void testGetFromDictWithDefaultNoneValue() { + doTest("Any", + "d = {}\n" + + "expr = d.get(\"abc\", None)"); + } + // PY-20757 public void testMinOrNone() { doTest("Union[None, Any]",