summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2020-05-23 20:40:24 +0200
committerStefan Behnel <stefan_ml@behnel.de>2020-05-23 20:40:24 +0200
commite7c7730c22921494bb50eabc0d0bdb0600e2ece9 (patch)
treee3a8166062d7f8e7db709a00bcdda9a0d371e4ad
parentdbc563c43906ce7007739ba1f0b314228255de09 (diff)
downloadcython-e7c7730c22921494bb50eabc0d0bdb0600e2ece9.tar.gz
Implement type inference for stared unpacking targets as list.
-rw-r--r--Cython/Compiler/FlowControl.py7
-rw-r--r--tests/run/type_inference.pyx29
2 files changed, 34 insertions, 2 deletions
diff --git a/Cython/Compiler/FlowControl.py b/Cython/Compiler/FlowControl.py
index 30301f91a..81d013529 100644
--- a/Cython/Compiler/FlowControl.py
+++ b/Cython/Compiler/FlowControl.py
@@ -778,8 +778,11 @@ class ControlFlowAnalysis(CythonTransform):
self.flow.mark_assignment(lhs, rhs, entry)
elif lhs.is_sequence_constructor:
for i, arg in enumerate(lhs.args):
- if not rhs or arg.is_starred:
- item_node = None
+ if arg.is_starred:
+ # "a, *b = x" assigns a list to "b"
+ item_node = TypedExprNode(Builtin.list_type, may_be_none=False, pos=arg.pos)
+ elif rhs is self.object_expr:
+ item_node = rhs
else:
item_node = rhs.inferable_item_node(i)
self.mark_assignment(arg, item_node)
diff --git a/tests/run/type_inference.pyx b/tests/run/type_inference.pyx
index 76a16c3b8..eb9016b00 100644
--- a/tests/run/type_inference.pyx
+++ b/tests/run/type_inference.pyx
@@ -287,6 +287,35 @@ def cascaded_assignment():
e = a + b + c + d
assert typeof(e) == "double"
+
+def unpacking(x):
+ """
+ >>> unpacking(0)
+ """
+ a, b, c, d = x, 1, 2.0, [3]
+ assert typeof(a) == "Python object", typeof(a)
+ assert typeof(b) == "long", typeof(b)
+ assert typeof(c) == "double", typeof(c)
+ assert typeof(d) == "list object", typeof(d)
+
+
+def star_unpacking(*x):
+ """
+ >>> star_unpacking(1, 2)
+ """
+ a, b = x
+ c, *d = x
+ *e, f = x
+ *g, g = x # re-assignment
+ assert typeof(a) == "Python object", typeof(a)
+ assert typeof(b) == "Python object", typeof(b)
+ assert typeof(c) == "Python object", typeof(c)
+ assert typeof(d) == "list object", typeof(d)
+ assert typeof(e) == "list object", typeof(e)
+ assert typeof(f) == "Python object", typeof(f)
+ assert typeof(g) == "Python object", typeof(f)
+
+
def increment():
"""
>>> increment()