| 3136 | |
| 3137 | |
| 3138 | class _TypedDictMeta(type): |
| 3139 | def __new__(cls, name, bases, ns, total=True): |
| 3140 | """Create a new typed dict class object. |
| 3141 | |
| 3142 | This method is called when TypedDict is subclassed, |
| 3143 | or when TypedDict is instantiated. This way |
| 3144 | TypedDict supports all three syntax forms described in its docstring. |
| 3145 | Subclasses and instances of TypedDict return actual dictionaries. |
| 3146 | """ |
| 3147 | for base in bases: |
| 3148 | if type(base) is not _TypedDictMeta and base is not Generic: |
| 3149 | raise TypeError('cannot inherit from both a TypedDict type ' |
| 3150 | 'and a non-TypedDict base class') |
| 3151 | |
| 3152 | if any(issubclass(b, Generic) for b in bases): |
| 3153 | generic_base = (Generic,) |
| 3154 | else: |
| 3155 | generic_base = () |
| 3156 | |
| 3157 | ns_annotations = ns.pop('__annotations__', None) |
| 3158 | |
| 3159 | tp_dict = type.__new__(_TypedDictMeta, name, (*generic_base, dict), ns) |
| 3160 | |
| 3161 | if not hasattr(tp_dict, '__orig_bases__'): |
| 3162 | tp_dict.__orig_bases__ = bases |
| 3163 | |
| 3164 | if ns_annotations is not None: |
| 3165 | own_annotate = None |
| 3166 | own_annotations = ns_annotations |
| 3167 | elif (own_annotate := _lazy_annotationlib.get_annotate_from_class_namespace(ns)) is not None: |
| 3168 | own_annotations = _lazy_annotationlib.call_annotate_function( |
| 3169 | own_annotate, _lazy_annotationlib.Format.FORWARDREF, owner=tp_dict |
| 3170 | ) |
| 3171 | else: |
| 3172 | own_annotate = None |
| 3173 | own_annotations = {} |
| 3174 | msg = "TypedDict('Name', {f0: t0, f1: t1, ...}); each t must be a type" |
| 3175 | own_checked_annotations = { |
| 3176 | n: _type_check(tp, msg, owner=tp_dict, module=tp_dict.__module__) |
| 3177 | for n, tp in own_annotations.items() |
| 3178 | } |
| 3179 | required_keys = set() |
| 3180 | optional_keys = set() |
| 3181 | readonly_keys = set() |
| 3182 | mutable_keys = set() |
| 3183 | |
| 3184 | for base in bases: |
| 3185 | base_required = base.__dict__.get('__required_keys__', set()) |
| 3186 | required_keys |= base_required |
| 3187 | optional_keys -= base_required |
| 3188 | |
| 3189 | base_optional = base.__dict__.get('__optional_keys__', set()) |
| 3190 | required_keys -= base_optional |
| 3191 | optional_keys |= base_optional |
| 3192 | |
| 3193 | readonly_keys.update(base.__dict__.get('__readonly_keys__', ())) |
| 3194 | mutable_keys.update(base.__dict__.get('__mutable_keys__', ())) |
| 3195 | |