Skip to content

Commit 8d27253

Browse files
authored
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
1 parent 1cbae85 commit 8d27253

2 files changed

Lines changed: 13 additions & 1 deletion

File tree

‎crates/codegen/src/unparse.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -814,7 +814,7 @@ impl<'a, 'b, 'c> Unparser<'a, 'b, 'c> {
814814

815815
if let Some(format_spec) = &interpolation.format_spec {
816816
self.p(":")?;
817-
self.unparse_tstring_body(&format_spec.elements)?;
817+
self.unparse_fstring_body(&format_spec.elements)?;
818818
}
819819

820820
self.p("}")

‎extra_tests/snippets/syntax_annotations.py‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,15 @@ def func(s: str) -> int:
88
# The order of type hints matters for certain functions
99
# e.g. functools.singledispatch
1010
assert list(hints.items()) == [('s', str), ('return', int)]
11+
12+
13+
# Template format specs use canonical expression text inside future annotations.
14+
for template, expected in (
15+
("t'{value:04}'", "t'{value:04}'"),
16+
("t'{value:{(width)}}'", "t'{value:{width}}'"),
17+
("t'{(value):{(width)!r}}'", "t'{(value):{width!r}}'"),
18+
):
19+
annotation_code = compile(
20+
"from __future__ import annotations\nx: " + template, "<test>", "exec"
21+
)
22+
assert expected in annotation_code.co_consts

0 commit comments

Comments
 (0)