Skip to content

annotationlib - call_annotate_function should check VALUE_WITH_FAKE_GLOBALS is implemented before calling in a namespace with empty fake globals #138764

@DavidCEllis

Description

@DavidCEllis

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directorytopic-typingtype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions