Ast.unparse unnecessarily produces code incompatible with earlier Python versions

Consider the following parse-unparse sequence

import ast

content = """
f"{'.' * 5}"
"""

print(ast.unparse(ast.parse(content)))

The output of this code on Python 3.9 is

f"{'.' * 5}"

On Python 3.11, it’s

f'{'.' * 5}'

The latter output is not compatible with earlier Python versions, e.g., 3.9. Is there a way for unparse to produce better compatible code?

(Note I think you meant Python 3.12, not 3.11?)

In general, I don’t think ast.unparse can guarantee anything about cross-compatible code.

For this specific case, technically speaking, it would be easy. You’d just have to revert some of gh-108469: Update ast.unparse for unescaped quote support from PEP701 [3.12] by tonybaloney · Pull Request #108553 · python/cpython · GitHub. I think it might be too late to change behaviour in Python 3.12 and 3.13 though

I wrote the original quote switching code, so let me know if I can help you

See also `ast.unparse` is needlessly "hip" for f-string quotes in Python 3.12+ · Issue #127975 · python/cpython · GitHub (edit: oh oops, I see that you opened that issue)