[ty] don't expand type aliases via type mappings unless necessary (#22241)
## Summary
`apply_type_mapping` always expands type aliases and operates on the
resulting types, which can lead to cluttered results due to excessive
type alias expansion in places where it is not actually needed.
Specifically, type aliases are expanded when displaying method
signatures, because we use `TypeMapping::BindSelf` to get the method
signature.
```python
type Scalar = int | float
type Array1d = list[Scalar] | tuple[Scalar]
def f(x: Scalar | Array1d) -> None: pass
reveal_type(f) # revealed: def f(x: Scalar | Array1d) -> None
class Foo:
def f(self, x: Scalar | Array1d) -> None: pass
# should be `bound method Foo.f(x: Scalar | Array1d) -> None`
reveal_type(Foo().f) # revealed: bound method Foo.f(x: int | float | list[int | float] | tuple[int | float]) -> None
```
In this PR, when type mapping is performed on a type alias, the
expansion result without type mapping is compared with the expansion
result after type mapping, and if the two are equivalent, the expansion
is deemed redundant and canceled.
## Test Plan
mdtest updated
This commit is contained in:
committed by
GitHub
parent
8716b4e230
commit
c429ef8407
@@ -310,7 +310,7 @@ x11: list[Literal[1] | Literal[2] | Literal[3]] = [1, 2, 3]
|
||||
reveal_type(x11) # revealed: list[Literal[1, 2, 3]]
|
||||
|
||||
x12: Y[Y[Literal[1]]] = [[1]]
|
||||
reveal_type(x12) # revealed: list[list[Literal[1]]]
|
||||
reveal_type(x12) # revealed: list[Y[Literal[1]]]
|
||||
|
||||
x13: list[tuple[Literal[1], Literal[2], Literal[3]]] = [(1, 2, 3)]
|
||||
reveal_type(x13) # revealed: list[tuple[Literal[1], Literal[2], Literal[3]]]
|
||||
|
||||
@@ -67,3 +67,53 @@ def _(x: object):
|
||||
c = C(x)
|
||||
reveal_type(c) # revealed: C[Top[(...)]]
|
||||
```
|
||||
|
||||
## Type aliases are not expanded unless necessary
|
||||
|
||||
```toml
|
||||
[environment]
|
||||
python-version = "3.12"
|
||||
```
|
||||
|
||||
```py
|
||||
type Scalar = int | float
|
||||
type Array1d = list[Scalar] | tuple[Scalar]
|
||||
|
||||
def f(x: Scalar | Array1d) -> None:
|
||||
pass
|
||||
|
||||
reveal_type(f) # revealed: def f(x: Scalar | Array1d) -> None
|
||||
|
||||
class Foo:
|
||||
def f(self, x: Scalar | Array1d) -> None:
|
||||
pass
|
||||
|
||||
reveal_type(Foo().f) # revealed: bound method Foo.f(x: Scalar | Array1d) -> None
|
||||
|
||||
type ArrayNd = Scalar | list[ArrayNd] | tuple[ArrayNd]
|
||||
|
||||
def g(x: Scalar | ArrayNd) -> None:
|
||||
pass
|
||||
|
||||
reveal_type(g) # revealed: def g(x: Scalar | ArrayNd) -> None
|
||||
|
||||
class Bar:
|
||||
def g(self, x: Scalar | ArrayNd) -> None:
|
||||
pass
|
||||
|
||||
# TODO: should be `bound method Bar.g(x: Scalar | ArrayNd) -> None`
|
||||
reveal_type(Bar().g) # revealed: bound method Bar.g(x: Scalar | list[Any] | tuple[Any]) -> None
|
||||
|
||||
type GenericArray1d[T] = list[T] | tuple[T]
|
||||
|
||||
def h(x: Scalar | GenericArray1d[Scalar]) -> None:
|
||||
pass
|
||||
|
||||
reveal_type(h) # revealed: def h(x: Scalar | GenericArray1d[Scalar]) -> None
|
||||
|
||||
class Baz:
|
||||
def h(self, x: Scalar | GenericArray1d[Scalar]) -> None:
|
||||
pass
|
||||
|
||||
reveal_type(Baz().h) # revealed: bound method Baz.h(x: Scalar | GenericArray1d[Scalar]) -> None
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user