python/cpython · error · ValueError

The VALUE_WITH_FAKE_GLOBALS format is for internal use only

Error message

The VALUE_WITH_FAKE_GLOBALS format is for internal use only

What it means

call_annotate_function() explicitly rejects Format.VALUE_WITH_FAKE_GLOBALS. That format exists only for CPython-internal use: it runs the annotate function in a sandbox where global name lookups return sentinel objects, and it is not part of the public annotation contract. Passing it as a caller is treated as API misuse and raises ValueError.

Source

Thrown at Lib/annotationlib.py:716

    can be called with any of the format arguments in the Format enum, but
    compiler-generated __annotate__ functions only support the VALUE format.
    This function provides additional functionality to call __annotate__
    functions with the FORWARDREF and STRING formats.

    *annotate* must be an __annotate__ function, which takes a single argument
    and returns a dict of annotations.

    *format* must be a member of the Format enum or one of the corresponding
    integer values.

    *owner* can be the object that owns the annotations (i.e., the module,
    class, or function that the __annotate__ function derives from). With the
    FORWARDREF format, it is used to provide better evaluation capabilities
    on the generated ForwardRef objects.

    """
    if format == Format.VALUE_WITH_FAKE_GLOBALS:
        raise ValueError("The VALUE_WITH_FAKE_GLOBALS format is for internal use only")
    try:
        return annotate(format)
    except NotImplementedError:
        pass
    if format == Format.STRING:
        # STRING 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.

        # Attempt to call with VALUE_WITH_FAKE_GLOBALS to check if it is implemented
        # See: https://github.com/python/cpython/issues/138764
        # Only fail on NotImplementedError
        try:
            annotate(Format.VALUE_WITH_FAKE_GLOBALS)

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Use Format.VALUE, Format.STRING, or Format.FORWARDREF instead — these are the public formats.
  2. If you need string-like capture of unresolved names, use Format.STRING; for lazy evaluation use FORWARDREF.
  3. Filter VALUE_WITH_FAKE_GLOBALS out when iterating over Format members.

Example fix

# before
ann = annotationlib.call_annotate_function(func.__annotate__, format=Format.VALUE_WITH_FAKE_GLOBALS)

# after
ann = annotationlib.call_annotate_function(func.__annotate__, format=Format.FORWARDREF)
Defensive patterns

Strategy: validation

Validate before calling

from annotationlib import Format

PUBLIC_FORMATS = {Format.VALUE, Format.STRING, Format.FORWARDREF}

def check_format(fmt):
    if fmt not in PUBLIC_FORMATS:
        raise ValueError(f'use one of {PUBLIC_FORMATS}, not {fmt!r}')

Type guard

from annotationlib import Format

def is_public_format(fmt) -> bool:
    return fmt in (Format.VALUE, Format.STRING, Format.FORWARDREF)

Try / catch

try:
    ann = annotationlib.call_annotate_function(annotate, format=fmt)
except ValueError as e:
    if 'internal use only' in str(e):
        fmt = Format.STRING  # fall back to a public format
        ann = annotationlib.call_annotate_function(annotate, format=fmt)
    else:
        raise

Prevention

When it happens

Trigger: annotationlib.call_annotate_function(func, format=Format.VALUE_WITH_FAKE_GLOBALS); passing the raw integer value of that enum member; copy-pasting internal CPython code that uses the format into application code.

Common situations: Developers exploring PEP 649 internals and reusing private formats; code that iterates over all Format enum members and calls the API with each; version upgrades where the enum gained new members not intended for public use.

Related errors


AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14). Data as JSON: /api/errors/b7aa4741ad4c1da3. Report an issue: GitHub.