1414import typing
1515import warnings
1616
17+ if sys .version_info >= (3 , 14 ):
18+ import annotationlib
19+
1720__all__ = [
1821 # Super-special typing primitives.
1922 'Any' ,
@@ -1018,21 +1021,27 @@ def __new__(cls, name, bases, ns, *, total=True, closed=None,
10181021 tp_dict .__orig_bases__ = bases
10191022
10201023 annotations = {}
1024+ own_annotate = None
10211025 if "__annotations__" in ns :
10221026 own_annotations = ns ["__annotations__" ]
1023- elif "__annotate__" in ns :
1024- # TODO: Use inspect.VALUE here, and make the annotations lazily evaluated
1025- own_annotations = ns ["__annotate__" ](1 )
1027+ elif sys .version_info >= (3 , 14 ):
1028+ own_annotate = annotationlib .get_annotate_from_class_namespace (ns )
1029+ if own_annotate is not None :
1030+ own_annotations = annotationlib .call_annotate_function (
1031+ own_annotate , annotationlib .Format .FORWARDREF , owner = tp_dict
1032+ )
1033+ else :
1034+ own_annotations = {}
10261035 else :
10271036 own_annotations = {}
10281037 msg = "TypedDict('Name', {f0: t0, f1: t1, ...}); each t must be a type"
10291038 if _TAKES_MODULE :
1030- own_annotations = {
1039+ own_checked_annotations = {
10311040 n : typing ._type_check (tp , msg , module = tp_dict .__module__ )
10321041 for n , tp in own_annotations .items ()
10331042 }
10341043 else :
1035- own_annotations = {
1044+ own_checked_annotations = {
10361045 n : typing ._type_check (tp , msg )
10371046 for n , tp in own_annotations .items ()
10381047 }
@@ -1045,7 +1054,8 @@ def __new__(cls, name, bases, ns, *, total=True, closed=None,
10451054 for base in bases :
10461055 base_dict = base .__dict__
10471056
1048- annotations .update (base_dict .get ('__annotations__' , {}))
1057+ if sys .version_info <= (3 , 14 ):
1058+ annotations .update (base_dict .get ('__annotations__' , {}))
10491059 required_keys .update (base_dict .get ('__required_keys__' , ()))
10501060 optional_keys .update (base_dict .get ('__optional_keys__' , ()))
10511061 readonly_keys .update (base_dict .get ('__readonly_keys__' , ()))
@@ -1055,8 +1065,8 @@ def __new__(cls, name, bases, ns, *, total=True, closed=None,
10551065 # is retained for backwards compatibility, but only for Python
10561066 # 3.13 and lower.
10571067 if (closed and sys .version_info < (3 , 14 )
1058- and "__extra_items__" in own_annotations ):
1059- annotation_type = own_annotations .pop ("__extra_items__" )
1068+ and "__extra_items__" in own_checked_annotations ):
1069+ annotation_type = own_checked_annotations .pop ("__extra_items__" )
10601070 qualifiers = set (_get_typeddict_qualifiers (annotation_type ))
10611071 if Required in qualifiers :
10621072 raise TypeError (
@@ -1070,8 +1080,8 @@ def __new__(cls, name, bases, ns, *, total=True, closed=None,
10701080 )
10711081 extra_items_type = annotation_type
10721082
1073- annotations .update (own_annotations )
1074- for annotation_key , annotation_type in own_annotations .items ():
1083+ annotations .update (own_checked_annotations )
1084+ for annotation_key , annotation_type in own_checked_annotations .items ():
10751085 qualifiers = set (_get_typeddict_qualifiers (annotation_type ))
10761086
10771087 if Required in qualifiers :
@@ -1089,7 +1099,38 @@ def __new__(cls, name, bases, ns, *, total=True, closed=None,
10891099 mutable_keys .add (annotation_key )
10901100 readonly_keys .discard (annotation_key )
10911101
1092- tp_dict .__annotations__ = annotations
1102+ if sys .version_info >= (3 , 14 ):
1103+ def __annotate__ (format ):
1104+ annos = {}
1105+ for base in bases :
1106+ if base is Generic :
1107+ continue
1108+ base_annotate = base .__annotate__
1109+ if base_annotate is None :
1110+ continue
1111+ base_annos = annotationlib .call_annotate_function (
1112+ base .__annotate__ , format , owner = base )
1113+ annos .update (base_annos )
1114+ if own_annotate is not None :
1115+ own = annotationlib .call_annotate_function (
1116+ own_annotate , format , owner = tp_dict )
1117+ if format != annotationlib .Format .STRING :
1118+ own = {
1119+ n : typing ._type_check (tp , msg , module = tp_dict .__module__ )
1120+ for n , tp in own .items ()
1121+ }
1122+ elif format == annotationlib .Format .STRING :
1123+ own = annotationlib .annotations_to_string (own_annotations )
1124+ elif format in (annotationlib .Format .FORWARDREF , annotationlib .Format .VALUE ):
1125+ own = own_checked_annotations
1126+ else :
1127+ raise NotImplementedError (format )
1128+ annos .update (own )
1129+ return annos
1130+
1131+ tp_dict .__annotate__ = __annotate__
1132+ else :
1133+ tp_dict .__annotations__ = annotations
10931134 tp_dict .__required_keys__ = frozenset (required_keys )
10941135 tp_dict .__optional_keys__ = frozenset (optional_keys )
10951136 tp_dict .__readonly_keys__ = frozenset (readonly_keys )
0 commit comments