diff options
author | cpopa <devnull@localhost> | 2014-07-08 15:24:45 +0300 |
---|---|---|
committer | cpopa <devnull@localhost> | 2014-07-08 15:24:45 +0300 |
commit | fac1865c061d62ddd5a8473a6f6d3fed9134d047 (patch) | |
tree | 76b90ee28571e0abb4e166b457613800095154a3 | |
parent | 59accca5013b2fcb4c03eecbd7d5e4a7f3892c1c (diff) | |
download | pylint-fac1865c061d62ddd5a8473a6f6d3fed9134d047.tar.gz |
Fix a false positive with unbalanced iterable unpacking, when encountering starred nodes. Closes issue #273.
-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | checkers/variables.py | 12 | ||||
-rw-r--r-- | test/input/func_noerror_unbalanced_tuple_unpacking_py30.py | 11 |
3 files changed, 22 insertions, 4 deletions
@@ -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) |