-
-
Notifications
You must be signed in to change notification settings - Fork 33.1k
Description
Bug report
Bug description:
The documentation for annotate functions only requires that they implement format.VALUE
.
However if a user created annotate
function does not implement the other formats, it will likely behave badly when accessed through call_annotate_function
using STRING
or FORWARDREF
formats.
Example:
from annotationlib import call_annotate_function, Format
def annotate(format, /):
if format == Format.VALUE:
print("pass")
return {}
else:
print("fail")
raise NotImplementedError(format)
call_annotate_function(annotate, Format.STRING)
Output:
fail
{}
The "fail" is expected, as annotate(Format.STRING)
is called first and is clearly not supported.
The empty dictionary is returned because annotate(Format.VALUE_WITH_FAKE_GLOBALS)
is called, but in a fake globals context where the globals namespace is empty. Format.VALUE
in this context becomes a _Stringifier
, so format == Format.VALUE
becomes a _Stringifier
which evaluates to True
. print
is also a _Stringifier
which is why "pass" is never printed.
Note that if you change the condition to check format == Format.VALUE_WITH_FAKE_GLOBALS
first, the condition will pass (for the wrong reason) but the function will fail with a TypeError
instead, because NotImplementedError
is also a _Stringifier
and exceptions must derive from BaseException
.
Format.FORWARDREF
should probably check for NotImplementedError
on the first call where globals do exist and reraise in that case, I don't see a way of handling Format.STRING
without an extra check before it calls the function in the fake globals environment.
CPython versions tested on:
3.14, CPython main branch
Operating systems tested on:
No response
Linked PRs
- gh-138764: annotationlib - Check if the
VALUE_WITH_FAKE_GLOBALS
format is implemented before calling an__annotate__
function with empty fake globals #138788 - gh-138764: annotationlib - Make
call_annotate_function
fallback to usingVALUE
annotations if both the requested format andVALUE_WITH_FAKE_GLOBALS
are not implemented #138803