[ty] Improve rendering of default values for function args (#22010)

## Summary

We're actually quite good at computing this but the main issue is just
that we compute it at the type-level and so wrap it in `Literal[...]`.
So just special-case the rendering of these to omit `Literal[...]` and
fallback to `...` in cases where the thing we'll show is probably
useless (i.e. `x: str = str`).

Fixes https://github.com/astral-sh/ty/issues/1882
This commit is contained in:
Aria Desires
2025-12-16 13:39:19 -05:00
committed by GitHub
parent 2214a46139
commit ad3de4e488
20 changed files with 93 additions and 71 deletions

View File

@@ -1838,15 +1838,39 @@ impl<'db> FmtDetailed<'db> for DisplayParameter<'_, 'db> {
}
}
// Default value can only be specified if `name` is given.
if let Some(default_ty) = self.param.default_type() {
if let Some(default_type) = self.param.default_type() {
if self.param.annotated_type().is_some() {
f.write_str(" = ")?;
} else {
f.write_str("=")?;
}
default_ty
.display_with(self.db, self.settings.clone())
.fmt_detailed(f)?;
match default_type {
Type::IntLiteral(_)
| Type::BooleanLiteral(_)
| Type::StringLiteral(_)
| Type::EnumLiteral(_)
| Type::BytesLiteral(_) => {
// For Literal types display the value without `Literal[..]` wrapping
let representation =
default_type.representation(self.db, self.settings.clone());
representation.fmt_detailed(f)?;
}
Type::NominalInstance(instance) => {
// Some key default types like `None` are worth showing
let class = instance.class(self.db);
match (class, class.known(self.db)) {
(_, Some(KnownClass::NoneType)) => {
f.with_type(default_type).write_str("None")?;
}
(_, Some(KnownClass::NoDefaultType)) => {
f.with_type(default_type).write_str("NoDefault")?;
}
_ => f.write_str("...")?,
}
}
_ => f.write_str("...")?,
}
}
} else if let Some(ty) = self.param.annotated_type() {
// This case is specifically for the `Callable` signature where name and default value
@@ -2598,7 +2622,7 @@ mod tests {
],
Some(Type::none(&db))
),
@"(x=int, y: str = str) -> None"
@"(x=..., y: str = ...) -> None"
);
// All positional only parameters.
@@ -2683,9 +2707,7 @@ mod tests {
],
Some(KnownClass::Bytes.to_instance(&db))
),
@"(a, b: int, c=Literal[1], d: int = Literal[2], \
/, e=Literal[3], f: int = Literal[4], *args: object, \
*, g=Literal[5], h: int = Literal[6], **kwargs: str) -> bytes"
@"(a, b: int, c=1, d: int = 2, /, e=3, f: int = 4, *args: object, *, g=5, h: int = 6, **kwargs: str) -> bytes"
);
}
@@ -2727,8 +2749,8 @@ mod tests {
),
@r"
(
x=int,
y: str = str
x=...,
y: str = ...
) -> None
"
);
@@ -2843,15 +2865,15 @@ mod tests {
(
a,
b: int,
c=Literal[1],
d: int = Literal[2],
c=1,
d: int = 2,
/,
e=Literal[3],
f: int = Literal[4],
e=3,
f: int = 4,
*args: object,
*,
g=Literal[5],
h: int = Literal[6],
g=5,
h: int = 6,
**kwargs: str
) -> bytes
"