summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Pribysh <dmand@yandex.ru>2015-11-09 18:16:14 +0300
committerDmitry Pribysh <dmand@yandex.ru>2015-11-09 18:16:14 +0300
commit928d8b8c9ed8f1d6d2e7cfe5d252c6cde47cff7e (patch)
treecc83e1e606edf52173a1c7caa83500633cc1a33c
parent55c4e267c454e54958aa1de605f3b55f1b6effe7 (diff)
downloadpylint-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.py4
-rw-r--r--pylint/test/functional/unbalanced_tuple_unpacking.py8
-rw-r--r--pylint/test/functional/unbalanced_tuple_unpacking.txt4
-rw-r--r--pylint/test/functional/unpacking_non_sequence.py26
-rw-r--r--pylint/test/functional/unpacking_non_sequence.txt22
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