@@ -640,12 +640,18 @@ def get_annotations(
640640):
641641 """Compute the annotations dict for an object.
642642
643- obj may be a callable, class, or module.
644- Passing in an object of any other type raises TypeError.
645-
646- Returns a dict. get_annotations() returns a new dict every time
647- it's called; calling it twice on the same object will return two
648- different but equivalent dicts.
643+ obj may be a callable, class, module, or other object with
644+ __annotate__ or __annotations__ attributes.
645+ Passing any other object raises TypeError.
646+
647+ The *format* parameter controls the format in which annotations are returned,
648+ and must be a member of the Format enum or its integer equivalent.
649+ For the VALUE format, the __annotations__ is tried first; if it
650+ does not exist, the __annotate__ function is called. The
651+ FORWARDREF format uses __annotations__ if it exists and can be
652+ evaluated, and otherwise falls back to calling the __annotate__ function.
653+ The SOURCE format tries __annotate__ first, and falls back to
654+ using __annotations__, stringified using annotations_to_string().
649655
650656 This function handles several details for you:
651657
@@ -687,37 +693,48 @@ def get_annotations(
687693
688694 match format :
689695 case Format .VALUE :
690- # For VALUE, we only look at __annotations__
696+ # For VALUE, we first look at __annotations__
691697 ann = _get_dunder_annotations (obj )
698+
699+ # If it's not there, try __annotate__ instead
700+ if ann is None :
701+ ann = _get_and_call_annotate (obj , format )
692702 case Format .FORWARDREF :
693703 # For FORWARDREF, we use __annotations__ if it exists
694704 try :
695- return dict ( _get_dunder_annotations (obj ) )
705+ ann = _get_dunder_annotations (obj )
696706 except NameError :
697707 pass
708+ else :
709+ if ann is not None :
710+ return dict (ann )
698711
699712 # But if __annotations__ threw a NameError, we try calling __annotate__
700713 ann = _get_and_call_annotate (obj , format )
701- if ann is not None :
702- return ann
703-
704- # If that didn't work either, we have a very weird object: evaluating
705- # __annotations__ threw NameError and there is no __annotate__. In that case,
706- # we fall back to trying __annotations__ again.
707- return dict (_get_dunder_annotations (obj ))
714+ if ann is None :
715+ # If that didn't work either, we have a very weird object: evaluating
716+ # __annotations__ threw NameError and there is no __annotate__. In that case,
717+ # we fall back to trying __annotations__ again.
718+ ann = _get_dunder_annotations (obj )
708719 case Format .STRING :
709720 # For STRING, we try to call __annotate__
710721 ann = _get_and_call_annotate (obj , format )
711722 if ann is not None :
712723 return ann
713724 # But if we didn't get it, we use __annotations__ instead.
714725 ann = _get_dunder_annotations (obj )
715- return annotations_to_string (ann )
726+ if ann is not None :
727+ ann = annotations_to_string (ann )
716728 case Format .VALUE_WITH_FAKE_GLOBALS :
717729 raise ValueError ("The VALUE_WITH_FAKE_GLOBALS format is for internal use only" )
718730 case _:
719731 raise ValueError (f"Unsupported format { format !r} " )
720732
733+ if ann is None :
734+ if isinstance (obj , type ) or callable (obj ):
735+ return {}
736+ raise TypeError (f"{ obj !r} does not have annotations" )
737+
721738 if not ann :
722739 return {}
723740
@@ -746,10 +763,8 @@ def get_annotations(
746763 obj_globals = getattr (obj , "__globals__" , None )
747764 obj_locals = None
748765 unwrap = obj
749- elif ann is not None :
750- obj_globals = obj_locals = unwrap = None
751766 else :
752- raise TypeError ( f" { obj !r } is not a module, class, or callable." )
767+ obj_globals = obj_locals = unwrap = None
753768
754769 if unwrap is not None :
755770 while True :
@@ -827,11 +842,11 @@ def _get_dunder_annotations(obj):
827842 ann = obj .__annotations__
828843 except AttributeError :
829844 # For static types, the descriptor raises AttributeError.
830- return {}
845+ return None
831846 else :
832847 ann = getattr (obj , "__annotations__" , None )
833848 if ann is None :
834- return {}
849+ return None
835850
836851 if not isinstance (ann , dict ):
837852 raise ValueError (f"{ obj !r} .__annotations__ is neither a dict nor None" )
0 commit comments