Skip to content

Commit

Permalink
'trailing-comma-tuple' check was added
Browse files Browse the repository at this point in the history
This message is emitted when pylint finds an one-element tuple,
created by a stray comma. This can suggest a potential problem in the
code and it is recommended to use parantheses in order to emphasise the
creation of a tuple, rather than relying on the comma itself.

Close #300
  • Loading branch information
PCManticore committed Dec 18, 2016
1 parent 7aee3e3 commit 6ae2b77
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 3 deletions.
7 changes: 7 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ What's New in Pylint 2.0?

Release date: tba

* 'trailing-comma-tuple' check was added

This message is emitted when pylint finds an one-element tuple,
created by a stray comma. This can suggest a potential problem in the
code and it is recommended to use parantheses in order to emphasise the
creation of a tuple, rather than relying on the comma itself.

* Don't emit not-callable for instances with unknown bases.

Close #1213
Expand Down
19 changes: 19 additions & 0 deletions doc/whatsnew/2.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,25 @@ New checkers
value = truth_value if condition else false_value
* A new refactoring check was added, 'trailing-comma-tuple', which is emitted
when pylint finds an one-element tuple, created by a stray comma. This can
suggest a potential problem in the code and it is recommended to use parantheses
in order to emphasise the creation of a tuple, rather than relying on the comma
itself.

The warning is emitted for such a construct:

.. code-block:: python
a = 1,
The warning can be fixed by adding parantheses:

.. code-block:: python
a = (1, )
Other Changes
=============

Expand Down
36 changes: 33 additions & 3 deletions pylint/checkers/refactoring.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import collections
import itertools
import tokenize

import astroid
from astroid import decorators
Expand Down Expand Up @@ -93,6 +94,14 @@ class RefactoringChecker(checkers.BaseTokenChecker):
'following a chain of ifs, all of them containing a '
'return statement.'
),
'R1707': ('Disallow trailing comma tuple',
'trailing-comma-tuple',
'In Python, a tuple is actually created by the comma symbol, '
'not by the parentheses. Unfortunately, one can actually create a '
'tuple by misplacing a trailing comma, which can lead to potential '
'weird bugs in your code. You should always use parentheses '
'explicitly for creating a tuple.',
{'minversion': (3, 0)}),
}
options = (('max-nested-blocks',
{'default': 5, 'type': 'int', 'metavar': '<int>',
Expand Down Expand Up @@ -196,11 +205,32 @@ def _check_simplifiable_if(self, node):

def process_tokens(self, tokens):
# Process tokens and look for 'if' or 'elif'
for _, token, _, _, _ in tokens:
if token == 'elif':
for index, token in enumerate(tokens):
if token.string == 'elif':
self._elifs.append(True)
elif token == 'if':
elif token.string == 'if':
self._elifs.append(False)
elif six.PY3 and token.exact_type == tokenize.COMMA:
self._check_one_element_trailing_comma_tuple(tokens, token, index)

def _check_one_element_trailing_comma_tuple(self, tokens, token, index):
left_tokens = itertools.islice(tokens, index + 1, None)
same_line_tokens = (
other_token for other_token in left_tokens
if other_token.start[0] == token.start[0]
)
is_last_element = all(
token.type in (tokenize.NEWLINE, tokenize.COMMENT)
for token in same_line_tokens
)
if not is_last_element:
return

assign_token = tokens[index-2:index-1]
if assign_token and assign_token[0].string == '=':
if self.linter.is_message_enabled('trailing-comma-tuple'):
self.add_message('trailing-comma-tuple',
line=token.start[0])

def leave_module(self, _):
self._init()
Expand Down
14 changes: 14 additions & 0 deletions pylint/test/functional/trailing_comma_tuple.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"""Check trailing comma one element tuples."""
# pylint: disable=bad-whitespace
AAA = 1, # [trailing-comma-tuple]
BBB = "aaaa", # [trailing-comma-tuple]
CCC="aaa", # [trailing-comma-tuple]

BBB = 1, 2
CCC = (1, 2, 3)
DDD = (
1, 2, 3,
)
EEE = (
"aaa",
)
2 changes: 2 additions & 0 deletions pylint/test/functional/trailing_comma_tuple.rc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[testoptions]
min_pyver=3.0
3 changes: 3 additions & 0 deletions pylint/test/functional/trailing_comma_tuple.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
trailing-comma-tuple:3::Disallow trailing comma tuple
trailing-comma-tuple:4::Disallow trailing comma tuple
trailing-comma-tuple:5::Disallow trailing comma tuple

0 comments on commit 6ae2b77

Please sign in to comment.