[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:
@@ -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
|
||||
"
|
||||
|
||||
Reference in New Issue
Block a user