Canonicalize nested template format specs in annotations (#9076)

Use the existing f-string body unparser for template interpolation format specs, while preserving the outer interpolation source text. Add compile-only Python annotation-constant coverage.

Assisted-by: OpenAI Codex:model identifier unavailable
This commit is contained in:
youknowdot authored and GitHub committed 2026-10-11 09:17:01 +09:00
1 parent 1cbae85e20
commit 8d27253fa2
2 files changed
+13 -1

No files matched your search

+1 -1
View File
@@ -814,7 +814,7 @@ impl<'a, 'b, 'c> Unparser<'a, 'b, 'c> {
if let Some(format_spec) = &interpolation.format_spec {
self.p(":")?;
self.unparse_tstring_body(&format_spec.elements)?;
self.unparse_fstring_body(&format_spec.elements)?;
}
self.p("}")
@@ -8,3 +8,15 @@ hints = get_type_hints(func)
# The order of type hints matters for certain functions
# e.g. functools.singledispatch
assert list(hints.items()) == [('s', str), ('return', int)]
# Template format specs use canonical expression text inside future annotations.
for template, expected in (
("t'{value:04}'", "t'{value:04}'"),
("t'{value:{(width)}}'", "t'{value:{width}}'"),
("t'{(value):{(width)!r}}'", "t'{(value):{width!r}}'"),
):
annotation_code = compile(
"from __future__ import annotations\nx: " + template, "<test>", "exec"
)
assert expected in annotation_code.co_consts