forked from astral-sh/ruff
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Don't special-case class instances in unary expression inference (ast…
…ral-sh#15045) We have a handy `to_meta_type` that does the right thing for class instances, and also works for all of the other types that are “instances of” something. Unless I'm missing something, this should let us get rid of the catch-all clause in one fell swoop. cf astral-sh#14548
- Loading branch information
Showing
2 changed files
with
193 additions
and
13 deletions.
There are no files selected for viewing
165 changes: 165 additions & 0 deletions
165
crates/red_knot_python_semantic/resources/mdtest/unary/custom.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
# Custom unary operations | ||
|
||
## Class instances | ||
|
||
```py | ||
class Yes: | ||
def __pos__(self) -> bool: | ||
return False | ||
|
||
def __neg__(self) -> str: | ||
return "negative" | ||
|
||
def __invert__(self) -> int: | ||
return 17 | ||
|
||
class Sub(Yes): ... | ||
class No: ... | ||
|
||
reveal_type(+Yes()) # revealed: bool | ||
reveal_type(-Yes()) # revealed: str | ||
reveal_type(~Yes()) # revealed: int | ||
|
||
reveal_type(+Sub()) # revealed: bool | ||
reveal_type(-Sub()) # revealed: str | ||
reveal_type(~Sub()) # revealed: int | ||
|
||
# error: [unsupported-operator] "Unary operator `+` is unsupported for type `No`" | ||
reveal_type(+No()) # revealed: Unknown | ||
# error: [unsupported-operator] "Unary operator `-` is unsupported for type `No`" | ||
reveal_type(-No()) # revealed: Unknown | ||
# error: [unsupported-operator] "Unary operator `~` is unsupported for type `No`" | ||
reveal_type(~No()) # revealed: Unknown | ||
``` | ||
|
||
## Classes | ||
|
||
```py | ||
class Yes: | ||
def __pos__(self) -> bool: | ||
return False | ||
|
||
def __neg__(self) -> str: | ||
return "negative" | ||
|
||
def __invert__(self) -> int: | ||
return 17 | ||
|
||
class Sub(Yes): ... | ||
class No: ... | ||
|
||
# error: [unsupported-operator] "Unary operator `+` is unsupported for type `Literal[Yes]`" | ||
reveal_type(+Yes) # revealed: Unknown | ||
# error: [unsupported-operator] "Unary operator `-` is unsupported for type `Literal[Yes]`" | ||
reveal_type(-Yes) # revealed: Unknown | ||
# error: [unsupported-operator] "Unary operator `~` is unsupported for type `Literal[Yes]`" | ||
reveal_type(~Yes) # revealed: Unknown | ||
|
||
# error: [unsupported-operator] "Unary operator `+` is unsupported for type `Literal[Sub]`" | ||
reveal_type(+Sub) # revealed: Unknown | ||
# error: [unsupported-operator] "Unary operator `-` is unsupported for type `Literal[Sub]`" | ||
reveal_type(-Sub) # revealed: Unknown | ||
# error: [unsupported-operator] "Unary operator `~` is unsupported for type `Literal[Sub]`" | ||
reveal_type(~Sub) # revealed: Unknown | ||
|
||
# error: [unsupported-operator] "Unary operator `+` is unsupported for type `Literal[No]`" | ||
reveal_type(+No) # revealed: Unknown | ||
# error: [unsupported-operator] "Unary operator `-` is unsupported for type `Literal[No]`" | ||
reveal_type(-No) # revealed: Unknown | ||
# error: [unsupported-operator] "Unary operator `~` is unsupported for type `Literal[No]`" | ||
reveal_type(~No) # revealed: Unknown | ||
``` | ||
|
||
## Function literals | ||
|
||
```py | ||
def f(): | ||
pass | ||
|
||
# error: [unsupported-operator] "Unary operator `+` is unsupported for type `Literal[f]`" | ||
reveal_type(+f) # revealed: Unknown | ||
# error: [unsupported-operator] "Unary operator `-` is unsupported for type `Literal[f]`" | ||
reveal_type(-f) # revealed: Unknown | ||
# error: [unsupported-operator] "Unary operator `~` is unsupported for type `Literal[f]`" | ||
reveal_type(~f) # revealed: Unknown | ||
``` | ||
|
||
## Subclass | ||
|
||
```py | ||
class Yes: | ||
def __pos__(self) -> bool: | ||
return False | ||
|
||
def __neg__(self) -> str: | ||
return "negative" | ||
|
||
def __invert__(self) -> int: | ||
return 17 | ||
|
||
class Sub(Yes): ... | ||
class No: ... | ||
|
||
def yes() -> type[Yes]: | ||
return Yes | ||
|
||
def sub() -> type[Sub]: | ||
return Sub | ||
|
||
def no() -> type[No]: | ||
return No | ||
|
||
# error: [unsupported-operator] "Unary operator `+` is unsupported for type `type[Yes]`" | ||
reveal_type(+yes()) # revealed: Unknown | ||
# error: [unsupported-operator] "Unary operator `-` is unsupported for type `type[Yes]`" | ||
reveal_type(-yes()) # revealed: Unknown | ||
# error: [unsupported-operator] "Unary operator `~` is unsupported for type `type[Yes]`" | ||
reveal_type(~yes()) # revealed: Unknown | ||
|
||
# error: [unsupported-operator] "Unary operator `+` is unsupported for type `type[Sub]`" | ||
reveal_type(+sub()) # revealed: Unknown | ||
# error: [unsupported-operator] "Unary operator `-` is unsupported for type `type[Sub]`" | ||
reveal_type(-sub()) # revealed: Unknown | ||
# error: [unsupported-operator] "Unary operator `~` is unsupported for type `type[Sub]`" | ||
reveal_type(~sub()) # revealed: Unknown | ||
|
||
# error: [unsupported-operator] "Unary operator `+` is unsupported for type `type[No]`" | ||
reveal_type(+no()) # revealed: Unknown | ||
# error: [unsupported-operator] "Unary operator `-` is unsupported for type `type[No]`" | ||
reveal_type(-no()) # revealed: Unknown | ||
# error: [unsupported-operator] "Unary operator `~` is unsupported for type `type[No]`" | ||
reveal_type(~no()) # revealed: Unknown | ||
``` | ||
|
||
## Metaclass | ||
|
||
```py | ||
class Meta(type): | ||
def __pos__(self) -> bool: | ||
return False | ||
|
||
def __neg__(self) -> str: | ||
return "negative" | ||
|
||
def __invert__(self) -> int: | ||
return 17 | ||
|
||
class Yes(metaclass=Meta): ... | ||
class Sub(Yes): ... | ||
class No: ... | ||
|
||
reveal_type(+Yes) # revealed: bool | ||
reveal_type(-Yes) # revealed: str | ||
reveal_type(~Yes) # revealed: int | ||
|
||
reveal_type(+Sub) # revealed: bool | ||
reveal_type(-Sub) # revealed: str | ||
reveal_type(~Sub) # revealed: int | ||
|
||
# error: [unsupported-operator] "Unary operator `+` is unsupported for type `Literal[No]`" | ||
reveal_type(+No) # revealed: Unknown | ||
# error: [unsupported-operator] "Unary operator `-` is unsupported for type `Literal[No]`" | ||
reveal_type(-No) # revealed: Unknown | ||
# error: [unsupported-operator] "Unary operator `~` is unsupported for type `Literal[No]`" | ||
reveal_type(~No) # revealed: Unknown | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters