← 输入框|github.com|刷新
Skip to content

gh-160766: Handle nested annotated and generic aliases that contain forward references in annotations - #160769

Open
DavidCEllis wants to merge 3 commits into
python:mainfrom
DavidCEllis:fix-nested-forwardref-annos
Open

DavidCEllis wants to merge 3 commits into
python:mainfrom
DavidCEllis:fix-nested-forwardref-annos

Conversation

@DavidCEllis

@DavidCEllis DavidCEllis commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

This adds another special case to _Stringifier.__convert_to_ast to handle types.GenericAlias and typing.Annotated similar to the handling of list, set, tuple, dict that constructs the ast to rebuild the GenericAlias or Annotated object.

This is to prevent the ForwardRef objects from becoming "hidden" inside the GenericAlias or Annotated objects.

For GenericAlias an ast.Call node is created to reconstruct the GenericAlias as there's no guarantee it was created through subscripting. The call is converted back to subscript format when evaluating the ForwardRef in STRING format in order to match the repr of GenericAlias objects.

For Annotated, subscripting is used. Are there any other types that need to be handled?

from annotationlib import get_annotations, Format

class X:
    a: Y[list[Z]]

# Get annotations here to get the ForwardRef
anno = get_annotations(X, format=Format.FORWARDREF)['a']

class Y[T]:
    pass

class Z:
    pass

print(anno.evaluate(format=Format.STRING))
print(anno.evaluate(format=Format.VALUE))

Main:

Y[list[ForwardRef('Z', is_class=True, owner=<class '__main__.X'>)]]
__main__.Y[list[ForwardRef('Z', is_class=True, owner=<class '__main__.X'>)]]

PR:

Y[list[Z]]
__main__.Y[list[__main__.Z]]

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant