Skip to content

How to convert annotations to Format.SOURCE in __annotate__?#124412

@sobolevn

Description

@sobolevn

Feature or enhancement

Let's say you have a dict of some custom annotations like I have in #122262

How users are expected to convert say an annotation dict of {'user': CustomUser[AuthToken], 'auth_callback': Callable[[CustomUser[T]], T]} to string?

There are several ways right now:

  1. repr for simple types, which might not work for complex ones
  2. ifformat==Format.SOURCE:
    # SOURCE is implemented by calling the annotate function in a special
    # environment where every name lookup results in an instance of _Stringifier.
    # _Stringifier supports every dunder operation and returns a new _Stringifier.
    # At the end, we get a dictionary that mostly contains _Stringifier objects (or
    # possibly constants if the annotate function uses them directly). We then
    # convert each of those into a string to get an approximation of the
    # original source.
    globals=_StringifierDict({})
    ifannotate.__closure__:
    freevars=annotate.__code__.co_freevars
    new_closure= []
    fori, cellinenumerate(annotate.__closure__):
    ifi<len(freevars):
    name=freevars[i]
    else:
    name="__cell__"
    fwdref=_Stringifier(ast.Name(id=name))
    new_closure.append(types.CellType(fwdref))
    closure=tuple(new_closure)
    else:
    closure=None
    func=types.FunctionType(
    annotate.__code__,
    globals,
    closure=closure,
    argdefs=annotate.__defaults__,
    kwdefaults=annotate.__kwdefaults__,
    )
    annos=func(Format.VALUE)
    if_is_evaluate:
    returnannosifisinstance(annos, str) elserepr(annos)
    return{
    key: valifisinstance(val, str) elserepr(val)
    forkey, valinannos.items()
    }
    but, it requires complex annotate object
  3. cpython/Lib/typing.py

    Lines 2955 to 2956 in 536bc8a

    def_convert_to_source(types):
    return{n: tifisinstance(t, str) else_type_repr(t) forn, tintypes.items()}
    but it is a private API

I propose adding a public and documented API for that.

Linked PRs

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions