From 8a8cca65802428a7f80f41d503232accfb201d19 Mon Sep 17 00:00:00 2001 From: Semyon Proshev Date: Tue, 20 Feb 2018 17:25:21 +0300 Subject: [PATCH] Unify processing dict keys (PY-27375) --- .../PyDictDuplicateKeysInspection.java | 31 +++++++++++++------ .../PyDictDuplicateKeysInspection/test.py | 15 ++++++++- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/python/src/com/jetbrains/python/inspections/PyDictDuplicateKeysInspection.java b/python/src/com/jetbrains/python/inspections/PyDictDuplicateKeysInspection.java index b2fab1afcb44..26b053cf107c 100644 --- a/python/src/com/jetbrains/python/inspections/PyDictDuplicateKeysInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyDictDuplicateKeysInspection.java @@ -20,7 +20,6 @@ import com.intellij.codeInspection.ProblemsHolder; import com.intellij.lang.ASTNode; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElementVisitor; -import java.util.HashMap; import com.jetbrains.python.PyBundle; import com.jetbrains.python.inspections.quickfix.PyRemoveDictKeyQuickFix; import com.jetbrains.python.psi.*; @@ -28,6 +27,7 @@ import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.HashMap; import java.util.Map; /** @@ -63,13 +63,13 @@ public class PyDictDuplicateKeysInspection extends PyInspection { final Map map = new HashMap<>(); for (PyExpression exp : elements) { final PyExpression key = ((PyKeyValueExpression)exp).getKey(); - if (key instanceof PyNumericLiteralExpression - || key instanceof PyStringLiteralExpression || key instanceof PyReferenceExpression) { - if (map.keySet().contains(key.getText())) { - registerProblem(key, "Dictionary contains duplicate keys " + key.getText(), new PyRemoveDictKeyQuickFix()); - registerProblem(map.get(key.getText()), "Dictionary contains duplicate keys " + key.getText(), new PyRemoveDictKeyQuickFix()); + final String keyValue = getKeyValue(key); + if (keyValue != null) { + if (map.keySet().contains(keyValue)) { + registerProblem(key, "Dictionary contains duplicate keys " + keyValue, new PyRemoveDictKeyQuickFix()); + registerProblem(map.get(keyValue), "Dictionary contains duplicate keys " + keyValue, new PyRemoveDictKeyQuickFix()); } - map.put(key.getText(), key); + map.put(keyValue, key); } } } @@ -99,11 +99,22 @@ public class PyDictDuplicateKeysInspection extends PyInspection { } } + @Nullable + private static String getKeyValue(@NotNull PsiElement node) { + final PsiElement parent = node.getParent(); + if (parent instanceof PyKeywordArgument && ((PyKeywordArgument)parent).getKeywordNode() == node) { + return ((PyKeywordArgument)parent).getKeyword(); + } + return node instanceof PyStringLiteralExpression + ? ((PyStringLiteralExpression)node).getStringValue() + : node instanceof PyLiteralExpression || node instanceof PyReferenceExpression + ? node.getText() + : null; + } + private void checkKey(final Map map, final PsiElement node) { if (node == null) return; - String key = node.getText(); - if (node instanceof PyStringLiteralExpression) - key = ((PyStringLiteralExpression)node).getStringValue(); + String key = getKeyValue(node); if (map.keySet().contains(key)) { registerProblem(node, "Dictionary contains duplicate keys " + key); registerProblem(map.get(key), "Dictionary contains duplicate keys " + key); diff --git a/python/testData/inspections/PyDictDuplicateKeysInspection/test.py b/python/testData/inspections/PyDictDuplicateKeysInspection/test.py index 3c055540f4ba..dfce5d893867 100644 --- a/python/testData/inspections/PyDictDuplicateKeysInspection/test.py +++ b/python/testData/inspections/PyDictDuplicateKeysInspection/test.py @@ -1,5 +1,5 @@ dict = {key_1 : 1, key_2: 2, key_1 : 3} -dict = {'key_1' : 1, 'key_2': 2, 'key_2' : 3} +dict = {'key_1' : 1, 'key_2': 2, 'key_2' : 3} a = {} {'key_1' : 1, 'key_2': 2} @@ -15,3 +15,16 @@ dict = dict((('key''key', 666), ('k', 123)), key=4) dict([('key', 666), ('ky', 123)]) + +# PY-27375 +d = {'a': 1, "a": 2} +d = dict([('a', 1), ("a", 2)]) + +d = {1: 1, 1: 2} +d = dict([(1, 1), (1, 2)]) + +d = {True: 1, True: 2} +d = dict([(True, 1), (True, 2)]) + +d = {None: 1, None: 2} +d = dict([(None, 1), (None, 2)]) \ No newline at end of file