[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:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user