You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
__iadd__ doesn't work when going through a Dict or List #2046
class A(object):
def __init__(self):
self.a = 0
def __iadd__(self, a):
# type: (int) -> A
self.a += 1
return self
a = A()
a += 1
b = {0: a}
b[0] += 1
c = [a]
c[0] += 1
print(a.a)
Yields the following errors:
rt1.py:15: error: Incompatible types in assignment (expression has type "int", target has type "A")
rt1.py:18: error: No overload variant of "__setitem__" of "list" matches argument types [builtins.int, builtins.int]
def visit_operator_assignment_stmt(self,
s: OperatorAssignmentStmt) -> Type:
"""Type check an operator assignment statement, e.g. x += 1."""
lvalue_type = self.accept(s.lvalue)
method = infer_operator_assignment_method(lvalue_type, s.op)
rvalue_type, method_type = self.expr_checker.check_op(
method, lvalue_type, s.rvalue, s)
if isinstance(s.lvalue, IndexExpr):
self.check_indexed_assignment(s.lvalue, s.rvalue, s.rvalue)
else:
if not is_subtype(rvalue_type, lvalue_type):
self.msg.incompatible_operator_assignment(s.op, s)
I think the issue is that when s.lvalue is an IndexExpr, we forget the possibility that the lvalue actually has an in-place method for this operator and we attempt to check an outright assignment. (I'm not convinced it's quite right even when there isn't an in-place method -- that check_indexed_assignment line goes and type-checks it as if we're assigning the type of the actual RHS, rather than rvalue_type which is the type the operator returns -- but that'd be a separate issue.)
Activity
gnprice commentedon Aug 24, 2016
Thanks for reporting this bug!
On a bit of debugging, here's the relevant logic:
https://github.com/python/mypy/blob/897398eff/mypy/checker.py#L1556
I think the issue is that when
s.lvalueis anIndexExpr, we forget the possibility that the lvalue actually has an in-place method for this operator and we attempt to check an outright assignment. (I'm not convinced it's quite right even when there isn't an in-place method -- thatcheck_indexed_assignmentline goes and type-checks it as if we're assigning the type of the actual RHS, rather thanrvalue_typewhich is the type the operator returns -- but that'd be a separate issue.)Will see if I can work up an easy fix.
Respect in-place operation when operator-assigning through square bra…
Respect in-place operation when operator-assigning through square bra…