Bug report
Bug description:
get_annotations(obj, format=Format.STRING) stringifies annotations by running __annotate__ under a _Stringifier fake-globals environment. That works for names and overloadable operators, but breaks for annotations that build a real object the stringifier can't proxy — comprehensions, lambdas, and generator expressions:
from annotationlib import get_annotations, Format
def f(x: {k: v for k, v in items}): pass
get_annotations(f, format=Format.STRING)
# ValueError: not enough values to unpack (expected 2, got 1) -- get_annotations crashes
def g(x: lambda q: q): pass
get_annotations(g, format=Format.STRING)
# {'x': '<function <lambda> at 0x...>'} -- invalid, non-deterministic (leaks an address)
def h(x: (w for w in seq)): pass
get_annotations(h, format=Format.STRING)
# {'x': '<generator object <genexpr> at 0x...>'}
- A comprehension annotation makes the fake-globals run itself raise (unpacking a
_Stringifier), so get_annotations raises a confusing ValueError — a problem for any tool that runs it over arbitrary third-party code.
- lambda / generator-expression annotations fall through
_stringify_single to repr(anno), giving non-reparsable output with a memory address.
Boolean operators (or/and/not, ternary) can't be stringified either, but those are understood best-effort limitations; a crash and address-leaking output are not.
CPython versions tested on:
CPython main
Operating systems tested on:
Linux, macOS
Bug report
Bug description:
get_annotations(obj, format=Format.STRING)stringifies annotations by running__annotate__under a_Stringifierfake-globals environment. That works for names and overloadable operators, but breaks for annotations that build a real object the stringifier can't proxy — comprehensions, lambdas, and generator expressions:_Stringifier), soget_annotationsraises a confusingValueError— a problem for any tool that runs it over arbitrary third-party code._stringify_singletorepr(anno), giving non-reparsable output with a memory address.Boolean operators (
or/and/not, ternary) can't be stringified either, but those are understood best-effort limitations; a crash and address-leaking output are not.CPython versions tested on:
CPython main
Operating systems tested on:
Linux, macOS