Skip to content

Commit 52b425b

Browse files
authored
[mypyc] Implement the walrus operator (python#9624)
My assessment that this would not be too hard was accurate. Fixes mypyc/mypyc#765.
1 parent ecec8bb commit 52b425b

File tree

4 files changed

+62
-3
lines changed

4 files changed

+62
-3
lines changed

mypyc/irbuild/expression.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
ConditionalExpr, ComparisonExpr, IntExpr, FloatExpr, ComplexExpr, StrExpr,
1212
BytesExpr, EllipsisExpr, ListExpr, TupleExpr, DictExpr, SetExpr, ListComprehension,
1313
SetComprehension, DictionaryComprehension, SliceExpr, GeneratorExpr, CastExpr, StarExpr,
14+
AssignmentExpr,
1415
Var, RefExpr, MypyFile, TypeInfo, TypeApplication, LDEF, ARG_POS
1516
)
1617
from mypy.types import TupleType, get_proper_type, Instance
@@ -682,3 +683,10 @@ def transform_generator_expr(builder: IRBuilder, o: GeneratorExpr) -> Value:
682683
return builder.call_c(
683684
iter_op, [translate_list_comprehension(builder, o)], o.line
684685
)
686+
687+
688+
def transform_assignment_expr(builder: IRBuilder, o: AssignmentExpr) -> Value:
689+
value = builder.accept(o.value)
690+
target = builder.get_assignment_target(o.target)
691+
builder.assign(target, value, o.line)
692+
return value

mypyc/irbuild/visitor.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
transform_dictionary_comprehension,
7777
transform_slice_expr,
7878
transform_generator_expr,
79+
transform_assignment_expr,
7980
)
8081

8182

@@ -264,10 +265,8 @@ def visit_yield_from_expr(self, o: YieldFromExpr) -> Value:
264265
def visit_await_expr(self, o: AwaitExpr) -> Value:
265266
return transform_await_expr(self.builder, o)
266267

267-
# Unimplemented constructs
268-
269268
def visit_assignment_expr(self, o: AssignmentExpr) -> Value:
270-
self.bail("I Am The Walrus (unimplemented)", o.line)
269+
return transform_assignment_expr(self.builder, o)
271270

272271
# Unimplemented constructs that shouldn't come up because they are py2 only
273272

mypyc/test-data/run-python38.test

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
[case testWalrus1]
2+
from typing import Optional
3+
4+
def foo(x: int) -> Optional[int]:
5+
if x < 0:
6+
return None
7+
return x
8+
9+
def test(x: int) -> str:
10+
if (n := foo(x)) is not None:
11+
return str(x)
12+
else:
13+
return "<fail>"
14+
15+
[file driver.py]
16+
from native import test
17+
18+
assert test(10) == "10"
19+
assert test(-1) == "<fail>"
20+
21+
22+
[case testWalrus2]
23+
from typing import Optional, Tuple, List
24+
25+
class Node:
26+
def __init__(self, val: int, next: Optional['Node']) -> None:
27+
self.val = val
28+
self.next = next
29+
30+
def pairs(nobe: Optional[Node]) -> List[Tuple[int, int]]:
31+
if nobe is None:
32+
return []
33+
l = []
34+
while next := nobe.next:
35+
l.append((nobe.val, next.val))
36+
nobe = next
37+
return l
38+
39+
def make(l: List[int]) -> Optional[Node]:
40+
cur: Optional[Node] = None
41+
for x in reversed(l):
42+
cur = Node(x, cur)
43+
return cur
44+
45+
[file driver.py]
46+
from native import Node, make, pairs
47+
48+
assert pairs(make([1,2,3])) == [(1,2), (2,3)]
49+
assert pairs(make([1])) == []
50+
assert pairs(make([])) == []

mypyc/test/test_run.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050
'run-bench.test',
5151
'run-mypy-sim.test',
5252
]
53+
if sys.version_info >= (3, 8):
54+
files.append('run-python38.test')
5355

5456
setup_format = """\
5557
from setuptools import setup

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy