Add failing tests for augmented assignments with partial binding (#14002)

## Summary

These cases aren't handled correctly yet -- some of them are waiting on
refactors to `Unbound` before fixing. Part of #12699.

---------

Co-authored-by: Carl Meyer <carl@astral.sh>
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
This commit is contained in:
Charlie Marsh 2024-10-30 14:22:34 -04:00 committed by GitHub
parent b1ce8a3949
commit eddc8d7644
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 106 additions and 1 deletions

View File

@ -25,7 +25,7 @@ reveal_type(x) # revealed: str
class C:
def __iadd__(self, other: str) -> float:
return "Hello, world!"
return 1.0
x = C()
x += "Hello"
@ -45,3 +45,108 @@ x -= 1
# TODO: should error, once operand type check is implemented
reveal_type(x) # revealed: int
```
## Method union
```py
def bool_instance() -> bool:
return True
flag = bool_instance()
class Foo:
if bool_instance():
def __iadd__(self, other: int) -> str:
return "Hello, world!"
else:
def __iadd__(self, other: int) -> int:
return 42
f = Foo()
f += 12
reveal_type(f) # revealed: str | int
```
## Partially bound `__iadd__`
```py
def bool_instance() -> bool:
return True
class Foo:
if bool_instance():
def __iadd__(self, other: str) -> int:
return 42
f = Foo()
f += "Hello, world!"
# TODO should emit a diagnostic warning that `Foo` might not have an `__iadd__` method
reveal_type(f) # revealed: int
```
## Partially bound with `__add__`
```py
def bool_instance() -> bool:
return True
class Foo:
def __add__(self, other: str) -> str:
return "Hello, world!"
if bool_instance():
def __iadd__(self, other: str) -> int:
return 42
f = Foo()
f += "Hello, world!"
# TODO(charlie): This should be `int | str`, since `__iadd__` may be unbound.
reveal_type(f) # revealed: int
```
## Partially bound target union
```py
def bool_instance() -> bool:
return True
class Foo:
def __add__(self, other: int) -> str:
return "Hello, world!"
if bool_instance():
def __iadd__(self, other: int) -> int:
return 42
if bool_instance():
f = Foo()
else:
f = 42.0
f += 12
# TODO(charlie): This should be `str | int | float`
reveal_type(f) # revealed: @Todo
```
## Target union
```py
def bool_instance() -> bool:
return True
flag = bool_instance()
class Foo:
def __iadd__(self, other: int) -> str:
return "Hello, world!"
if flag:
f = Foo()
else:
f = 42.0
f += 12
# TODO(charlie): This should be `str | float`.
reveal_type(f) # revealed: @Todo
```