@@ -2884,8 +2884,14 @@ def __new__(cls, name, bases, ns, total=True):
28842884
28852885 for base in bases :
28862886 annotations .update (base .__dict__ .get ('__annotations__' , {}))
2887- required_keys .update (base .__dict__ .get ('__required_keys__' , ()))
2888- optional_keys .update (base .__dict__ .get ('__optional_keys__' , ()))
2887+
2888+ base_required = base .__dict__ .get ('__required_keys__' , set ())
2889+ required_keys |= base_required
2890+ optional_keys -= base_required
2891+
2892+ base_optional = base .__dict__ .get ('__optional_keys__' , set ())
2893+ required_keys -= base_optional
2894+ optional_keys |= base_optional
28892895
28902896 annotations .update (own_annotations )
28912897 for annotation_key , annotation_type in own_annotations .items ():
@@ -2897,14 +2903,23 @@ def __new__(cls, name, bases, ns, total=True):
28972903 annotation_origin = get_origin (annotation_type )
28982904
28992905 if annotation_origin is Required :
2900- required_keys . add ( annotation_key )
2906+ is_required = True
29012907 elif annotation_origin is NotRequired :
2902- optional_keys .add (annotation_key )
2903- elif total :
2908+ is_required = False
2909+ else :
2910+ is_required = total
2911+
2912+ if is_required :
29042913 required_keys .add (annotation_key )
2914+ optional_keys .discard (annotation_key )
29052915 else :
29062916 optional_keys .add (annotation_key )
2917+ required_keys .discard (annotation_key )
29072918
2919+ assert required_keys .isdisjoint (optional_keys ), (
2920+ f"Required keys overlap with optional keys in { name } :"
2921+ f" { required_keys = } , { optional_keys = } "
2922+ )
29082923 tp_dict .__annotations__ = annotations
29092924 tp_dict .__required_keys__ = frozenset (required_keys )
29102925 tp_dict .__optional_keys__ = frozenset (optional_keys )
0 commit comments