diff --git a/crates/ty_python_semantic/resources/mdtest/annotations/generic_alias.md b/crates/ty_python_semantic/resources/mdtest/annotations/generic_alias.md new file mode 100644 index 0000000000..86a115d90e --- /dev/null +++ b/crates/ty_python_semantic/resources/mdtest/annotations/generic_alias.md @@ -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: + +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 +``` diff --git a/crates/ty_python_semantic/resources/mdtest/annotations/new_types.md b/crates/ty_python_semantic/resources/mdtest/annotations/new_types.md index a41b6ad870..39a88cff49 100644 --- a/crates/ty_python_semantic/resources/mdtest/annotations/new_types.md +++ b/crates/ty_python_semantic/resources/mdtest/annotations/new_types.md @@ -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 ``" -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 diff --git a/crates/ty_python_semantic/src/types.rs b/crates/ty_python_semantic/src/types.rs index ff41b2d06d..a81e09edc8 100644 --- a/crates/ty_python_semantic/src/types.rs +++ b/crates/ty_python_semantic/src/types.rs @@ -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)