[ty] Improve diagnostics for unsupported binary operations and unsupported augmented assignments (#21947)

## Summary

This PR takes the improvements we made to unsupported-comparison
diagnostics in https://github.com/astral-sh/ruff/pull/21737, and extends
them to other `unsupported-operator` diagnostics.

## Test Plan

Mdtests and snapshots
This commit is contained in:
Alex Waygood
2025-12-12 21:53:29 +00:00
committed by GitHub
parent ca5f099481
commit 5a2aba237b
15 changed files with 401 additions and 107 deletions

View File

@@ -38,6 +38,8 @@ reveal_type(x) # revealed: int
## Unsupported types
<!-- snapshot-diagnostics -->
```py
class C:
def __isub__(self, other: str) -> int:

View File

@@ -79,31 +79,31 @@ reveal_type(Sub() & Sub()) # revealed: Literal["&"]
reveal_type(Sub() // Sub()) # revealed: Literal["//"]
# No does not implement any of the dunder methods.
# error: [unsupported-operator] "Operator `+` is not supported between objects of type `No` and `No`"
# error: [unsupported-operator] "Operator `+` is not supported between two objects of type `No`"
reveal_type(No() + No()) # revealed: Unknown
# error: [unsupported-operator] "Operator `-` is not supported between objects of type `No` and `No`"
# error: [unsupported-operator] "Operator `-` is not supported between two objects of type `No`"
reveal_type(No() - No()) # revealed: Unknown
# error: [unsupported-operator] "Operator `*` is not supported between objects of type `No` and `No`"
# error: [unsupported-operator] "Operator `*` is not supported between two objects of type `No`"
reveal_type(No() * No()) # revealed: Unknown
# error: [unsupported-operator] "Operator `@` is not supported between objects of type `No` and `No`"
# error: [unsupported-operator] "Operator `@` is not supported between two objects of type `No`"
reveal_type(No() @ No()) # revealed: Unknown
# error: [unsupported-operator] "Operator `/` is not supported between objects of type `No` and `No`"
# error: [unsupported-operator] "Operator `/` is not supported between two objects of type `No`"
reveal_type(No() / No()) # revealed: Unknown
# error: [unsupported-operator] "Operator `%` is not supported between objects of type `No` and `No`"
# error: [unsupported-operator] "Operator `%` is not supported between two objects of type `No`"
reveal_type(No() % No()) # revealed: Unknown
# error: [unsupported-operator] "Operator `**` is not supported between objects of type `No` and `No`"
# error: [unsupported-operator] "Operator `**` is not supported between two objects of type `No`"
reveal_type(No() ** No()) # revealed: Unknown
# error: [unsupported-operator] "Operator `<<` is not supported between objects of type `No` and `No`"
# error: [unsupported-operator] "Operator `<<` is not supported between two objects of type `No`"
reveal_type(No() << No()) # revealed: Unknown
# error: [unsupported-operator] "Operator `>>` is not supported between objects of type `No` and `No`"
# error: [unsupported-operator] "Operator `>>` is not supported between two objects of type `No`"
reveal_type(No() >> No()) # revealed: Unknown
# error: [unsupported-operator] "Operator `|` is not supported between objects of type `No` and `No`"
# error: [unsupported-operator] "Operator `|` is not supported between two objects of type `No`"
reveal_type(No() | No()) # revealed: Unknown
# error: [unsupported-operator] "Operator `^` is not supported between objects of type `No` and `No`"
# error: [unsupported-operator] "Operator `^` is not supported between two objects of type `No`"
reveal_type(No() ^ No()) # revealed: Unknown
# error: [unsupported-operator] "Operator `&` is not supported between objects of type `No` and `No`"
# error: [unsupported-operator] "Operator `&` is not supported between two objects of type `No`"
reveal_type(No() & No()) # revealed: Unknown
# error: [unsupported-operator] "Operator `//` is not supported between objects of type `No` and `No`"
# error: [unsupported-operator] "Operator `//` is not supported between two objects of type `No`"
reveal_type(No() // No()) # revealed: Unknown
# Yes does not implement any of the reflected dunder methods.
@@ -293,6 +293,8 @@ reveal_type(Yes() // No()) # revealed: Literal["//"]
## Classes
<!-- snapshot-diagnostics -->
Dunder methods defined in a class are available to instances of that class, but not to the class
itself. (For these operators to work on the class itself, they would have to be defined on the
class's type, i.e. `type`.)
@@ -307,11 +309,11 @@ class Yes:
class Sub(Yes): ...
class No: ...
# error: [unsupported-operator] "Operator `+` is not supported between objects of type `<class 'Yes'>` and `<class 'Yes'>`"
# error: [unsupported-operator] "Operator `+` is not supported between two objects of type `<class 'Yes'>`"
reveal_type(Yes + Yes) # revealed: Unknown
# error: [unsupported-operator] "Operator `+` is not supported between objects of type `<class 'Sub'>` and `<class 'Sub'>`"
# error: [unsupported-operator] "Operator `+` is not supported between two objects of type `<class 'Sub'>`"
reveal_type(Sub + Sub) # revealed: Unknown
# error: [unsupported-operator] "Operator `+` is not supported between objects of type `<class 'No'>` and `<class 'No'>`"
# error: [unsupported-operator] "Operator `+` is not supported between two objects of type `<class 'No'>`"
reveal_type(No + No) # revealed: Unknown
```
@@ -336,11 +338,11 @@ def sub() -> type[Sub]:
def no() -> type[No]:
return No
# error: [unsupported-operator] "Operator `+` is not supported between objects of type `type[Yes]` and `type[Yes]`"
# error: [unsupported-operator] "Operator `+` is not supported between two objects of type `type[Yes]`"
reveal_type(yes() + yes()) # revealed: Unknown
# error: [unsupported-operator] "Operator `+` is not supported between objects of type `type[Sub]` and `type[Sub]`"
# error: [unsupported-operator] "Operator `+` is not supported between two objects of type `type[Sub]`"
reveal_type(sub() + sub()) # revealed: Unknown
# error: [unsupported-operator] "Operator `+` is not supported between objects of type `type[No]` and `type[No]`"
# error: [unsupported-operator] "Operator `+` is not supported between two objects of type `type[No]`"
reveal_type(no() + no()) # revealed: Unknown
```
@@ -350,30 +352,54 @@ reveal_type(no() + no()) # revealed: Unknown
def f():
pass
# error: [unsupported-operator] "Operator `+` is not supported between objects of type `def f() -> Unknown` and `def f() -> Unknown`"
# error: [unsupported-operator] "Operator `+` is not supported between two objects of type `def f() -> Unknown`"
reveal_type(f + f) # revealed: Unknown
# error: [unsupported-operator] "Operator `-` is not supported between objects of type `def f() -> Unknown` and `def f() -> Unknown`"
# error: [unsupported-operator] "Operator `-` is not supported between two objects of type `def f() -> Unknown`"
reveal_type(f - f) # revealed: Unknown
# error: [unsupported-operator] "Operator `*` is not supported between objects of type `def f() -> Unknown` and `def f() -> Unknown`"
# error: [unsupported-operator] "Operator `*` is not supported between two objects of type `def f() -> Unknown`"
reveal_type(f * f) # revealed: Unknown
# error: [unsupported-operator] "Operator `@` is not supported between objects of type `def f() -> Unknown` and `def f() -> Unknown`"
# error: [unsupported-operator] "Operator `@` is not supported between two objects of type `def f() -> Unknown`"
reveal_type(f @ f) # revealed: Unknown
# error: [unsupported-operator] "Operator `/` is not supported between objects of type `def f() -> Unknown` and `def f() -> Unknown`"
# error: [unsupported-operator] "Operator `/` is not supported between two objects of type `def f() -> Unknown`"
reveal_type(f / f) # revealed: Unknown
# error: [unsupported-operator] "Operator `%` is not supported between objects of type `def f() -> Unknown` and `def f() -> Unknown`"
# error: [unsupported-operator] "Operator `%` is not supported between two objects of type `def f() -> Unknown`"
reveal_type(f % f) # revealed: Unknown
# error: [unsupported-operator] "Operator `**` is not supported between objects of type `def f() -> Unknown` and `def f() -> Unknown`"
# error: [unsupported-operator] "Operator `**` is not supported between two objects of type `def f() -> Unknown`"
reveal_type(f**f) # revealed: Unknown
# error: [unsupported-operator] "Operator `<<` is not supported between objects of type `def f() -> Unknown` and `def f() -> Unknown`"
# error: [unsupported-operator] "Operator `<<` is not supported between two objects of type `def f() -> Unknown`"
reveal_type(f << f) # revealed: Unknown
# error: [unsupported-operator] "Operator `>>` is not supported between objects of type `def f() -> Unknown` and `def f() -> Unknown`"
# error: [unsupported-operator] "Operator `>>` is not supported between two objects of type `def f() -> Unknown`"
reveal_type(f >> f) # revealed: Unknown
# error: [unsupported-operator] "Operator `|` is not supported between objects of type `def f() -> Unknown` and `def f() -> Unknown`"
# error: [unsupported-operator] "Operator `|` is not supported between two objects of type `def f() -> Unknown`"
reveal_type(f | f) # revealed: Unknown
# error: [unsupported-operator] "Operator `^` is not supported between objects of type `def f() -> Unknown` and `def f() -> Unknown`"
# error: [unsupported-operator] "Operator `^` is not supported between two objects of type `def f() -> Unknown`"
reveal_type(f ^ f) # revealed: Unknown
# error: [unsupported-operator] "Operator `&` is not supported between objects of type `def f() -> Unknown` and `def f() -> Unknown`"
# error: [unsupported-operator] "Operator `&` is not supported between two objects of type `def f() -> Unknown`"
reveal_type(f & f) # revealed: Unknown
# error: [unsupported-operator] "Operator `//` is not supported between objects of type `def f() -> Unknown` and `def f() -> Unknown`"
# error: [unsupported-operator] "Operator `//` is not supported between two objects of type `def f() -> Unknown`"
reveal_type(f // f) # revealed: Unknown
```
## Classes from different modules with the same name
We use the fully qualified names in diagnostics if the two classes have the same unqualified name,
but are nonetheless different.
<!-- snapshot-diagnostics -->
`mod1.py`:
```py
class A: ...
```
`mod2.py`:
```py
import mod1
class A: ...
# error: [unsupported-operator] "Operator `+` is not supported between objects of type `mod2.A` and `mod1.A`"
A() + mod1.A()
```

View File

@@ -412,7 +412,7 @@ class A:
def __init__(self):
self.__add__ = add_impl
# error: [unsupported-operator] "Operator `+` is not supported between objects of type `A` and `A`"
# error: [unsupported-operator] "Operator `+` is not supported between two objects of type `A`"
# revealed: Unknown
reveal_type(A() + A())
```

View File

@@ -18,7 +18,7 @@ cannot be added, because that would require addition of `int` and `str` or vice
def f2(i: int, s: str, int_or_str: int | str):
i + i
s + s
# error: [unsupported-operator] "Operator `+` is not supported between objects of type `int | str` and `int | str`"
# error: [unsupported-operator] "Operator `+` is not supported between two objects of type `int | str`"
reveal_type(int_or_str + int_or_str) # revealed: Unknown
```

View File

@@ -277,7 +277,7 @@ T = TypeVar("T", int, str)
def same_constrained_types(t1: T, t2: T) -> T:
# TODO: no error
# error: [unsupported-operator] "Operator `+` is not supported between objects of type `T@same_constrained_types` and `T@same_constrained_types`"
# error: [unsupported-operator] "Operator `+` is not supported between two objects of type `T@same_constrained_types`"
return t1 + t2
```
@@ -287,7 +287,7 @@ and an `int` and a `str` cannot be added together:
```py
def unions_are_different(t1: int | str, t2: int | str) -> int | str:
# error: [unsupported-operator] "Operator `+` is not supported between objects of type `int | str` and `int | str`"
# error: [unsupported-operator] "Operator `+` is not supported between two objects of type `int | str`"
return t1 + t2
```

View File

@@ -246,7 +246,7 @@ methods that are compatible with the return type, so the `return` expression is
```py
def same_constrained_types[T: (int, str)](t1: T, t2: T) -> T:
# TODO: no error
# error: [unsupported-operator] "Operator `+` is not supported between objects of type `T@same_constrained_types` and `T@same_constrained_types`"
# error: [unsupported-operator] "Operator `+` is not supported between two objects of type `T@same_constrained_types`"
return t1 + t2
```
@@ -256,7 +256,7 @@ and an `int` and a `str` cannot be added together:
```py
def unions_are_different(t1: int | str, t2: int | str) -> int | str:
# error: [unsupported-operator] "Operator `+` is not supported between objects of type `int | str` and `int | str`"
# error: [unsupported-operator] "Operator `+` is not supported between two objects of type `int | str`"
return t1 + t2
```

View File

@@ -214,7 +214,7 @@ def _(int_or_int: IntOrInt, list_of_int_or_list_of_int: ListOfIntOrListOfInt):
`NoneType` has no special or-operator behavior, so this is an error:
```py
None | None # error: [unsupported-operator] "Operator `|` is not supported between objects of type `None` and `None`"
None | None # error: [unsupported-operator] "Operator `|` is not supported between two objects of type `None`"
```
When constructing something nonsensical like `int | 1`, we emit a diagnostic for the expression

View File

@@ -19,12 +19,15 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/assignment/annotations.m
# Diagnostics
```
error[unsupported-operator]: Operator `|` is not supported between objects of type `<class 'int'>` and `<class 'str'>`
error[unsupported-operator]: Unsupported `|` operation
--> src/mdtest_snippet.py:2:12
|
1 | # error: [unsupported-operator]
2 | IntOrStr = int | str
| ^^^^^^^^^
| ---^^^---
| | |
| | Has type `<class 'str'>`
| Has type `<class 'int'>`
|
info: Note that `X | Y` PEP 604 union syntax is only available in Python 3.10 and later
info: Python 3.9 was assumed when resolving types because it was specified on the command line

View File

@@ -0,0 +1,44 @@
---
source: crates/ty_test/src/lib.rs
expression: snapshot
---
---
mdtest name: augmented.md - Augmented assignment - Unsupported types
mdtest path: crates/ty_python_semantic/resources/mdtest/assignment/augmented.md
---
# Python source files
## mdtest_snippet.py
```
1 | class C:
2 | def __isub__(self, other: str) -> int:
3 | return 42
4 |
5 | x = C()
6 | # error: [unsupported-operator] "Operator `-=` is not supported between objects of type `C` and `Literal[1]`"
7 | x -= 1
8 |
9 | reveal_type(x) # revealed: int
```
# Diagnostics
```
error[unsupported-operator]: Unsupported `-=` operation
--> src/mdtest_snippet.py:7:1
|
5 | x = C()
6 | # error: [unsupported-operator] "Operator `-=` is not supported between objects of type `C` and `Literal[1]`"
7 | x -= 1
| -^^^^-
| | |
| | Has type `Literal[1]`
| Has type `C`
8 |
9 | reveal_type(x) # revealed: int
|
info: rule `unsupported-operator` is enabled by default
```

View File

@@ -0,0 +1,80 @@
---
source: crates/ty_test/src/lib.rs
expression: snapshot
---
---
mdtest name: custom.md - Custom binary operations - Classes
mdtest path: crates/ty_python_semantic/resources/mdtest/binary/custom.md
---
# Python source files
## mdtest_snippet.py
```
1 | from typing import Literal
2 |
3 | class Yes:
4 | def __add__(self, other) -> Literal["+"]:
5 | return "+"
6 |
7 | class Sub(Yes): ...
8 | class No: ...
9 |
10 | # error: [unsupported-operator] "Operator `+` is not supported between two objects of type `<class 'Yes'>`"
11 | reveal_type(Yes + Yes) # revealed: Unknown
12 | # error: [unsupported-operator] "Operator `+` is not supported between two objects of type `<class 'Sub'>`"
13 | reveal_type(Sub + Sub) # revealed: Unknown
14 | # error: [unsupported-operator] "Operator `+` is not supported between two objects of type `<class 'No'>`"
15 | reveal_type(No + No) # revealed: Unknown
```
# Diagnostics
```
error[unsupported-operator]: Unsupported `+` operation
--> src/mdtest_snippet.py:11:13
|
10 | # error: [unsupported-operator] "Operator `+` is not supported between two objects of type `<class 'Yes'>`"
11 | reveal_type(Yes + Yes) # revealed: Unknown
| ---^^^---
| |
| Both operands have type `<class 'Yes'>`
12 | # error: [unsupported-operator] "Operator `+` is not supported between two objects of type `<class 'Sub'>`"
13 | reveal_type(Sub + Sub) # revealed: Unknown
|
info: rule `unsupported-operator` is enabled by default
```
```
error[unsupported-operator]: Unsupported `+` operation
--> src/mdtest_snippet.py:13:13
|
11 | reveal_type(Yes + Yes) # revealed: Unknown
12 | # error: [unsupported-operator] "Operator `+` is not supported between two objects of type `<class 'Sub'>`"
13 | reveal_type(Sub + Sub) # revealed: Unknown
| ---^^^---
| |
| Both operands have type `<class 'Sub'>`
14 | # error: [unsupported-operator] "Operator `+` is not supported between two objects of type `<class 'No'>`"
15 | reveal_type(No + No) # revealed: Unknown
|
info: rule `unsupported-operator` is enabled by default
```
```
error[unsupported-operator]: Unsupported `+` operation
--> src/mdtest_snippet.py:15:13
|
13 | reveal_type(Sub + Sub) # revealed: Unknown
14 | # error: [unsupported-operator] "Operator `+` is not supported between two objects of type `<class 'No'>`"
15 | reveal_type(No + No) # revealed: Unknown
| --^^^--
| |
| Both operands have type `<class 'No'>`
|
info: rule `unsupported-operator` is enabled by default
```

View File

@@ -0,0 +1,44 @@
---
source: crates/ty_test/src/lib.rs
expression: snapshot
---
---
mdtest name: custom.md - Custom binary operations - Classes from different modules with the same name
mdtest path: crates/ty_python_semantic/resources/mdtest/binary/custom.md
---
# Python source files
## mod1.py
```
1 | class A: ...
```
## mod2.py
```
1 | import mod1
2 |
3 | class A: ...
4 |
5 | # error: [unsupported-operator] "Operator `+` is not supported between objects of type `mod2.A` and `mod1.A`"
6 | A() + mod1.A()
```
# Diagnostics
```
error[unsupported-operator]: Unsupported `+` operation
--> src/mod2.py:6:1
|
5 | # error: [unsupported-operator] "Operator `+` is not supported between objects of type `mod2.A` and `mod1.A`"
6 | A() + mod1.A()
| ---^^^--------
| | |
| | Has type `mod1.A`
| Has type `mod2.A`
|
info: rule `unsupported-operator` is enabled by default
```

View File

@@ -24,11 +24,11 @@ reveal_type(+Sub()) # revealed: bool
reveal_type(-Sub()) # revealed: str
reveal_type(~Sub()) # revealed: int
# error: [unsupported-operator] "Unary operator `+` is not supported for type `No`"
# error: [unsupported-operator] "Unary operator `+` is not supported for object of type `No`"
reveal_type(+No()) # revealed: Unknown
# error: [unsupported-operator] "Unary operator `-` is not supported for type `No`"
# error: [unsupported-operator] "Unary operator `-` is not supported for object of type `No`"
reveal_type(-No()) # revealed: Unknown
# error: [unsupported-operator] "Unary operator `~` is not supported for type `No`"
# error: [unsupported-operator] "Unary operator `~` is not supported for object of type `No`"
reveal_type(~No()) # revealed: Unknown
```
@@ -52,25 +52,25 @@ class Yes:
class Sub(Yes): ...
class No: ...
# error: [unsupported-operator] "Unary operator `+` is not supported for type `<class 'Yes'>`"
# error: [unsupported-operator] "Unary operator `+` is not supported for object of type `<class 'Yes'>`"
reveal_type(+Yes) # revealed: Unknown
# error: [unsupported-operator] "Unary operator `-` is not supported for type `<class 'Yes'>`"
# error: [unsupported-operator] "Unary operator `-` is not supported for object of type `<class 'Yes'>`"
reveal_type(-Yes) # revealed: Unknown
# error: [unsupported-operator] "Unary operator `~` is not supported for type `<class 'Yes'>`"
# error: [unsupported-operator] "Unary operator `~` is not supported for object of type `<class 'Yes'>`"
reveal_type(~Yes) # revealed: Unknown
# error: [unsupported-operator] "Unary operator `+` is not supported for type `<class 'Sub'>`"
# error: [unsupported-operator] "Unary operator `+` is not supported for object of type `<class 'Sub'>`"
reveal_type(+Sub) # revealed: Unknown
# error: [unsupported-operator] "Unary operator `-` is not supported for type `<class 'Sub'>`"
# error: [unsupported-operator] "Unary operator `-` is not supported for object of type `<class 'Sub'>`"
reveal_type(-Sub) # revealed: Unknown
# error: [unsupported-operator] "Unary operator `~` is not supported for type `<class 'Sub'>`"
# error: [unsupported-operator] "Unary operator `~` is not supported for object of type `<class 'Sub'>`"
reveal_type(~Sub) # revealed: Unknown
# error: [unsupported-operator] "Unary operator `+` is not supported for type `<class 'No'>`"
# error: [unsupported-operator] "Unary operator `+` is not supported for object of type `<class 'No'>`"
reveal_type(+No) # revealed: Unknown
# error: [unsupported-operator] "Unary operator `-` is not supported for type `<class 'No'>`"
# error: [unsupported-operator] "Unary operator `-` is not supported for object of type `<class 'No'>`"
reveal_type(-No) # revealed: Unknown
# error: [unsupported-operator] "Unary operator `~` is not supported for type `<class 'No'>`"
# error: [unsupported-operator] "Unary operator `~` is not supported for object of type `<class 'No'>`"
reveal_type(~No) # revealed: Unknown
```
@@ -80,11 +80,11 @@ reveal_type(~No) # revealed: Unknown
def f():
pass
# error: [unsupported-operator] "Unary operator `+` is not supported for type `def f() -> Unknown`"
# error: [unsupported-operator] "Unary operator `+` is not supported for object of type `def f() -> Unknown`"
reveal_type(+f) # revealed: Unknown
# error: [unsupported-operator] "Unary operator `-` is not supported for type `def f() -> Unknown`"
# error: [unsupported-operator] "Unary operator `-` is not supported for object of type `def f() -> Unknown`"
reveal_type(-f) # revealed: Unknown
# error: [unsupported-operator] "Unary operator `~` is not supported for type `def f() -> Unknown`"
# error: [unsupported-operator] "Unary operator `~` is not supported for object of type `def f() -> Unknown`"
reveal_type(~f) # revealed: Unknown
```
@@ -113,25 +113,25 @@ def sub() -> type[Sub]:
def no() -> type[No]:
return No
# error: [unsupported-operator] "Unary operator `+` is not supported for type `type[Yes]`"
# error: [unsupported-operator] "Unary operator `+` is not supported for object of type `type[Yes]`"
reveal_type(+yes()) # revealed: Unknown
# error: [unsupported-operator] "Unary operator `-` is not supported for type `type[Yes]`"
# error: [unsupported-operator] "Unary operator `-` is not supported for object of type `type[Yes]`"
reveal_type(-yes()) # revealed: Unknown
# error: [unsupported-operator] "Unary operator `~` is not supported for type `type[Yes]`"
# error: [unsupported-operator] "Unary operator `~` is not supported for object of type `type[Yes]`"
reveal_type(~yes()) # revealed: Unknown
# error: [unsupported-operator] "Unary operator `+` is not supported for type `type[Sub]`"
# error: [unsupported-operator] "Unary operator `+` is not supported for object of type `type[Sub]`"
reveal_type(+sub()) # revealed: Unknown
# error: [unsupported-operator] "Unary operator `-` is not supported for type `type[Sub]`"
# error: [unsupported-operator] "Unary operator `-` is not supported for object of type `type[Sub]`"
reveal_type(-sub()) # revealed: Unknown
# error: [unsupported-operator] "Unary operator `~` is not supported for type `type[Sub]`"
# error: [unsupported-operator] "Unary operator `~` is not supported for object of type `type[Sub]`"
reveal_type(~sub()) # revealed: Unknown
# error: [unsupported-operator] "Unary operator `+` is not supported for type `type[No]`"
# error: [unsupported-operator] "Unary operator `+` is not supported for object of type `type[No]`"
reveal_type(+no()) # revealed: Unknown
# error: [unsupported-operator] "Unary operator `-` is not supported for type `type[No]`"
# error: [unsupported-operator] "Unary operator `-` is not supported for object of type `type[No]`"
reveal_type(-no()) # revealed: Unknown
# error: [unsupported-operator] "Unary operator `~` is not supported for type `type[No]`"
# error: [unsupported-operator] "Unary operator `~` is not supported for object of type `type[No]`"
reveal_type(~no()) # revealed: Unknown
```
@@ -160,10 +160,10 @@ reveal_type(+Sub) # revealed: bool
reveal_type(-Sub) # revealed: str
reveal_type(~Sub) # revealed: int
# error: [unsupported-operator] "Unary operator `+` is not supported for type `<class 'No'>`"
# error: [unsupported-operator] "Unary operator `+` is not supported for object of type `<class 'No'>`"
reveal_type(+No) # revealed: Unknown
# error: [unsupported-operator] "Unary operator `-` is not supported for type `<class 'No'>`"
# error: [unsupported-operator] "Unary operator `-` is not supported for object of type `<class 'No'>`"
reveal_type(-No) # revealed: Unknown
# error: [unsupported-operator] "Unary operator `~` is not supported for type `<class 'No'>`"
# error: [unsupported-operator] "Unary operator `~` is not supported for object of type `<class 'No'>`"
reveal_type(~No) # revealed: Unknown
```

View File

@@ -27,7 +27,7 @@ reveal_type(~a) # revealed: Literal[True]
class NoDunder: ...
b = NoDunder()
+b # error: [unsupported-operator] "Unary operator `+` is not supported for type `NoDunder`"
-b # error: [unsupported-operator] "Unary operator `-` is not supported for type `NoDunder`"
~b # error: [unsupported-operator] "Unary operator `~` is not supported for type `NoDunder`"
+b # error: [unsupported-operator] "Unary operator `+` is not supported for object of type `NoDunder`"
-b # error: [unsupported-operator] "Unary operator `-` is not supported for object of type `NoDunder`"
~b # error: [unsupported-operator] "Unary operator `~` is not supported for object of type `NoDunder`"
```