Files
ruff/crates/red_knot_python_semantic/resources/mdtest/assignment/augmented.md
Charlie Marsh eddc8d7644 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>
2024-10-30 14:22:34 -04:00

2.4 KiB

Augmented assignment

Basic

x = 3
x -= 1
reveal_type(x)  # revealed: Literal[2]

x = 1.0
x /= 2
reveal_type(x)  # revealed: float

Dunder methods

class C:
    def __isub__(self, other: int) -> str:
        return "Hello, world!"

x = C()
x -= 1
reveal_type(x)  # revealed: str

class C:
    def __iadd__(self, other: str) -> float:
        return 1.0

x = C()
x += "Hello"
reveal_type(x)  # revealed: float

Unsupported types

class C:
    def __isub__(self, other: str) -> int:
        return 42

x = C()
x -= 1

# TODO: should error, once operand type check is implemented
reveal_type(x)  # revealed: int

Method union

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__

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__

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

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

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