Skip to content

Commit 985adb3

Browse files
robertmorellimeta-codesync[bot]
authored andcommitted
Type check augmented assignments to primitives (facebookincubator#148)
Summary: fix for facebookincubator#147 reject mixing incompatible types in augmented assignments in order to bring type checking in line with binops Pull Request resolved: facebookincubator#148 Reviewed By: alexmalyshev Differential Revision: D116791481 Pulled By: yoney fbshipit-source-id: 2356f8d50089416e51d00f9073676256567b6569
1 parent 8390c68 commit 985adb3

2 files changed

Lines changed: 37 additions & 1 deletion

File tree

cinderx/PythonLib/cinderx/compiler/static/type_binder.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -833,7 +833,12 @@ def visitAnnAssign(self, node: AnnAssign) -> None:
833833
def visitAugAssign(self, node: AugAssign) -> None:
834834
self.visit(node.target)
835835
target_type = self.get_type(node.target).inexact()
836-
self.visit(node.value, target_type)
836+
if isinstance(target_type, CInstance):
837+
self.visitExpectedType(
838+
node.value, target_type, target_type.binop_error("{1}", "{0}", node.op)
839+
)
840+
else:
841+
self.visit(node.value, target_type)
837842
self.set_type(node, target_type)
838843

839844
@contextmanager

cinderx/PythonLib/test_cinderx/test_compiler/test_static/test_augassign.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,37 @@ def a(i: int) -> int:
4545
self.assertInBytecode(a, "PRIMITIVE_BINARY_OP", 0)
4646
self.assertEqual(a(3), 5)
4747

48+
def test_primitive_int_dynamic_rhs(self) -> None:
49+
codestr = """
50+
from __static__ import int64
51+
52+
class C:
53+
def __init__(self) -> None:
54+
self.total: int64 = 0
55+
56+
def add_values(self, values: dict[str, int]) -> None:
57+
for _, value in values.items():
58+
self.total += value
59+
"""
60+
self.type_error(codestr, r"cannot add int64 and dynamic", at="value")
61+
62+
def test_primitive_int_dynamic_rhs_explicit_cast(self) -> None:
63+
codestr = """
64+
from __static__ import box, int64
65+
66+
class C:
67+
def __init__(self) -> None:
68+
self.total: int64 = 0
69+
70+
def add_values(self, values: dict[str, int]) -> int:
71+
for _, value in values.items():
72+
self.total += int64(value)
73+
return box(self.total)
74+
"""
75+
with self.in_module(codestr) as mod:
76+
instance = mod.C()
77+
self.assertEqual(instance.add_values({"a": 2, "b": 3}), 5)
78+
4879
def test_inexact(self) -> None:
4980
codestr = """
5081
def something():

0 commit comments

Comments
 (0)