{"record":{"id":"d3e811dee3d3a914","repo":"python/cpython","slug":"unsupported-format-format-r","errorCode":null,"errorMessage":"Unsupported format {format!r}","messagePattern":"Unsupported format (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"Lib/annotationlib.py","lineNumber":998,"sourceCode":"            ann = _get_and_call_annotate(obj, format)\n            if ann is None:\n                # If that didn't work either, we have a very weird object: evaluating\n                # __annotations__ threw NameError and there is no __annotate__. In that case,\n                # we fall back to trying __annotations__ again.\n                ann = _get_dunder_annotations(obj)\n        case Format.STRING:\n            # For STRING, we try to call __annotate__\n            ann = _get_and_call_annotate(obj, format)\n            if ann is not None:\n                return dict(ann)\n            # But if we didn't get it, we use __annotations__ instead.\n            ann = _get_dunder_annotations(obj)\n            if ann is not None:\n                return annotations_to_string(ann)\n        case Format.VALUE_WITH_FAKE_GLOBALS:\n            raise ValueError(\"The VALUE_WITH_FAKE_GLOBALS format is for internal use only\")\n        case _:\n            raise ValueError(f\"Unsupported format {format!r}\")\n\n    if ann is None:\n        if isinstance(obj, type) or callable(obj):\n            return {}\n        raise TypeError(f\"{obj!r} does not have annotations\")\n\n    if not ann:\n        return {}\n\n    if not eval_str:\n        return dict(ann)\n\n    if globals is None or locals is None:\n        if isinstance(obj, type):\n            # class\n            obj_globals = None\n            module_name = getattr(obj, \"__module__\", None)\n            if module_name:","sourceCodeStart":980,"sourceCodeEnd":1016,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/annotationlib.py#L980-L1016","documentation":"The wildcard case in get_annotations()'s format match raises ValueError('Unsupported format {format!r}') for anything that is not a known Format member. Unlike the sibling 'Invalid format' check in call_annotate_function, this fires on the public API when the format argument is an invalid integer, an unrelated enum, or an unhashable/odd value that simply matches no case.","triggerScenarios":"get_annotations(obj, format=99); get_annotations(obj, format='string'); passing a custom IntEnum that coincidentally overlaps no case; forwarding a user-supplied format parameter unchecked.","commonSituations":"Configuration-driven format selection parsed from config files as strings or ints; desynchronized enum values between interpreter and library code; typos in keyword arguments.","solutions":["Pass a real Format member (Format.VALUE / STRING / FORWARDREF).","Coerce untrusted input via `Format.try_value(value)` or `Format(value)` inside try/except before calling.","Default the format parameter to Format.VALUE in your own wrappers instead of None passthrough."],"exampleFix":"# before\nfmt = request.args.get('format')  # e.g. 'VALUE' string\nann = get_annotations(obj, format=fmt)  # ValueError: Unsupported format 'VALUE'\n\n# after\nfmt = Format[request.args.get('format', 'VALUE').upper()]\nann = get_annotations(obj, format=fmt)","handlingStrategy":"validation","validationCode":"from annotationlib import Format\n\ndef parse_format(raw):\n    if isinstance(raw, Format):\n        return raw\n    try:\n        return Format(raw)\n    except ValueError:\n        raise ValueError(f'unsupported format {raw!r}; expected one of VALUE, STRING, FORWARDREF')","typeGuard":"from annotationlib import Format\n\ndef is_supported_format(fmt) -> bool:\n    return isinstance(fmt, Format) and fmt in (Format.VALUE, Format.STRING, Format.FORWARDREF)","tryCatchPattern":"try:\n    ann = get_annotations(obj, format=fmt)\nexcept ValueError as e:\n    if 'Unsupported format' in str(e):\n        fmt = Format.VALUE\n        ann = get_annotations(obj, format=fmt)\n    else:\n        raise","preventionTips":["Accept format names as strings from config, map via Format[name.upper()]","Fail fast on unknown format values at config validation time","Do not persist integer enum values across versions"],"tags":["python","annotations","validation","format-enum"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}