Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new message called duplicate-value #5928

Merged
merged 16 commits into from
Apr 2, 2022
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ Release date: TBA

* Fix bug where specifically enabling just ``await-outside-async`` was not possible.

* Added new message called ``duplicate-value`` which identifies duplicate values inside sets.

Closes #5880

..
Insert your changelog randomly, it will reduce merge conflicts
(Ie. not necessarily at the end)
Expand Down Expand Up @@ -161,6 +165,9 @@ Release date: 2022-03-24

* Fix pyreverse diagrams type hinting for classmethods and staticmethods.

* Add new message ``duplicate-value`` for identifying duplicate values inside sets.
Pierre-Sassoulas marked this conversation as resolved.
Show resolved Hide resolved

Closes #5880
Pierre-Sassoulas marked this conversation as resolved.
Show resolved Hide resolved
* Fix pyreverse diagrams type hinting for methods returning None.

* Fix matching ``--notes`` options that end in a non-word character.
Expand Down
1 change: 1 addition & 0 deletions doc/data/messages/d/duplicate-value/bad.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
incorrect_set = {'value1', 23, 5, 'value1'} # [duplicate-value]
2 changes: 2 additions & 0 deletions doc/data/messages/d/duplicate-value/details.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
This error message is emitted when a set contains the same value two or more times.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Information like this should probably included in the message description in its declaration.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only need to move this to pylint/checkers/base/basic_checker.py

It aims to reduce duplication of values inside sets.
1 change: 1 addition & 0 deletions doc/data/messages/d/duplicate-value/good.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
correct_set = {1, 2, 'value', 'arg'}
Pierre-Sassoulas marked this conversation as resolved.
Show resolved Hide resolved
1 change: 1 addition & 0 deletions doc/whatsnew/2.13.rst
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ New checkers

Closes #5670


Pierre-Sassoulas marked this conversation as resolved.
Show resolved Hide resolved
Removed checkers
================

Expand Down
4 changes: 4 additions & 0 deletions doc/whatsnew/2.14.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ New checkers

Closes #4525

* Added new message called ``duplicate-value`` which identifies duplicate values inside sets.

Closes #5880

Removed checkers
================

Expand Down
22 changes: 21 additions & 1 deletion pylint/checkers/base/basic_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from pylint import interfaces
from pylint import utils as lint_utils
from pylint.checkers import BaseChecker, utils
from pylint.interfaces import IAstroidChecker
from pylint.interfaces import HIGH, IAstroidChecker
from pylint.reporters.ureports import nodes as reporter_nodes
from pylint.utils import LinterStats
from pylint.utils.utils import get_global_option
Expand Down Expand Up @@ -246,6 +246,11 @@ class BasicChecker(_BasicChecker):
"Used when an assert statement has a string literal as its first argument, which will "
"cause the assert to always pass.",
),
"W0130": (
"Duplicate value %r in set",
"duplicate-value",
"Used when a set contains the same value multiple times.",
),
}

reports = (("RP0101", "Statistics by type", report_by_type_stats),)
Expand Down Expand Up @@ -637,6 +642,21 @@ def visit_dict(self, node: nodes.Dict) -> None:
self.add_message("duplicate-key", node=node, args=key)
keys.add(key)

@utils.check_messages("duplicate-value")
def visit_set(self, node: nodes.Set) -> None:
"""Check duplicate value in set."""
values = set()
for v in node.elts:
if isinstance(v, nodes.Const):
value = v.value
else:
continue
if value in values:
self.add_message(
"duplicate-value", node=node, args=value, confidence=HIGH
)
values.add(value)

def visit_tryfinally(self, node: nodes.TryFinally) -> None:
"""Update try...finally flag."""
self._tryfinallys.append(node)
Expand Down
6 changes: 2 additions & 4 deletions pylint/checkers/format.py
Original file line number Diff line number Diff line change
Expand Up @@ -673,10 +673,8 @@ def is_line_length_check_activated(pylint_pattern_match_object) -> bool:
def specific_splitlines(lines: str) -> List[str]:
"""Split lines according to universal newlines except those in a specific sets."""
unsplit_ends = {
"\v",
"\x0b",
"\f",
"\x0c",
"\x0b", # synonym of \v
"\x0c", # synonym of \f
"\x1c",
"\x1d",
"\x1e",
Expand Down
18 changes: 18 additions & 0 deletions tests/functional/d/duplicate_value.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# pylint: disable = invalid-name, line-too-long
"""Simple test sets for checking duplicate values"""

set1 = {1, 2, 3, 4}
set2 = {1, 1, 2} # [duplicate-value]
set3 = {1, 2, 2} # [duplicate-value]

set4 = {'one', 'two', 'three'}
set5 = {'one', 'two', 'one'} # [duplicate-value]
set6 = {'one', 'two', 'two'} # [duplicate-value]

wrong_set = {12, 23, True, 6, True, 0, 12} # [duplicate-value, duplicate-value]
correct_set = {12, 13, 23, 24, 89}

wrong_set_mixed = {1, 2, 'value', 1} # [duplicate-value]
wrong_set = {'arg1', 'arg2', False, 'arg1', True} # [duplicate-value]

another_wrong_set = {2, 3, 'arg1', True, 'arg1', False, True} # [duplicate-value, duplicate-value]
10 changes: 10 additions & 0 deletions tests/functional/d/duplicate_value.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
duplicate-value:5:7:5:16::Duplicate value 1 in set:HIGH
duplicate-value:6:7:6:16::Duplicate value 2 in set:HIGH
duplicate-value:9:7:9:28::Duplicate value 'one' in set:HIGH
duplicate-value:10:7:10:28::Duplicate value 'two' in set:HIGH
duplicate-value:12:12:12:42::Duplicate value 12 in set:HIGH
duplicate-value:12:12:12:42::Duplicate value True in set:HIGH
duplicate-value:15:18:15:36::Duplicate value 1 in set:HIGH
duplicate-value:16:12:16:49::Duplicate value 'arg1' in set:HIGH
duplicate-value:18:20:18:61::Duplicate value 'arg1' in set:HIGH
duplicate-value:18:20:18:61::Duplicate value True in set:HIGH