Skip to content

gh-157056: Fix STRING format for comprehension and lambda annotations - #157151

Closed
KingLizard1020 wants to merge 11 commits into
python:mainfrom
KingLizard1020:gh-157056-annotationlib-string
Closed

gh-157056: Fix STRING format for comprehension and lambda annotations#157151
KingLizard1020 wants to merge 11 commits into
python:mainfrom
KingLizard1020:gh-157056-annotationlib-string

Conversation

@KingLizard1020

@KingLizard1020 KingLizard1020 commented Sep 8, 2026

Copy link
Copy Markdown

Fixes #157056

annotationlib.get_annotations(..., format=Format.STRING) failed in two ways for annotations that are not simple name lookups:

  1. Dict comprehensions such as {k: v for k, v in items} raised ValueError: not enough values to unpack, because fake-globals _Stringifier.__iter__ yields a single starred node while the comprehension unpacks a pair.
  2. Lambda and generator-expression annotations (lambda q: q, (w for w in seq)) were stringified with repr(), which embeds a memory address.

This change recovers the original annotation text from the owner's source AST when fake-globals evaluation raises ValueError, and when the evaluated value is a runtime-constructed function/generator. _stringify_single now uses type_repr instead of repr, and type_repr handles generator/coroutine objects via __qualname__ so STRING output does not include 0x... addresses.

inspect is imported lazily inside the source-recovery helper because inspect imports annotationlib.

Tests: ./python -m test test_annotationlib test_inspect test_typing (debug build).

…ations

get_annotations(..., format=Format.STRING) raised ValueError on dict
comprehension annotations because fake-globals iteration cannot unpack
pair targets. Recover the annotation text from source in that case.

Lambda and generator-expression annotations are syntax, so they were
stringified with repr() and leaked a memory address. Prefer the source
text when available, and use a stable type_repr() otherwise.
…ations

get_annotations(..., format=Format.STRING) raised ValueError on dict
comprehension annotations because fake-globals iteration cannot unpack
pair targets. Recover the annotation text from source in that case.

Lambda and generator-expression annotations are syntax, so they were
stringified with repr() and leaked a memory address. Prefer the source
text when available, and use a stable type_repr() otherwise.
…ations

get_annotations(..., format=Format.STRING) raised ValueError on dict
comprehension annotations because fake-globals iteration cannot unpack
pair targets. Recover the annotation text from source in that case.

Lambda and generator-expression annotations are syntax, so they were
stringified with repr() and leaked a memory address. Prefer the source
text when available, and use a stable type_repr() otherwise.
…ations

get_annotations(..., format=Format.STRING) raised ValueError on dict
comprehension annotations because fake-globals iteration cannot unpack
pair targets. Recover the annotation text from source in that case.

Lambda and generator-expression annotations are syntax, so they were
stringified with repr() and leaked a memory address. Prefer the source
text when available, and use a stable type_repr() otherwise.
@python-cla-bot

python-cla-bot Bot commented Sep 8, 2026

Copy link
Copy Markdown

All commit authors signed the Contributor License Agreement.

CLA signed

@KingLizard1020
KingLizard1020 marked this pull request as draft September 8, 2026 01:37
@KingLizard1020

Copy link
Copy Markdown
Author

Closing this draft. The test file on this branch was accidentally truncated. The complete fix is in a follow-up PR from gh-157056-string-format.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

annotationlib: get_annotations(format=STRING) fails on a comprehension annotation

1 participant