Skip to content

t-strings: AST unparsing does not reproduce original formatting #133581

Closed

Description

@JelleZijlstra

Bug report

Bug description:

The AST unparsing of Interpolation objects does not reproduce formatting within interpolations.

This is true both for ast.unparse in Python:

>>> ast.unparse(ast.parse('t"{a   + b}"'))
"t'{a + b}'"

And for the C unparse that is used by from __future__ import annotations:

>>> ns = {}
>>> exec("""
... from __future__ import annotations
... def f(x: t"{a    + b}"): ...
... """, ns)
>>> ns["f"].__annotations__
{'x': "t'{a + b}'"}

In general, we can't recover the original source exactly, but in this case we do have the original source available:

>>> ast.parse('t"{a   + b}"').body[0].value.values[0].str
'a   + b'

Let's use it.

CPython versions tested on:

3.14

Operating systems tested on:

No response

Linked PRs

Activity

  1. added
    type-bugAn unexpected behavior, bug, or error
    3.14bugs and security fixes
    on May 7, 2025
  2. added
    stdlibStandard Library Python modules in the Lib/ directory
    on May 7, 2025
  3. JelleZijlstra commented on May 7, 2025

    @JelleZijlstra
    MemberAuthor

    This leads to AST roundtrip failures (showing up in test cases in #133553).

  4. JelleZijlstra commented on May 7, 2025

    @JelleZijlstra
    MemberAuthor
  5. lysnikolaou commented on May 7, 2025

    @lysnikolaou
    Member

    Hmm, what exactly is failing in the AST roundtrip tests? test_unparse only checks ASTs, which should be the same for all of these, right?

  6. JelleZijlstra commented on May 7, 2025

    @JelleZijlstra
    MemberAuthor

    The AST changes on roundtrip because the AST for an interpolation object includes the raw text, which changes.

  7. lysnikolaou commented on May 7, 2025

    @lysnikolaou
    Member

    Oh right, I hit that while working on the PEP PR and thought I'd implemented skipping checking ast.Interpolation.str in test_unparse.

    Not sure whether we should be using it for test_unparse, that'd be breaking assumptions for the formatting of the code. For example, a + b roundtrips to a + b. Why should t-string be different in that regard?

  8. JelleZijlstra commented on May 7, 2025

    @JelleZijlstra
    MemberAuthor

    Why should t-string be different in that regard?

    Because in t-strings the original source code is part of the AST, and in the rest of the grammar it isn't.

    In general I feel ast.unparse(ast.parse(...)) should roundtrip as much as possible, to the extent that the original source code is still recoverable from the AST.

  9. added a commit that references this issue on May 8, 2025
  10. added a commit that references this issue on May 8, 2025
  11. added 2 commits that reference this issue on May 8, 2025
  12. added a commit that references this issue on May 9, 2025
  13. added a commit that references this issue on May 9, 2025
  14. added a commit that references this issue on May 9, 2025
  15. lysnikolaou commented on May 9, 2025

    @lysnikolaou
    Member

    This has been fixed.

  16. added 2 commits that reference this issue on Jul 12, 2025
  17. added 2 commits that reference this issue on Aug 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.14bugs and security fixesstdlibStandard Library Python modules in the Lib/ directorytopic-parsertype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions