mirror of https://github.com/astral-sh/ruff
[ty] Remove `GenericAlias`-related todo type (#21728)
## Summary If you manage to create an `typing.GenericAlias` instance without us knowing how that was created, then we don't know what to do with this in a type annotation. So it's better to be explicit and show an error instead of failing silently with a `@Todo` type. ## Test Plan * New Markdown tests * Zero ecosystem impact
This commit is contained in:
parent
5358ddae88
commit
116fd7c7af
|
|
@ -0,0 +1,34 @@
|
|||
# GenericAlias in type expressions
|
||||
|
||||
We recognize if a `types.GenericAlias` instance is created by specializing a generic class. We don't
|
||||
explicitly mention it in our type display, but `list[int]` in the example below is a `GenericAlias`
|
||||
instance at runtime:
|
||||
|
||||
```py
|
||||
Numbers = list[int]
|
||||
|
||||
# At runtime, `Numbers` is an instance of `types.GenericAlias`. Showing
|
||||
# this as `list[int]` is more helpful, though:
|
||||
reveal_type(Numbers) # revealed: <class 'list[int]'>
|
||||
|
||||
def _(numbers: Numbers) -> None:
|
||||
reveal_type(numbers) # revealed: list[int]
|
||||
```
|
||||
|
||||
It is also valid to create `GenericAlias` instances manually:
|
||||
|
||||
```py
|
||||
from types import GenericAlias
|
||||
|
||||
Strings = GenericAlias(list, (str,))
|
||||
|
||||
reveal_type(Strings) # revealed: GenericAlias
|
||||
```
|
||||
|
||||
However, using such a `GenericAlias` instance in a type expression is currently not supported:
|
||||
|
||||
```py
|
||||
# error: [invalid-type-form] "Variable of type `GenericAlias` is not allowed in a type expression"
|
||||
def _(strings: Strings) -> None:
|
||||
reveal_type(strings) # revealed: Unknown
|
||||
```
|
||||
|
|
@ -1,24 +1,16 @@
|
|||
# NewType
|
||||
|
||||
## Valid forms
|
||||
## Basic usage
|
||||
|
||||
`NewType` can be used to create distinct types that are based on existing types:
|
||||
|
||||
```py
|
||||
from typing_extensions import NewType
|
||||
from types import GenericAlias
|
||||
|
||||
X = GenericAlias(type, ())
|
||||
A = NewType("A", int)
|
||||
# TODO: typeshed for `typing.GenericAlias` uses `type` for the first argument. `NewType` should be special-cased
|
||||
# to be compatible with `type`
|
||||
# error: [invalid-argument-type] "Argument to function `__new__` is incorrect: Expected `type`, found `<NewType pseudo-class 'A'>`"
|
||||
B = GenericAlias(A, ())
|
||||
UserId = NewType("UserId", int)
|
||||
|
||||
def _(
|
||||
a: A,
|
||||
b: B,
|
||||
):
|
||||
reveal_type(a) # revealed: A
|
||||
reveal_type(b) # revealed: @Todo(Support for `typing.GenericAlias` instances in type expressions)
|
||||
def _(user_id: UserId):
|
||||
reveal_type(user_id) # revealed: UserId
|
||||
```
|
||||
|
||||
## Subtyping
|
||||
|
|
|
|||
|
|
@ -7372,9 +7372,6 @@ impl<'db> Type<'db> {
|
|||
Some(KnownClass::TypeVarTuple) => Ok(todo_type!(
|
||||
"Support for `typing.TypeVarTuple` instances in type expressions"
|
||||
)),
|
||||
Some(KnownClass::GenericAlias) => Ok(todo_type!(
|
||||
"Support for `typing.GenericAlias` instances in type expressions"
|
||||
)),
|
||||
_ => Err(InvalidTypeExpressionError {
|
||||
invalid_expressions: smallvec::smallvec_inline![
|
||||
InvalidTypeExpression::InvalidType(*self, scope_id)
|
||||
|
|
|
|||
Loading…
Reference in New Issue