[ty] Use unqualified names for displays of `ParamSpec`, `TypeVar` and `TypeAliasType`

This commit is contained in:
Alex Waygood 2025-12-13 15:41:38 +00:00
parent e2ec2bc306
commit 91fe690f89
13 changed files with 149 additions and 60 deletions

View File

@ -3057,10 +3057,10 @@ def function():
); );
assert_snapshot!(test.hover(), @r" assert_snapshot!(test.hover(), @r"
typing.TypeVar TypeVar
--------------------------------------------- ---------------------------------------------
```python ```python
typing.TypeVar TypeVar
``` ```
--------------------------------------------- ---------------------------------------------
info[hover]: Hovered content is info[hover]: Hovered content is
@ -3120,10 +3120,10 @@ def function():
); );
assert_snapshot!(test.hover(), @r" assert_snapshot!(test.hover(), @r"
typing.TypeVar TypeVar
--------------------------------------------- ---------------------------------------------
```python ```python
typing.TypeVar TypeVar
``` ```
--------------------------------------------- ---------------------------------------------
info[hover]: Hovered content is info[hover]: Hovered content is

View File

@ -6635,26 +6635,9 @@ mod tests {
assert_snapshot!(test.inlay_hints(), @r" assert_snapshot!(test.inlay_hints(), @r"
from typing import Protocol, TypeVar from typing import Protocol, TypeVar
T[: typing.TypeVar] = TypeVar([name=]'T') T = TypeVar([name=]'T')
Strange[: <special form 'typing.Protocol[T]'>] = Protocol[T] Strange[: <special form 'typing.Protocol[T]'>] = Protocol[T]
--------------------------------------------- ---------------------------------------------
info[inlay-hint-location]: Inlay Hint Target
--> main.py:3:1
|
2 | from typing import Protocol, TypeVar
3 | T = TypeVar('T')
| ^
4 | Strange = Protocol[T]
|
info: Source
--> main2.py:3:5
|
2 | from typing import Protocol, TypeVar
3 | T[: typing.TypeVar] = TypeVar([name=]'T')
| ^^^^^^^^^^^^^^
4 | Strange[: <special form 'typing.Protocol[T]'>] = Protocol[T]
|
info[inlay-hint-location]: Inlay Hint Target info[inlay-hint-location]: Inlay Hint Target
--> stdlib/typing.pyi:276:13 --> stdlib/typing.pyi:276:13
| |
@ -6666,10 +6649,10 @@ mod tests {
278 | bound: Any | None = None, # AnnotationForm 278 | bound: Any | None = None, # AnnotationForm
| |
info: Source info: Source
--> main2.py:3:32 --> main2.py:3:14
| |
2 | from typing import Protocol, TypeVar 2 | from typing import Protocol, TypeVar
3 | T[: typing.TypeVar] = TypeVar([name=]'T') 3 | T = TypeVar([name=]'T')
| ^^^^ | ^^^^
4 | Strange[: <special form 'typing.Protocol[T]'>] = Protocol[T] 4 | Strange[: <special form 'typing.Protocol[T]'>] = Protocol[T]
| |
@ -6687,7 +6670,7 @@ mod tests {
--> main2.py:4:26 --> main2.py:4:26
| |
2 | from typing import Protocol, TypeVar 2 | from typing import Protocol, TypeVar
3 | T[: typing.TypeVar] = TypeVar([name=]'T') 3 | T = TypeVar([name=]'T')
4 | Strange[: <special form 'typing.Protocol[T]'>] = Protocol[T] 4 | Strange[: <special form 'typing.Protocol[T]'>] = Protocol[T]
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
| |
@ -6704,18 +6687,124 @@ mod tests {
--> main2.py:4:42 --> main2.py:4:42
| |
2 | from typing import Protocol, TypeVar 2 | from typing import Protocol, TypeVar
3 | T[: typing.TypeVar] = TypeVar([name=]'T') 3 | T = TypeVar([name=]'T')
4 | Strange[: <special form 'typing.Protocol[T]'>] = Protocol[T] 4 | Strange[: <special form 'typing.Protocol[T]'>] = Protocol[T]
| ^ | ^
| |
");
}
#[test]
fn test_paramspec_creation_inlay_hint() {
let mut test = inlay_hint_test(
"
from typing import ParamSpec
P = ParamSpec('P')",
);
assert_snapshot!(test.inlay_hints(), @r"
from typing import ParamSpec
P = ParamSpec([name=]'P')
--------------------------------------------- ---------------------------------------------
info[inlay-hint-edit]: File after edits info[inlay-hint-location]: Inlay Hint Target
--> stdlib/typing.pyi:552:17
|
550 | def __new__(
551 | cls,
552 | name: str,
| ^^^^
553 | *,
554 | bound: Any | None = None, # AnnotationForm
|
info: Source info: Source
--> main2.py:3:16
|
2 | from typing import ParamSpec
3 | P = ParamSpec([name=]'P')
| ^^^^
|
");
}
from typing import Protocol, TypeVar #[test]
T: typing.TypeVar = TypeVar('T') fn test_typealiastype_creation_inlay_hint() {
Strange = Protocol[T] let mut test = inlay_hint_test(
"
from typing_extensions import TypeAliasType
A = TypeAliasType('A', str)",
);
assert_snapshot!(test.inlay_hints(), @r#"
from typing_extensions import TypeAliasType
A = TypeAliasType([name=]'A', [value=]str)
---------------------------------------------
info[inlay-hint-location]: Inlay Hint Target
--> stdlib/typing.pyi:2032:26
|
2030 | """
2031 |
2032 | def __new__(cls, name: str, value: Any, *, type_params: tuple[_TypeParameter, ...] = ()) -> Self: ...
| ^^^^
2033 | @property
2034 | def __value__(self) -> Any: ... # AnnotationForm
|
info: Source
--> main2.py:3:20
|
2 | from typing_extensions import TypeAliasType
3 | A = TypeAliasType([name=]'A', [value=]str)
| ^^^^
|
info[inlay-hint-location]: Inlay Hint Target
--> stdlib/typing.pyi:2032:37
|
2030 | """
2031 |
2032 | def __new__(cls, name: str, value: Any, *, type_params: tuple[_TypeParameter, ...] = ()) -> Self: ...
| ^^^^^
2033 | @property
2034 | def __value__(self) -> Any: ... # AnnotationForm
|
info: Source
--> main2.py:3:32
|
2 | from typing_extensions import TypeAliasType
3 | A = TypeAliasType([name=]'A', [value=]str)
| ^^^^^
|
"#);
}
#[test]
fn test_typevartuple_creation_inlay_hint() {
let mut test = inlay_hint_test(
"
from typing_extensions import TypeVarTuple
Ts = TypeVarTuple('Ts')",
);
assert_snapshot!(test.inlay_hints(), @r"
from typing_extensions import TypeVarTuple
Ts = TypeVarTuple([name=]'Ts')
---------------------------------------------
info[inlay-hint-location]: Inlay Hint Target
--> stdlib/typing.pyi:412:30
|
410 | def has_default(self) -> bool: ...
411 | if sys.version_info >= (3, 13):
412 | def __new__(cls, name: str, *, default: Any = ...) -> Self: ... # AnnotationForm
| ^^^^
413 | elif sys.version_info >= (3, 12):
414 | def __new__(cls, name: str) -> Self: ...
|
info: Source
--> main2.py:3:20
|
2 | from typing_extensions import TypeVarTuple
3 | Ts = TypeVarTuple([name=]'Ts')
| ^^^^
|
"); ");
} }

View File

@ -201,7 +201,7 @@ python-version = "3.12"
```py ```py
type IntOrStr = int | str type IntOrStr = int | str
reveal_type(IntOrStr.__or__) # revealed: bound method typing.TypeAliasType.__or__(right: Any, /) -> _SpecialForm reveal_type(IntOrStr.__or__) # revealed: bound method TypeAliasType.__or__(right: Any, /) -> _SpecialForm
``` ```
## Method calls on types not disjoint from `None` ## Method calls on types not disjoint from `None`

View File

@ -567,7 +567,7 @@ def f(x: int):
super(x, x) super(x, x)
type IntAlias = int type IntAlias = int
# error: [invalid-super-argument] "`typing.TypeAliasType` is not a valid class" # error: [invalid-super-argument] "`TypeAliasType` is not a valid class"
super(IntAlias, 0) super(IntAlias, 0)
# error: [invalid-super-argument] "`str` is not an instance or subclass of `<class 'int'>` in `super(<class 'int'>, str)` call" # error: [invalid-super-argument] "`str` is not an instance or subclass of `<class 'int'>` in `super(<class 'int'>, str)` call"

View File

@ -9,7 +9,7 @@ from typing import ParamSpec
P = ParamSpec("P") P = ParamSpec("P")
reveal_type(type(P)) # revealed: <class 'ParamSpec'> reveal_type(type(P)) # revealed: <class 'ParamSpec'>
reveal_type(P) # revealed: typing.ParamSpec reveal_type(P) # revealed: ParamSpec
reveal_type(P.__name__) # revealed: Literal["P"] reveal_type(P.__name__) # revealed: Literal["P"]
``` ```

View File

@ -22,7 +22,7 @@ from typing import TypeVar
T = TypeVar("T") T = TypeVar("T")
reveal_type(type(T)) # revealed: <class 'TypeVar'> reveal_type(type(T)) # revealed: <class 'TypeVar'>
reveal_type(T) # revealed: typing.TypeVar reveal_type(T) # revealed: TypeVar
reveal_type(T.__name__) # revealed: Literal["T"] reveal_type(T.__name__) # revealed: Literal["T"]
``` ```
@ -146,7 +146,7 @@ from typing import TypeVar
T = TypeVar("T", default=int) T = TypeVar("T", default=int)
reveal_type(type(T)) # revealed: <class 'TypeVar'> reveal_type(type(T)) # revealed: <class 'TypeVar'>
reveal_type(T) # revealed: typing.TypeVar reveal_type(T) # revealed: TypeVar
reveal_type(T.__default__) # revealed: int reveal_type(T.__default__) # revealed: int
reveal_type(T.__bound__) # revealed: None reveal_type(T.__bound__) # revealed: None
reveal_type(T.__constraints__) # revealed: tuple[()] reveal_type(T.__constraints__) # revealed: tuple[()]
@ -187,7 +187,7 @@ from typing import TypeVar
T = TypeVar("T", bound=int) T = TypeVar("T", bound=int)
reveal_type(type(T)) # revealed: <class 'TypeVar'> reveal_type(type(T)) # revealed: <class 'TypeVar'>
reveal_type(T) # revealed: typing.TypeVar reveal_type(T) # revealed: TypeVar
reveal_type(T.__bound__) # revealed: int reveal_type(T.__bound__) # revealed: int
reveal_type(T.__constraints__) # revealed: tuple[()] reveal_type(T.__constraints__) # revealed: tuple[()]
@ -211,7 +211,7 @@ from typing import TypeVar
T = TypeVar("T", int, str) T = TypeVar("T", int, str)
reveal_type(type(T)) # revealed: <class 'TypeVar'> reveal_type(type(T)) # revealed: <class 'TypeVar'>
reveal_type(T) # revealed: typing.TypeVar reveal_type(T) # revealed: TypeVar
reveal_type(T.__constraints__) # revealed: tuple[int, str] reveal_type(T.__constraints__) # revealed: tuple[int, str]
S = TypeVar("S") S = TypeVar("S")

View File

@ -12,7 +12,7 @@ python-version = "3.13"
```py ```py
def foo1[**P]() -> None: def foo1[**P]() -> None:
reveal_type(P) # revealed: typing.ParamSpec reveal_type(P) # revealed: ParamSpec
``` ```
## Bounds and constraints ## Bounds and constraints
@ -45,14 +45,14 @@ The default value for a `ParamSpec` can be either a list of types, `...`, or ano
```py ```py
def foo2[**P = ...]() -> None: def foo2[**P = ...]() -> None:
reveal_type(P) # revealed: typing.ParamSpec reveal_type(P) # revealed: ParamSpec
def foo3[**P = [int, str]]() -> None: def foo3[**P = [int, str]]() -> None:
reveal_type(P) # revealed: typing.ParamSpec reveal_type(P) # revealed: ParamSpec
def foo4[**P, **Q = P](): def foo4[**P, **Q = P]():
reveal_type(P) # revealed: typing.ParamSpec reveal_type(P) # revealed: ParamSpec
reveal_type(Q) # revealed: typing.ParamSpec reveal_type(Q) # revealed: ParamSpec
``` ```
Other values are invalid. Other values are invalid.

View File

@ -17,7 +17,7 @@ instances of `typing.TypeVar`, just like legacy type variables.
```py ```py
def f[T](): def f[T]():
reveal_type(type(T)) # revealed: <class 'TypeVar'> reveal_type(type(T)) # revealed: <class 'TypeVar'>
reveal_type(T) # revealed: typing.TypeVar reveal_type(T) # revealed: TypeVar
reveal_type(T.__name__) # revealed: Literal["T"] reveal_type(T.__name__) # revealed: Literal["T"]
``` ```
@ -33,7 +33,7 @@ python-version = "3.13"
```py ```py
def f[T = int](): def f[T = int]():
reveal_type(type(T)) # revealed: <class 'TypeVar'> reveal_type(type(T)) # revealed: <class 'TypeVar'>
reveal_type(T) # revealed: typing.TypeVar reveal_type(T) # revealed: TypeVar
reveal_type(T.__default__) # revealed: int reveal_type(T.__default__) # revealed: int
reveal_type(T.__bound__) # revealed: None reveal_type(T.__bound__) # revealed: None
reveal_type(T.__constraints__) # revealed: tuple[()] reveal_type(T.__constraints__) # revealed: tuple[()]
@ -66,7 +66,7 @@ class Invalid[S = T]: ...
```py ```py
def f[T: int](): def f[T: int]():
reveal_type(type(T)) # revealed: <class 'TypeVar'> reveal_type(type(T)) # revealed: <class 'TypeVar'>
reveal_type(T) # revealed: typing.TypeVar reveal_type(T) # revealed: TypeVar
reveal_type(T.__bound__) # revealed: int reveal_type(T.__bound__) # revealed: int
reveal_type(T.__constraints__) # revealed: tuple[()] reveal_type(T.__constraints__) # revealed: tuple[()]
@ -79,7 +79,7 @@ def g[S]():
```py ```py
def f[T: (int, str)](): def f[T: (int, str)]():
reveal_type(type(T)) # revealed: <class 'TypeVar'> reveal_type(type(T)) # revealed: <class 'TypeVar'>
reveal_type(T) # revealed: typing.TypeVar reveal_type(T) # revealed: TypeVar
reveal_type(T.__constraints__) # revealed: tuple[int, str] reveal_type(T.__constraints__) # revealed: tuple[int, str]
reveal_type(T.__bound__) # revealed: None reveal_type(T.__bound__) # revealed: None

View File

@ -400,7 +400,7 @@ reveal_type(ListOrTuple) # revealed: <types.UnionType special form 'list[T@List
reveal_type(ListOrTupleLegacy) reveal_type(ListOrTupleLegacy)
reveal_type(MyCallable) # revealed: <typing.Callable special form '(**P@MyCallable) -> T@MyCallable'> reveal_type(MyCallable) # revealed: <typing.Callable special form '(**P@MyCallable) -> T@MyCallable'>
reveal_type(AnnotatedType) # revealed: <special form 'typing.Annotated[T@AnnotatedType, <metadata>]'> reveal_type(AnnotatedType) # revealed: <special form 'typing.Annotated[T@AnnotatedType, <metadata>]'>
reveal_type(TransparentAlias) # revealed: typing.TypeVar reveal_type(TransparentAlias) # revealed: TypeVar
reveal_type(MyOptional) # revealed: <types.UnionType special form 'T@MyOptional | None'> reveal_type(MyOptional) # revealed: <types.UnionType special form 'T@MyOptional | None'>
def _( def _(

View File

@ -12,7 +12,7 @@ python-version = "3.12"
```py ```py
type IntOrStr = int | str type IntOrStr = int | str
reveal_type(IntOrStr) # revealed: typing.TypeAliasType reveal_type(IntOrStr) # revealed: TypeAliasType
reveal_type(IntOrStr.__name__) # revealed: Literal["IntOrStr"] reveal_type(IntOrStr.__name__) # revealed: Literal["IntOrStr"]
x: IntOrStr = 1 x: IntOrStr = 1
@ -205,7 +205,7 @@ from typing_extensions import TypeAliasType, Union
IntOrStr = TypeAliasType("IntOrStr", Union[int, str]) IntOrStr = TypeAliasType("IntOrStr", Union[int, str])
reveal_type(IntOrStr) # revealed: typing.TypeAliasType reveal_type(IntOrStr) # revealed: TypeAliasType
reveal_type(IntOrStr.__name__) # revealed: Literal["IntOrStr"] reveal_type(IntOrStr.__name__) # revealed: Literal["IntOrStr"]

View File

@ -13,7 +13,7 @@ diagnostic message for `invalid-exception-caught` expects to construct `typing.P
def foo[**P]() -> None: def foo[**P]() -> None:
try: try:
pass pass
# error: [invalid-exception-caught] "Invalid object caught in an exception handler: Object has type `typing.ParamSpec`" # error: [invalid-exception-caught] "Invalid object caught in an exception handler: Object has type `ParamSpec`"
except P: except P:
pass pass
``` ```

View File

@ -2358,7 +2358,7 @@ impl<'db> FmtDetailed<'db> for DisplayKnownInstanceRepr<'db> {
.fmt_detailed(f)?; .fmt_detailed(f)?;
f.write_str("'>") f.write_str("'>")
} else { } else {
f.with_type(ty).write_str("typing.TypeAliasType") f.with_type(ty).write_str("TypeAliasType")
} }
} }
// This is a legacy `TypeVar` _outside_ of any generic class or function, so we render // This is a legacy `TypeVar` _outside_ of any generic class or function, so we render
@ -2366,9 +2366,9 @@ impl<'db> FmtDetailed<'db> for DisplayKnownInstanceRepr<'db> {
// have a `Type::TypeVar(_)`, which is rendered as the typevar's name. // have a `Type::TypeVar(_)`, which is rendered as the typevar's name.
KnownInstanceType::TypeVar(typevar_instance) => { KnownInstanceType::TypeVar(typevar_instance) => {
if typevar_instance.kind(self.db).is_paramspec() { if typevar_instance.kind(self.db).is_paramspec() {
f.with_type(ty).write_str("typing.ParamSpec") f.with_type(ty).write_str("ParamSpec")
} else { } else {
f.with_type(ty).write_str("typing.TypeVar") f.with_type(ty).write_str("TypeVar")
} }
} }
KnownInstanceType::Deprecated(_) => f.write_str("warnings.deprecated"), KnownInstanceType::Deprecated(_) => f.write_str("warnings.deprecated"),

View File

@ -222,14 +222,14 @@ fn pep695_type_params() {
); );
}; };
check_typevar("T", "typing.TypeVar", None, None, None); check_typevar("T", "TypeVar", None, None, None);
check_typevar("U", "typing.TypeVar", Some("A"), None, None); check_typevar("U", "TypeVar", Some("A"), None, None);
check_typevar("V", "typing.TypeVar", None, Some(&["A", "B"]), None); check_typevar("V", "TypeVar", None, Some(&["A", "B"]), None);
check_typevar("W", "typing.TypeVar", None, None, Some("A")); check_typevar("W", "TypeVar", None, None, Some("A"));
check_typevar("X", "typing.TypeVar", Some("A"), None, Some("A1")); check_typevar("X", "TypeVar", Some("A"), None, Some("A1"));
// a typevar with less than two constraints is treated as unconstrained // a typevar with less than two constraints is treated as unconstrained
check_typevar("Y", "typing.TypeVar", None, None, None); check_typevar("Y", "TypeVar", None, None, None);
} }
/// Test that a symbol known to be unbound in a scope does not still trigger cycle-causing /// Test that a symbol known to be unbound in a scope does not still trigger cycle-causing