Content-Length: 294843 | pFad | https://github.com/python/cpython/issues/138764

05 annotationlib - `call_annotate_function` should check `VALUE_WITH_FAKE_GLOBALS` is implemented before calling in a namespace with empty fake globals · Issue #138764 · python/cpython · GitHub
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









      ApplySandwichStrip

      pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


      --- a PPN by Garber Painting Akron. With Image Size Reduction included!

      Fetched URL: https://github.com/python/cpython/issues/138764

      Alternative Proxies:

      Alternative Proxy

      pFad Proxy

      pFad v3 Proxy

      pFad v4 Proxy