diff options
author | Dmitry Pribysh <dmand@yandex.ru> | 2015-11-09 18:16:14 +0300 |
---|---|---|
committer | Dmitry Pribysh <dmand@yandex.ru> | 2015-11-09 18:16:14 +0300 |
commit | 928d8b8c9ed8f1d6d2e7cfe5d252c6cde47cff7e (patch) | |
tree | cc83e1e606edf52173a1c7caa83500633cc1a33c | |
parent | 55c4e267c454e54958aa1de605f3b55f1b6effe7 (diff) | |
download | pylint-928d8b8c9ed8f1d6d2e7cfe5d252c6cde47cff7e.tar.gz |
Use safe inference in unpacking-non-sequence checker
Unfortunately, this fix means that we won't be able to emit an error for
cases like this one:
```
def foo():
if True:
return [1, 2]
return [3, 4, 5]
a, b = foo()
```
Well, not unless we get flow-sensitive inference. But we still need this fix to
reduce the number of false-positive errors.
Fixes issue #695.
-rw-r--r-- | pylint/checkers/variables.py | 4 | ||||
-rw-r--r-- | pylint/test/functional/unbalanced_tuple_unpacking.py | 8 | ||||
-rw-r--r-- | pylint/test/functional/unbalanced_tuple_unpacking.txt | 4 | ||||
-rw-r--r-- | pylint/test/functional/unpacking_non_sequence.py | 26 | ||||
-rw-r--r-- | pylint/test/functional/unpacking_non_sequence.txt | 22 |
5 files changed, 37 insertions, 27 deletions
diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py index 6f0f5a3..d813e1f 100644 --- a/pylint/checkers/variables.py +++ b/pylint/checkers/variables.py @@ -21,6 +21,7 @@ import re from copy import copy import astroid +from astroid import helpers from astroid import modutils from pylint.interfaces import IAstroidChecker, INFERENCE, INFERENCE_FAILURE, HIGH @@ -1033,7 +1034,8 @@ builtins. Remember that you should avoid to define new builtins when possible.' targets = node.targets[0].itered() try: - for infered in node.value.infer(): + infered = helpers.safe_infer(node.value) + if infered is not None: self._check_unpacking(infered, node, targets) except astroid.InferenceError: return diff --git a/pylint/test/functional/unbalanced_tuple_unpacking.py b/pylint/test/functional/unbalanced_tuple_unpacking.py index bd21a05..98f5640 100644 --- a/pylint/test/functional/unbalanced_tuple_unpacking.py +++ b/pylint/test/functional/unbalanced_tuple_unpacking.py @@ -46,8 +46,8 @@ def temp(): return [2, 3, 4] def do_stuff7(): - """ This is not right """ - first, second = temp() # [unbalanced-tuple-unpacking] + """ This is not right, but we're not sure """ + first, second = temp() return first + second def temp2(): @@ -74,7 +74,9 @@ class UnbalancedUnpacking(object): # pylint: disable=attribute-defined-outside-init, invalid-name, too-few-public-methods def test(self): """ unpacking in instance attributes """ - self.a, self.b = temp() # [unbalanced-tuple-unpacking] + # we're not sure if temp() returns two or three values + # so we shouldn't emit an error + self.a, self.b = temp() self.a, self.b = temp2() self.a, self.b = unpack() # [unbalanced-tuple-unpacking] diff --git a/pylint/test/functional/unbalanced_tuple_unpacking.txt b/pylint/test/functional/unbalanced_tuple_unpacking.txt index 23038fb..e904209 100644 --- a/pylint/test/functional/unbalanced_tuple_unpacking.txt +++ b/pylint/test/functional/unbalanced_tuple_unpacking.txt @@ -2,7 +2,5 @@ unbalanced-tuple-unpacking:9:do_stuff:"Possible unbalanced tuple unpacking with unbalanced-tuple-unpacking:14:do_stuff1:"Possible unbalanced tuple unpacking with sequence [1, 2, 3]: left side has 2 label(s), right side has 3 value(s)" unbalanced-tuple-unpacking:19:do_stuff2:"Possible unbalanced tuple unpacking with sequence (1, 2, 3): left side has 2 label(s), right side has 3 value(s)" unbalanced-tuple-unpacking:24:do_stuff3:"Possible unbalanced tuple unpacking with sequence (1, 2, 3): left side has 2 label(s), right side has 3 value(s)" -unbalanced-tuple-unpacking:50:do_stuff7:"Possible unbalanced tuple unpacking with sequence defined at line 46: left side has 2 label(s), right side has 3 value(s)" unbalanced-tuple-unpacking:69:do_stuff9:"Possible unbalanced tuple unpacking with sequence defined at line 7 of functional.unpacking: left side has 2 label(s), right side has 3 value(s)" -unbalanced-tuple-unpacking:77:UnbalancedUnpacking.test:"Possible unbalanced tuple unpacking with sequence defined at line 46: left side has 2 label(s), right side has 3 value(s)" -unbalanced-tuple-unpacking:79:UnbalancedUnpacking.test:"Possible unbalanced tuple unpacking with sequence defined at line 7 of functional.unpacking: left side has 2 label(s), right side has 3 value(s)"
\ No newline at end of file +unbalanced-tuple-unpacking:81:UnbalancedUnpacking.test:"Possible unbalanced tuple unpacking with sequence defined at line 7 of functional.unpacking: left side has 2 label(s), right side has 3 value(s)" diff --git a/pylint/test/functional/unpacking_non_sequence.py b/pylint/test/functional/unpacking_non_sequence.py index f449d5b..1e5de23 100644 --- a/pylint/test/functional/unpacking_non_sequence.py +++ b/pylint/test/functional/unpacking_non_sequence.py @@ -75,19 +75,12 @@ a, b = IterClass class NonSeq(object): """ does nothing """ -def bad_unpacking(): - """ one return isn't unpackable """ - if True: - return None - return [1, 2] - a, b = NonSeq() # [unpacking-non-sequence] a, b = ValueError # [unpacking-non-sequence] a, b = None # [unpacking-non-sequence] a, b = 1 # [unpacking-non-sequence] a, b = nonseq # [unpacking-non-sequence] a, b = nonseq() # [unpacking-non-sequence] -a, b = bad_unpacking() # [unpacking-non-sequence] a, b = nonseq_func # [unpacking-non-sequence] class ClassUnpacking(object): @@ -105,5 +98,22 @@ class ClassUnpacking(object): self.a, self.b = NonSeq() # [unpacking-non-sequence] self.a, self.b = ValueError # [unpacking-non-sequence] - self.a, self.b = bad_unpacking() # [unpacking-non-sequence] self.a, c = nonseq_func # [unpacking-non-sequence] + +class TestBase(object): + 'base class with `test` method implementation' + @staticmethod + def test(data): + 'default implementation' + return data + +class Test(TestBase): + 'child class that overrides `test` method' + def __init__(self): + # no error should be emitted here as `test` is overriden in this class + (self.aaa, self.bbb, self.ccc) = self.test(None) + + @staticmethod + def test(data): + 'overridden implementation' + return (1, 2, 3) diff --git a/pylint/test/functional/unpacking_non_sequence.txt b/pylint/test/functional/unpacking_non_sequence.txt index 8d13c44..0a21fab 100644 --- a/pylint/test/functional/unpacking_non_sequence.txt +++ b/pylint/test/functional/unpacking_non_sequence.txt @@ -1,12 +1,10 @@ -unpacking-non-sequence:84::Attempting to unpack a non-sequence defined at line 75 -unpacking-non-sequence:85::Attempting to unpack a non-sequence -unpacking-non-sequence:86::Attempting to unpack a non-sequence None -unpacking-non-sequence:87::Attempting to unpack a non-sequence 1 -unpacking-non-sequence:88::Attempting to unpack a non-sequence defined at line 9 of functional.unpacking -unpacking-non-sequence:89::Attempting to unpack a non-sequence defined at line 11 of functional.unpacking -unpacking-non-sequence:90::Attempting to unpack a non-sequence defined at line 81 -unpacking-non-sequence:91::Attempting to unpack a non-sequence -unpacking-non-sequence:106:ClassUnpacking.test:Attempting to unpack a non-sequence defined at line 75 -unpacking-non-sequence:107:ClassUnpacking.test:Attempting to unpack a non-sequence -unpacking-non-sequence:108:ClassUnpacking.test:Attempting to unpack a non-sequence defined at line 81 -unpacking-non-sequence:109:ClassUnpacking.test:Attempting to unpack a non-sequence +unpacking-non-sequence:78::Attempting to unpack a non-sequence defined at line 75 +unpacking-non-sequence:79::Attempting to unpack a non-sequence +unpacking-non-sequence:80::Attempting to unpack a non-sequence None +unpacking-non-sequence:81::Attempting to unpack a non-sequence 1 +unpacking-non-sequence:82::Attempting to unpack a non-sequence defined at line 9 of functional.unpacking +unpacking-non-sequence:83::Attempting to unpack a non-sequence defined at line 11 of functional.unpacking +unpacking-non-sequence:84::Attempting to unpack a non-sequence +unpacking-non-sequence:99:ClassUnpacking.test:Attempting to unpack a non-sequence defined at line 75 +unpacking-non-sequence:100:ClassUnpacking.test:Attempting to unpack a non-sequence +unpacking-non-sequence:101:ClassUnpacking.test:Attempting to unpack a non-sequence |