summaryrefslogtreecommitdiff
path: root/tests/functional/u/unpacking
diff options
context:
space:
mode:
Diffstat (limited to 'tests/functional/u/unpacking')
-rw-r--r--tests/functional/u/unpacking/unpacking.py11
-rw-r--r--tests/functional/u/unpacking/unpacking_generalizations.py29
-rw-r--r--tests/functional/u/unpacking/unpacking_generalizations.txt6
-rw-r--r--tests/functional/u/unpacking/unpacking_non_sequence.py149
-rw-r--r--tests/functional/u/unpacking/unpacking_non_sequence.txt10
-rw-r--r--tests/functional/u/unpacking/unpacking_non_sequence_py37.py15
-rw-r--r--tests/functional/u/unpacking/unpacking_non_sequence_py37.rc2
7 files changed, 222 insertions, 0 deletions
diff --git a/tests/functional/u/unpacking/unpacking.py b/tests/functional/u/unpacking/unpacking.py
new file mode 100644
index 000000000..59d9abbe4
--- /dev/null
+++ b/tests/functional/u/unpacking/unpacking.py
@@ -0,0 +1,11 @@
+""" Code for checking the display of the module
+for unbalanced-tuple-unpacking and unpacking-non-sequence
+"""
+
+def unpack():
+ """ Return something"""
+ return (1, 2, 3)
+
+def nonseq():
+ """ Return non sequence """
+ return 1
diff --git a/tests/functional/u/unpacking/unpacking_generalizations.py b/tests/functional/u/unpacking/unpacking_generalizations.py
new file mode 100644
index 000000000..1c5fb16b8
--- /dev/null
+++ b/tests/functional/u/unpacking/unpacking_generalizations.py
@@ -0,0 +1,29 @@
+"""Various tests for unpacking generalizations added in Python 3.5"""
+
+# pylint: disable=missing-docstring, invalid-name
+
+def func_variadic_args(*args):
+ return args
+
+
+def func_variadic_positional_args(a, b, *args):
+ return a, b, args
+
+def func_positional_args(a, b, c, d):
+ return a, b, c, d
+
+
+func_variadic_args(*(2, 3), *(3, 4), *(4, 5))
+func_variadic_args(1, 2, *(2, 3), 2, 3, *(4, 5))
+func_variadic_positional_args(1, 2, *(4, 5), *(5, 6))
+func_variadic_positional_args(*(2, 3), *(4, 5), *(5, 6))
+func_variadic_positional_args(*(2, 3))
+func_variadic_positional_args(*(2, 3, 4))
+func_variadic_positional_args(1, 2, 3, *(3, 4))
+
+func_positional_args(*(2, 3, 4), *(2, 3)) # [too-many-function-args]
+func_positional_args(*(1, 2), 3) # [no-value-for-parameter]
+func_positional_args(1, *(2, ), 3, *(4, 5)) # [too-many-function-args]
+func_positional_args(1, 2, c=24, d=32, **{'d': 32}) # [repeated-keyword]
+# +1: [repeated-keyword,repeated-keyword]
+func_positional_args(1, 2, c=24, **{'c': 34, 'd': 33}, **{'d': 24})
diff --git a/tests/functional/u/unpacking/unpacking_generalizations.txt b/tests/functional/u/unpacking/unpacking_generalizations.txt
new file mode 100644
index 000000000..caecb193e
--- /dev/null
+++ b/tests/functional/u/unpacking/unpacking_generalizations.txt
@@ -0,0 +1,6 @@
+too-many-function-args:24:0:24:41::Too many positional arguments for function call:UNDEFINED
+no-value-for-parameter:25:0:25:32::No value for argument 'd' in function call:UNDEFINED
+too-many-function-args:26:0:26:43::Too many positional arguments for function call:UNDEFINED
+repeated-keyword:27:0:27:51::Got multiple values for keyword argument 'd' in function call:UNDEFINED
+repeated-keyword:29:0:29:67::Got multiple values for keyword argument 'c' in function call:UNDEFINED
+repeated-keyword:29:0:29:67::Got multiple values for keyword argument 'd' in function call:UNDEFINED
diff --git a/tests/functional/u/unpacking/unpacking_non_sequence.py b/tests/functional/u/unpacking/unpacking_non_sequence.py
new file mode 100644
index 000000000..0299af762
--- /dev/null
+++ b/tests/functional/u/unpacking/unpacking_non_sequence.py
@@ -0,0 +1,149 @@
+"""Check unpacking non-sequences in assignments. """
+
+# pylint: disable=too-few-public-methods, invalid-name, attribute-defined-outside-init, unused-variable
+# pylint: disable=using-constant-test, no-init, missing-docstring, wrong-import-order,wrong-import-position,no-else-return, useless-object-inheritance
+from os import rename as nonseq_func
+from functional.u.unpacking.unpacking import nonseq
+from typing import NamedTuple
+
+__revision__ = 0
+
+# Working
+
+class Seq(object):
+ """ sequence """
+ def __init__(self):
+ self.items = range(2)
+
+ def __getitem__(self, item):
+ return self.items[item]
+
+ def __len__(self):
+ return len(self.items)
+
+class Iter(object):
+ """ Iterator """
+ def __iter__(self):
+ for number in range(2):
+ yield number
+
+def good_unpacking():
+ """ returns should be unpackable """
+ if True:
+ return [1, 2]
+ else:
+ return (3, 4)
+
+def good_unpacking2():
+ """ returns should be unpackable """
+ return good_unpacking()
+
+class MetaIter(type):
+ "metaclass that makes classes that use it iterables"
+ def __iter__(cls):
+ return iter((1, 2))
+
+class IterClass(metaclass=MetaIter):
+ "class that is iterable (and unpackable)"
+
+class AbstrClass(object):
+ "abstract class"
+ pair = None
+
+ def setup_pair(self):
+ "abstract method"
+ raise NotImplementedError
+
+ def __init__(self):
+ "error should not be emitted because setup_pair is abstract"
+ self.setup_pair()
+ x, y = self.pair
+
+a, b = [1, 2]
+a, b = (1, 2)
+a, b = set([1, 2])
+a, b = {1: 2, 2: 3}
+a, b = "xy"
+a, b = Seq()
+a, b = Iter()
+a, b = (number for number in range(2))
+a, b = good_unpacking()
+a, b = good_unpacking2()
+a, b = IterClass
+
+# Not working
+class NonSeq(object):
+ """ does nothing """
+
+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 = nonseq_func # [unpacking-non-sequence]
+
+class ClassUnpacking(object):
+ """ Check unpacking as instance attributes. """
+
+ def test(self):
+ """ test unpacking in instance attributes. """
+
+ self.a, self.b = 1, 2
+ self.a, self.b = {1: 2, 2: 3}
+ self.a, self.b = "xy"
+ self.a, c = "xy"
+ c, self.a = good_unpacking()
+ self.a, self.b = Iter()
+
+ self.a, self.b = NonSeq() # [unpacking-non-sequence]
+ self.a, self.b = ValueError # [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 overridden in this class
+ (self.aaa, self.bbb, self.ccc) = self.test(None)
+
+ @staticmethod
+ def test(data):
+ 'overridden implementation'
+ return (1, 2, 3)
+
+
+import platform
+
+
+def flow_control_false_positive():
+ # This used to trigger an unpacking-non-sequence error. The problem was
+ # partially related to the fact that pylint does not understand flow control,
+ # but now it does not emit anymore, for this example, due to skipping it when
+ # determining an inference of multiple potential values.
+ # In any case, it is good having this repro as a test.
+ system, node, release, version, machine, processor = platform.uname()
+ # The previous line raises W0633
+ return system, node, release, version, machine, processor
+
+
+def flow_control_unpacking(var=None):
+ if var is not None:
+ var0, var1 = var
+ return var0, var1
+ return None
+
+
+class MyClass(NamedTuple):
+ x: float
+ y: float
+
+ def sum(self):
+ x, y = self
+ return x + y
diff --git a/tests/functional/u/unpacking/unpacking_non_sequence.txt b/tests/functional/u/unpacking/unpacking_non_sequence.txt
new file mode 100644
index 000000000..c3c65050c
--- /dev/null
+++ b/tests/functional/u/unpacking/unpacking_non_sequence.txt
@@ -0,0 +1,10 @@
+unpacking-non-sequence:78:0:78:15::Attempting to unpack a non-sequence defined at line 75:UNDEFINED
+unpacking-non-sequence:79:0:79:17::Attempting to unpack a non-sequence:UNDEFINED
+unpacking-non-sequence:80:0:80:11::Attempting to unpack a non-sequence None:UNDEFINED
+unpacking-non-sequence:81:0:81:8::Attempting to unpack a non-sequence 1:UNDEFINED
+unpacking-non-sequence:82:0:82:13::Attempting to unpack a non-sequence defined at line 9 of functional.u.unpacking.unpacking:UNDEFINED
+unpacking-non-sequence:83:0:83:15::Attempting to unpack a non-sequence defined at line 11 of functional.u.unpacking.unpacking:UNDEFINED
+unpacking-non-sequence:84:0:84:18::Attempting to unpack a non-sequence:UNDEFINED
+unpacking-non-sequence:99:8:99:33:ClassUnpacking.test:Attempting to unpack a non-sequence defined at line 75:UNDEFINED
+unpacking-non-sequence:100:8:100:35:ClassUnpacking.test:Attempting to unpack a non-sequence:UNDEFINED
+unpacking-non-sequence:101:8:101:31:ClassUnpacking.test:Attempting to unpack a non-sequence:UNDEFINED
diff --git a/tests/functional/u/unpacking/unpacking_non_sequence_py37.py b/tests/functional/u/unpacking/unpacking_non_sequence_py37.py
new file mode 100644
index 000000000..dd8af1136
--- /dev/null
+++ b/tests/functional/u/unpacking/unpacking_non_sequence_py37.py
@@ -0,0 +1,15 @@
+# pylint: disable=missing-docstring
+
+# https://github.com/PyCQA/pylint/issues/4895
+from __future__ import annotations
+
+from collections.abc import Callable
+from dataclasses import dataclass
+
+
+@dataclass
+class Metric:
+ function: Callable[..., tuple[int, int]]
+
+ def update(self):
+ _, _ = self.function()
diff --git a/tests/functional/u/unpacking/unpacking_non_sequence_py37.rc b/tests/functional/u/unpacking/unpacking_non_sequence_py37.rc
new file mode 100644
index 000000000..a17bb22da
--- /dev/null
+++ b/tests/functional/u/unpacking/unpacking_non_sequence_py37.rc
@@ -0,0 +1,2 @@
+[testoptions]
+min_pyver=3.7