RustPython/RustPython · error · ValueError

Unsupported format {format!r}

Error message

Unsupported format {format!r}

What it means

The final `case _` arm of get_annotations()'s format match raises ValueError(f"Unsupported format {format!r}") for any value that is not one of the known Format members. Unlike the sibling 'Invalid format' error in call_annotate_function, this one guards the public get_annotations dispatch.

Source

Thrown at Lib/annotationlib.py:1021

            ann = _get_and_call_annotate(obj, format)
            if ann is None:
                # If that didn't work either, we have a very weird object: evaluating
                # __annotations__ threw NameError and there is no __annotate__. In that case,
                # we fall back to trying __annotations__ again.
                ann = _get_dunder_annotations(obj)
        case Format.STRING:
            # For STRING, we try to call __annotate__
            ann = _get_and_call_annotate(obj, format)
            if ann is not None:
                return dict(ann)
            # But if we didn't get it, we use __annotations__ instead.
            ann = _get_dunder_annotations(obj)
            if ann is not None:
                return annotations_to_string(ann)
        case Format.VALUE_WITH_FAKE_GLOBALS:
            raise ValueError("The VALUE_WITH_FAKE_GLOBALS format is for internal use only")
        case _:
            raise ValueError(f"Unsupported format {format!r}")

    if ann is None:
        if isinstance(obj, type) or callable(obj):
            return {}
        raise TypeError(f"{obj!r} does not have annotations")

    if not ann:
        return {}

    if not eval_str:
        return dict(ann)

    if globals is None or locals is None:
        if isinstance(obj, type):
            # class
            obj_globals = None
            module_name = getattr(obj, "__module__", None)
            if module_name:

View on GitHub (pinned to aaeab4f754)

Solutions

  1. Import and pass the enum: from annotationlib import Format; get_annotations(obj, format=Format.FORWARDREF)
  2. Coerce with Format.try_value(value) before calling, so invalid values fail with your own handling
  3. If format arrives as text, map it explicitly: {'value': Format.VALUE, 'string': Format.STRING, 'forwardref': Format.FORWARDREF}

Example fix

# before
ann = get_annotations(func, format='VALUE')  # ValueError

# after
from annotationlib import Format, get_annotations
ann = get_annotations(func, format=Format.VALUE)
Defensive patterns

Strategy: validation

Validate before calling

from annotationlib import Format

FORMAT_ALIASES = {'value': Format.VALUE, 'string': Format.STRING, 'forwardref': Format.FORWARDREF}

def coerce_format(raw):
    fmt = FORMAT_ALIASES.get(str(raw).lower()) if isinstance(raw, str) else raw
    try:
        return Format.try_value(fmt)
    except (ValueError, TypeError):
        raise ValueError(f'unsupported format {raw!r}') from None

Type guard

from annotationlib import Format

def is_supported_format(value) -> bool:
    return value in (Format.VALUE, Format.STRING, Format.FORWARDREF)

Prevention

When it happens

Trigger: `get_annotations(obj, format=99)`, `format='VALUE'`, or format=None passed positionally by mistake.

Common situations: Passing a string name instead of the enum; sending format over the wire as an int and deserializing without validation; stale constants from an older Python where enum members differed.

Related errors


AI-assisted analysis of RustPython/RustPython@aaeab4f754 (2026-08-17). Data as JSON: /api/errors/ba14abad631942b4. Report an issue: GitHub.