summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcpopa <devnull@localhost>2014-07-08 15:24:45 +0300
committercpopa <devnull@localhost>2014-07-08 15:24:45 +0300
commitfac1865c061d62ddd5a8473a6f6d3fed9134d047 (patch)
tree76b90ee28571e0abb4e166b457613800095154a3
parent59accca5013b2fcb4c03eecbd7d5e4a7f3892c1c (diff)
downloadpylint-fac1865c061d62ddd5a8473a6f6d3fed9134d047.tar.gz
Fix a false positive with unbalanced iterable unpacking, when encountering starred nodes. Closes issue #273.
-rw-r--r--ChangeLog3
-rw-r--r--checkers/variables.py12
-rw-r--r--test/input/func_noerror_unbalanced_tuple_unpacking_py30.py11
3 files changed, 22 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index fdc27e1..f56cfe2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -20,6 +20,9 @@ ChangeLog for Pylint
* Emit 'not-callable' when calling properties. Closes issue #268.
+ * Fix a false positive with unbalanced iterable unpacking,
+ when encountering starred nodes. Closes issue #273.
+
2014-04-30 -- 1.2.1
* Restore the ability to specify the init-hook option via the
configuration file, which was accidentally broken in 1.2.0.
diff --git a/checkers/variables.py b/checkers/variables.py
index dc8d111..b84ad4f 100644
--- a/checkers/variables.py
+++ b/checkers/variables.py
@@ -147,7 +147,7 @@ MSGS = {
'a sequence is used in an unpack assignment'),
'W0640': ('Cell variable %s defined in loop',
- 'cell-var-from-loop',
+ 'cell-var-from-loop',
'A variable used in a closure is defined in a loop. '
'This will result in all closures using the same value for '
'the closed-over variable.'),
@@ -447,7 +447,7 @@ builtins. Remember that you should avoid to define new builtins when possible.'
else:
if maybe_for.parent_of(node_scope) and not isinstance(node_scope.statement(), astroid.Return):
self.add_message('cell-var-from-loop', node=node, args=node.name)
-
+
def _loopvar_name(self, node, name):
# filter variables according to node's scope
# XXX used to filter parents but don't remember why, and removing this
@@ -649,6 +649,10 @@ builtins. Remember that you should avoid to define new builtins when possible.'
# attempt to check unpacking is properly balanced
values = infered.itered()
if len(targets) != len(values):
+ # Check if we have starred nodes.
+ if any(isinstance(target, astroid.Starred)
+ for target in targets):
+ return
self.add_message('unbalanced-tuple-unpacking', node=node,
args=(_get_unpacking_extra_info(node, infered),
len(targets),
@@ -727,8 +731,8 @@ class VariablesChecker3k(VariablesChecker):
if isinstance(klass._metaclass, astroid.Name):
module_locals.pop(klass._metaclass.name, None)
- if metaclass:
- # if it uses a `metaclass=module.Class`
+ if metaclass:
+ # if it uses a `metaclass=module.Class`
module_locals.pop(metaclass.root().name, None)
super(VariablesChecker3k, self).leave_module(node)
diff --git a/test/input/func_noerror_unbalanced_tuple_unpacking_py30.py b/test/input/func_noerror_unbalanced_tuple_unpacking_py30.py
new file mode 100644
index 0000000..68f5fb7
--- /dev/null
+++ b/test/input/func_noerror_unbalanced_tuple_unpacking_py30.py
@@ -0,0 +1,11 @@
+""" Test that using starred nodes in unpacking
+does not trigger a false positive on Python 3.
+"""
+
+__revision__ = 1
+
+def test():
+ """ Test that starred expressions don't give false positives. """
+ first, second, *last = (1, 2, 3, 4)
+ *last, = (1, 2)
+ return (first, second, last)