diff options
Diffstat (limited to 'Lib/annotationlib.py')
-rw-r--r-- | Lib/annotationlib.py | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/Lib/annotationlib.py b/Lib/annotationlib.py index 20c9542..a027f4d 100644 --- a/Lib/annotationlib.py +++ b/Lib/annotationlib.py @@ -15,6 +15,8 @@ __all__ = [ "call_evaluate_function", "get_annotate_function", "get_annotations", + "annotations_to_source", + "value_to_source", ] @@ -693,7 +695,7 @@ def get_annotations( return ann # But if we didn't get it, we use __annotations__ instead. ann = _get_dunder_annotations(obj) - return ann + return annotations_to_source(ann) case _: raise ValueError(f"Unsupported format {format!r}") @@ -762,6 +764,33 @@ def get_annotations( return return_value +def value_to_source(value): + """Convert a Python value to a format suitable for use with the SOURCE format. + + This is inteded as a helper for tools that support the SOURCE format but do + not have access to the code that originally produced the annotations. It uses + repr() for most objects. + + """ + if isinstance(value, type): + if value.__module__ == "builtins": + return value.__qualname__ + return f"{value.__module__}.{value.__qualname__}" + if value is ...: + return "..." + if isinstance(value, (types.FunctionType, types.BuiltinFunctionType)): + return value.__name__ + return repr(value) + + +def annotations_to_source(annotations): + """Convert an annotation dict containing values to approximately the SOURCE format.""" + return { + n: t if isinstance(t, str) else value_to_source(t) + for n, t in annotations.items() + } + + def _get_and_call_annotate(obj, format): annotate = get_annotate_function(obj) if annotate is not None: |