Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -494,10 +494,12 @@ def compare_str_bound(a: V, b: V) -> bool:

### Constrained TypeVar comparisons

Constrained TypeVars support comparisons if all constraints support the operation:
Constrained TypeVars support comparisons if all constraints support the operation. Comparisons
between two occurrences of the same constrained TypeVar preserve the correlation that both
occurrences have the same specialization:

```py
from typing import TypeVar
from typing import Literal, TypeVar

W = TypeVar("W", int, str)

Expand All @@ -510,6 +512,12 @@ X = TypeVar("X", int, str)
def compare_constrained_lt(a: X, b: X) -> bool:
# Both int and str support <
return a < b

Y = TypeVar("Y", Literal[1], Literal[2])

def compare_same_constrained_literal(value: Y):
reveal_type(value == value) # revealed: Literal[True]
reveal_type(value != value) # revealed: Literal[False]
```

### TypeVar with `complex` bound
Expand Down
27 changes: 27 additions & 0 deletions crates/ty_python_semantic/resources/mdtest/comparison/unions.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,33 @@ def _(small: Literal[1, 2], large: Literal[2, 3]):
reveal_type(small > large) # revealed: Literal[False]
```

Equality inference still preserves custom return types for every union arm:

```py
class AEq: ...
class ANe: ...
class BEq: ...
class BNe: ...

class A:
def __eq__(self, other: object) -> AEq: # error: [invalid-method-override]
return AEq()

def __ne__(self, other: object) -> ANe: # error: [invalid-method-override]
return ANe()

class B:
def __eq__(self, other: object) -> BEq: # error: [invalid-method-override]
return BEq()

def __ne__(self, other: object) -> BNe: # error: [invalid-method-override]
return BNe()

def _(value: A | B):
reveal_type(value == object()) # revealed: AEq | BEq
reveal_type(value != object()) # revealed: ANe | BNe
```

## Unsupported operations

Make sure we emit a diagnostic if *any* of the possible comparisons is unsupported. For now, we fall
Expand Down
Loading
Loading