diff --git a/crates/codegen/src/unparse.rs b/crates/codegen/src/unparse.rs index 3ada6644cbb..868f1b1bab1 100644 --- a/crates/codegen/src/unparse.rs +++ b/crates/codegen/src/unparse.rs @@ -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("}") diff --git a/extra_tests/snippets/syntax_annotations.py b/extra_tests/snippets/syntax_annotations.py index 0f78bdc2be1..9b7d0c0ce89 100644 --- a/extra_tests/snippets/syntax_annotations.py +++ b/extra_tests/snippets/syntax_annotations.py @@ -8,3 +8,15 @@ def func(s: str) -> int: # 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, "", "exec" + ) + assert expected in annotation_code.co_consts