Skip to content

Commit

Permalink
Add B033: Duplicate items in sets (#373)
Browse files Browse the repository at this point in the history
* Add B033: Duplicate items in sets

* Simplify by checking lengths

---------

Co-authored-by: Cooper Lees <[email protected]>
  • Loading branch information
FozzieHi and cooperlees authored May 9, 2023
1 parent 3f16173 commit eb300be
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 0 deletions.
3 changes: 3 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@ second usage. Save the result to a list if the result is needed multiple times.

**B032**: Possible unintentional type annotation (using ``:``). Did you mean to assign (using ``=``)?

**B033**: Sets should not contain duplicate items. Duplicate items will be replaced with a single item at runtime.

Opinionated warnings
~~~~~~~~~~~~~~~~~~~~

Expand Down Expand Up @@ -337,6 +339,7 @@ Unreleased
* flake8-bugbear is now >= 3.8.1 project like flake8>=6.0.0
* This has allowed some more modern AST usage cleanup and less CI running etc.
* B030: Fix crash on certain unusual except handlers (e.g. ``except a[0].b:``)
* Add B033: Check for duplicate items in sets.

23.3.12
~~~~~~~~
Expand Down
19 changes: 19 additions & 0 deletions bugbear.py
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,10 @@ def visit_Import(self, node):
self.check_for_b005(node)
self.generic_visit(node)

def visit_Set(self, node):
self.check_for_b033(node)
self.generic_visit(node)

def check_for_b005(self, node):
if isinstance(node, ast.Import):
for name in node.names:
Expand Down Expand Up @@ -1346,6 +1350,14 @@ 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))


def compose_call_path(node):
if isinstance(node, ast.Attribute):
Expand Down Expand Up @@ -1743,6 +1755,13 @@ 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."
)
)

# Warnings disabled by default.
B901 = Error(
message=(
Expand Down
17 changes: 17 additions & 0 deletions tests/b033.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"""
Should emit:
B033 - on lines 6-12
"""

test = {1, 2, 3, 3, 5}
test = {"a", "b", "c", "c", "e"}
test = {True, False, True}
test = {None, True, None}
test = {3, 3.0}
test = {1, True}
test = {0, False}

test = {1, 2, 3, 3.5, 5}
test = {"a", "b", "c", "d", "e"}
test = {True, False}
test = {None}
16 changes: 16 additions & 0 deletions tests/test_bugbear.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
B030,
B031,
B032,
B033,
B901,
B902,
B903,
Expand Down Expand Up @@ -487,6 +488,21 @@ def test_b032(self):
)
self.assertEqual(errors, expected)

def test_b033(self):
filename = Path(__file__).absolute().parent / "b033.py"
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),
)
self.assertEqual(errors, expected)

def test_b908(self):
filename = Path(__file__).absolute().parent / "b908.py"
bbc = BugBearChecker(filename=str(filename))
Expand Down

0 comments on commit eb300be

Please sign in to comment.