@@ -917,7 +917,7 @@ def _get_typeddict_qualifiers(annotation_type):
917917 break
918918
919919 class _TypedDictMeta (type ):
920- def __new__ (cls , name , bases , ns , * , total = True , closed = False ):
920+ def __new__ (cls , name , bases , ns , * , total = True , closed = None , extra_items = None ):
921921 """Create new typed dict class object.
922922
923923 This method is called when TypedDict is subclassed,
@@ -929,6 +929,10 @@ def __new__(cls, name, bases, ns, *, total=True, closed=False):
929929 if type (base ) is not _TypedDictMeta and base is not typing .Generic :
930930 raise TypeError ('cannot inherit from both a TypedDict type '
931931 'and a non-TypedDict base class' )
932+ if closed is not None and extra_items is not None :
933+ raise TypeError ("Cannot combine closed=True and extra_items" )
934+ elif closed is None :
935+ closed = False
932936
933937 if any (issubclass (b , typing .Generic ) for b in bases ):
934938 generic_base = (typing .Generic ,)
@@ -968,7 +972,7 @@ def __new__(cls, name, bases, ns, *, total=True, closed=False):
968972 optional_keys = set ()
969973 readonly_keys = set ()
970974 mutable_keys = set ()
971- extra_items_type = None
975+ extra_items_type = extra_items
972976
973977 for base in bases :
974978 base_dict = base .__dict__
@@ -978,13 +982,19 @@ def __new__(cls, name, bases, ns, *, total=True, closed=False):
978982 optional_keys .update (base_dict .get ('__optional_keys__' , ()))
979983 readonly_keys .update (base_dict .get ('__readonly_keys__' , ()))
980984 mutable_keys .update (base_dict .get ('__mutable_keys__' , ()))
981- base_extra_items_type = base_dict . get ( '__extra_items__' , None )
985+ base_extra_items_type = getattr ( base , '__extra_items__' , None )
982986 if base_extra_items_type is not None :
983987 extra_items_type = base_extra_items_type
988+ if getattr (base , "__closed__" , False ) and not closed :
989+ raise TypeError ("Child of a closed TypedDict must also be closed" )
984990
985991 if closed and extra_items_type is None :
986992 extra_items_type = Never
987- if closed and "__extra_items__" in own_annotations :
993+
994+ # This was specified in an earlier version of PEP 728. Support
995+ # is retained for backwards compatibility, but only for Python 3.13
996+ # and lower.
997+ if closed and sys .version_info < (3 , 14 ) and "__extra_items__" in own_annotations :
988998 annotation_type = own_annotations .pop ("__extra_items__" )
989999 qualifiers = set (_get_typeddict_qualifiers (annotation_type ))
9901000 if Required in qualifiers :
0 commit comments