Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 33.9k
Description
Bug report
Bug description:
While looking into #125618 I ran into this case.
Using the union syntax gives a ForwardRef that can't be evaluated as the class that can be evaluated gets converted into its repr via ast.Constant. Using the typing.Union class however gives a proper union object where only the undefined value is a forwardref.
str | undefined->ForwardRef("<class 'str'> | undefined")Union[str, undefined]->str | ForwardRef("undefined")
Example:
fromannotationlibimportget_annotations, FormatfromtypingimportUnionclassDifferentUnions: attrib: str|undefinedother_attrib: Union[str, undefined] different_unions=get_annotations(DifferentUnions, format=Format.FORWARDREF) print(different_unions)Formatted Output:
{'attrib': ForwardRef("<class 'str'> | undefined", is_class=True, owner=<class'__main__.DifferentUnions'>), 'other_attrib': str|ForwardRef('undefined', is_class=True, owner=<class'__main__.DifferentUnions'>) }One possible solution to this is to add a create_unions attribute to the _StringifierDict. If this is True then the __or__ and __ror__ methods should create types.UnionType instances instead of calling __make_new. This is False for Format.STRING in order to keep a | b in the reproduction in that case.
I already have a branch with this approach so I can make a PR.
Doing this will break the current test_nonexistent_attribute ForwardRef test as some | obj would evaluate to ForwardRef('some') | ForwardRef('obj') instead of ForwardRef('some | obj') but I think this is probably correct and the test should be changed.
CPython versions tested on:
CPython main branch
Operating systems tested on:
No response