From a309029eed5070938a376af88b0d046e8acda5c9 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Mon, 22 May 2023 10:42:56 -0700 Subject: [PATCH] Improve B033 (duplicate set items) (#385) - Include the repr() of the duplicate item in the error - Point the error directly at the duplicate item Fixes #384 --- bugbear.py | 20 ++++++++++++-------- tests/b033.py | 9 ++++++++- tests/test_bugbear.py | 16 +++++++++------- 3 files changed, 29 insertions(+), 16 deletions(-) diff --git a/bugbear.py b/bugbear.py index f4252fc..eff5c58 100644 --- a/bugbear.py +++ b/bugbear.py @@ -1351,12 +1351,16 @@ def check_for_b032(self, node): self.errors.append(B032(node.lineno, node.col_offset)) def check_for_b033(self, node): - constants = [ - item.value - for item in filter(lambda x: isinstance(x, ast.Constant), node.elts) - ] - if len(constants) != len(set(constants)): - self.errors.append(B033(node.lineno, node.col_offset)) + seen = set() + for elt in node.elts: + if not isinstance(elt, ast.Constant): + continue + if elt.value in seen: + self.errors.append( + B033(elt.lineno, elt.col_offset, vars=(repr(elt.value),)) + ) + else: + seen.add(elt.value) def compose_call_path(node): @@ -1757,8 +1761,8 @@ def visit_Lambda(self, node): B033 = Error( message=( - "B033 Sets should not contain duplicate items. Duplicate items will be replaced" - " with a single item at runtime." + "B033 Set should not contain duplicate item {}. Duplicate items will be" + " replaced with a single item at runtime." ) ) diff --git a/tests/b033.py b/tests/b033.py index 4738344..8ce42c9 100644 --- a/tests/b033.py +++ b/tests/b033.py @@ -1,6 +1,6 @@ """ Should emit: -B033 - on lines 6-12 +B033 - on lines 6-12, 16, 18 """ test = {1, 2, 3, 3, 5} @@ -10,6 +10,13 @@ test = {3, 3.0} test = {1, True} test = {0, False} +multi_line = { + "alongvalueeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + 1, + True, + 0, + False, +} test = {1, 2, 3, 3.5, 5} test = {"a", "b", "c", "d", "e"} diff --git a/tests/test_bugbear.py b/tests/test_bugbear.py index 73e7b19..9047a41 100644 --- a/tests/test_bugbear.py +++ b/tests/test_bugbear.py @@ -493,13 +493,15 @@ def test_b033(self): bbc = BugBearChecker(filename=str(filename)) errors = list(bbc.run()) expected = self.errors( - B033(6, 7), - B033(7, 7), - B033(8, 7), - B033(9, 7), - B033(10, 7), - B033(11, 7), - B033(12, 7), + B033(6, 17, vars=("3",)), + B033(7, 23, vars=("'c'",)), + B033(8, 21, vars=("True",)), + B033(9, 20, vars=("None",)), + B033(10, 11, vars=("3.0",)), + B033(11, 11, vars=("True",)), + B033(12, 11, vars=("False",)), + B033(16, 4, vars=("True",)), + B033(18, 4, vars=("False",)), ) self.assertEqual(errors, expected)