mirror of
https://github.com/astral-sh/ruff
synced 2026-01-21 13:30:49 -05:00
[ty] fix display of top ParamSpec specialization (#22227)
## Summary I only noticed this in the ecosystem report of https://github.com/astral-sh/ruff/pull/22213 after merging it. The change to displaying `Top[]` wrapper around the entire signature instead of just the parameters had the side effect of not showing it at all when displaying a top ParamSpec specialization. This PR fixes that. Marking internal since this is a fixup of a not-released PR. ## Test Plan Added mdtest that fails without this PR.
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
# Display of callable types
|
||||
|
||||
## Parenthesizing callables
|
||||
|
||||
### Simple
|
||||
|
||||
We parenthesize callable types when they appear inside more complex types, to disambiguate:
|
||||
|
||||
```py
|
||||
@@ -9,11 +13,13 @@ def f(x: Callable[[], str] | Callable[[int], str]):
|
||||
reveal_type(x) # revealed: (() -> str) | ((int, /) -> str)
|
||||
```
|
||||
|
||||
### Overloaded
|
||||
|
||||
We don't parenthesize display of an overloaded callable, since it is already wrapped in
|
||||
`Overload[...]`:
|
||||
|
||||
```py
|
||||
from typing import overload
|
||||
from typing import overload, Callable
|
||||
from ty_extensions import CallableTypeOf
|
||||
|
||||
@overload
|
||||
@@ -28,11 +34,36 @@ def _(flag: bool, c: CallableTypeOf[f]):
|
||||
reveal_type(x) # revealed: Overload[(x: int) -> bool, (x: str) -> str] | Literal[True]
|
||||
```
|
||||
|
||||
### Top
|
||||
|
||||
And we don't parenthesize the top callable, since it is wrapped in `Top[...]`:
|
||||
|
||||
```py
|
||||
from typing import Callable
|
||||
from ty_extensions import Top
|
||||
|
||||
def f(x: Top[Callable[..., str]] | Callable[[int], int]):
|
||||
reveal_type(x) # revealed: Top[(...) -> str] | ((int, /) -> int)
|
||||
```
|
||||
|
||||
## Top ParamSpec
|
||||
|
||||
```toml
|
||||
[environment]
|
||||
python-version = "3.12"
|
||||
```
|
||||
|
||||
We wrap the signature of a top ParamSpec with `Top[...]`:
|
||||
|
||||
```py
|
||||
from typing import Callable
|
||||
|
||||
class C[**P]:
|
||||
def __init__(self, f: Callable[P, object]) -> None:
|
||||
self.f = f
|
||||
|
||||
def _(x: object):
|
||||
if callable(x):
|
||||
c = C(x)
|
||||
reveal_type(c) # revealed: C[Top[(...)]]
|
||||
```
|
||||
|
||||
@@ -1600,10 +1600,16 @@ impl<'db> FmtDetailed<'db> for DisplayCallableType<'_, 'db> {
|
||||
match self.signatures.overloads.as_slice() {
|
||||
[signature] => {
|
||||
if matches!(self.kind, CallableTypeKind::ParamSpecValue) {
|
||||
if signature.parameters().is_top() {
|
||||
f.write_str("Top[")?;
|
||||
}
|
||||
signature
|
||||
.parameters()
|
||||
.display_with(self.db, self.settings.clone())
|
||||
.fmt_detailed(f)?;
|
||||
if signature.parameters().is_top() {
|
||||
f.write_str("]")?;
|
||||
}
|
||||
} else {
|
||||
signature
|
||||
.display_with(self.db, self.settings.clone())
|
||||
|
||||
Reference in New Issue
Block a user