Skip to content

Commit 287f415

Browse files
committed
Add comments and more tests
1 parent 24c8af6 commit 287f415

File tree

4 files changed

+97
-1
lines changed

4 files changed

+97
-1
lines changed

mypy/checker.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1940,11 +1940,13 @@ def visit_operator_assignment_stmt(self,
19401940
lvalue_type = self.expr_checker.accept(s.lvalue)
19411941
inplace, method = infer_operator_assignment_method(lvalue_type, s.op)
19421942
if inplace:
1943+
# There is __ifoo__, treat as x = x.__ifoo__(y)
19431944
rvalue_type, method_type = self.expr_checker.check_op(
19441945
method, lvalue_type, s.rvalue, s)
19451946
if not is_subtype(rvalue_type, lvalue_type):
19461947
self.msg.incompatible_operator_assignment(s.op, s)
19471948
else:
1949+
# There is no __ifoo__, treat as x = x <foo> y
19481950
expr = OpExpr(s.op, s.lvalue, s.rvalue)
19491951
expr.set_line(s)
19501952
self.check_assignment(lvalue=s.lvalue, rvalue=expr,

test-data/unit/check-statements.test

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1524,5 +1524,36 @@ weight0 *= 'a' # E: Incompatible types in assignment (expression has type "str"
15241524
weight0 *= 0.5
15251525
reveal_type(weight0) # E: Revealed type is 'builtins.float'
15261526
weight0 *= object() # E: Unsupported operand types for * ("float" and "object")
1527+
reveal_type(weight0) # E: Revealed type is 'builtins.float'
15271528

15281529
[builtins fixtures/float.pyi]
1530+
1531+
[case testAugmentedAssignmentIntFloatMember]
1532+
class A:
1533+
def __init__(self) -> None:
1534+
self.weight0 = 65.5
1535+
reveal_type(self.weight0) # E: Revealed type is 'builtins.float'
1536+
self.weight0 = 65
1537+
reveal_type(self.weight0) # E: Revealed type is 'builtins.int'
1538+
self.weight0 *= 'a' # E: Incompatible types in assignment (expression has type "str", variable has type "float")
1539+
self.weight0 *= 0.5
1540+
reveal_type(self.weight0) # E: Revealed type is 'builtins.float'
1541+
self.weight0 *= object() # E: Unsupported operand types for * ("float" and "object")
1542+
reveal_type(self.weight0) # E: Revealed type is 'builtins.float'
1543+
1544+
[builtins fixtures/float.pyi]
1545+
1546+
[case testAugmentedAssignmentIntFloatDict]
1547+
from typing import Dict
1548+
d = {'weight0': 65.5}
1549+
reveal_type(d['weight0']) # E: Revealed type is 'builtins.float*'
1550+
d['weight0'] = 65
1551+
reveal_type(d['weight0']) # E: Revealed type is 'builtins.float*'
1552+
d['weight0'] *= 'a' # E: Unsupported operand types for * ("float" and "str") # E: Incompatible types in assignment (expression has type "str", target has type "float")
1553+
d['weight0'] *= 0.5
1554+
reveal_type(d['weight0']) # E: Revealed type is 'builtins.float*'
1555+
d['weight0'] *= object() # E: Unsupported operand types for * ("float" and "object")
1556+
reveal_type(d['weight0']) # E: Revealed type is 'builtins.float*'
1557+
1558+
[builtins fixtures/floatdict.pyi]
1559+

test-data/unit/fixtures/floatdict.pyi

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
from typing import TypeVar, Generic, Iterable, Iterator, Mapping, Tuple, overload, Optional, Union
2+
3+
T = TypeVar('T')
4+
KT = TypeVar('KT')
5+
VT = TypeVar('VT')
6+
7+
Any = 0
8+
9+
class object:
10+
def __init__(self) -> None: pass
11+
12+
class type:
13+
def __init__(self, x: Any) -> None: pass
14+
15+
class str:
16+
def __add__(self, other: 'str') -> 'str': pass
17+
def __rmul__(self, n: int) -> str: ...
18+
19+
class bytes: pass
20+
21+
class tuple: pass
22+
class function: pass
23+
24+
class ellipsis: pass
25+
26+
class list(Iterable[T], Generic[T]):
27+
@overload
28+
def __init__(self) -> None: pass
29+
@overload
30+
def __init__(self, x: Iterable[T]) -> None: pass
31+
def __iter__(self) -> Iterator[T]: pass
32+
def __add__(self, x: list[T]) -> list[T]: pass
33+
def __mul__(self, x: int) -> list[T]: pass
34+
def __getitem__(self, x: int) -> T: pass
35+
def append(self, x: T) -> None: pass
36+
def extend(self, x: Iterable[T]) -> None: pass
37+
38+
class dict(Iterable[KT], Mapping[KT, VT], Generic[KT, VT]):
39+
@overload
40+
def __init__(self, **kwargs: VT) -> None: pass
41+
@overload
42+
def __init__(self, arg: Iterable[Tuple[KT, VT]], **kwargs: VT) -> None: pass
43+
def __setitem__(self, k: KT, v: VT) -> None: pass
44+
def __getitem__(self, k: KT) -> VT: pass
45+
def __iter__(self) -> Iterator[KT]: pass
46+
def update(self, a: Mapping[KT, VT]) -> None: pass
47+
@overload
48+
def get(self, k: KT) -> Optional[VT]: pass
49+
@overload
50+
def get(self, k: KT, default: Union[KT, T]) -> Union[VT, T]: pass
51+
52+
53+
class int:
54+
def __float__(self) -> float: ...
55+
def __int__(self) -> int: ...
56+
def __mul__(self, x: int) -> int: ...
57+
def __rmul__(self, x: int) -> int: ...
58+
59+
class float:
60+
def __float__(self) -> float: ...
61+
def __int__(self) -> int: ...
62+
def __mul__(self, x: float) -> float: ...
63+
def __rmul__(self, x: float) -> float: ...

0 commit comments

Comments
 (0)