diff options
author | Stefan Behnel <stefan_ml@behnel.de> | 2020-05-23 20:40:24 +0200 |
---|---|---|
committer | Stefan Behnel <stefan_ml@behnel.de> | 2020-05-23 20:40:24 +0200 |
commit | e7c7730c22921494bb50eabc0d0bdb0600e2ece9 (patch) | |
tree | e3a8166062d7f8e7db709a00bcdda9a0d371e4ad | |
parent | dbc563c43906ce7007739ba1f0b314228255de09 (diff) | |
download | cython-e7c7730c22921494bb50eabc0d0bdb0600e2ece9.tar.gz |
Implement type inference for stared unpacking targets as list.
-rw-r--r-- | Cython/Compiler/FlowControl.py | 7 | ||||
-rw-r--r-- | tests/run/type_inference.pyx | 29 |
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() |