(cls, typename, bases, ns)
| 3012 | |
| 3013 | class NamedTupleMeta(type): |
| 3014 | def __new__(cls, typename, bases, ns): |
| 3015 | assert _NamedTuple in bases |
| 3016 | if "__classcell__" in ns: |
| 3017 | raise TypeError( |
| 3018 | "uses of super() and __class__ are unsupported in methods of NamedTuple subclasses") |
| 3019 | for base in bases: |
| 3020 | if base is not _NamedTuple and base is not Generic: |
| 3021 | raise TypeError( |
| 3022 | 'can only inherit from a NamedTuple type and Generic') |
| 3023 | bases = tuple(tuple if base is _NamedTuple else base for base in bases) |
| 3024 | if "__annotations__" in ns: |
| 3025 | types = ns["__annotations__"] |
| 3026 | field_names = list(types) |
| 3027 | annotate = _make_eager_annotate(types) |
| 3028 | elif (original_annotate := _lazy_annotationlib.get_annotate_from_class_namespace(ns)) is not None: |
| 3029 | types = _lazy_annotationlib.call_annotate_function( |
| 3030 | original_annotate, _lazy_annotationlib.Format.FORWARDREF) |
| 3031 | field_names = list(types) |
| 3032 | |
| 3033 | # For backward compatibility, type-check all the types at creation time |
| 3034 | for typ in types.values(): |
| 3035 | _type_check(typ, "field annotation must be a type") |
| 3036 | |
| 3037 | def annotate(format): |
| 3038 | annos = _lazy_annotationlib.call_annotate_function( |
| 3039 | original_annotate, format) |
| 3040 | if format != _lazy_annotationlib.Format.STRING: |
| 3041 | return {key: _type_check(val, f"field {key} annotation must be a type") |
| 3042 | for key, val in annos.items()} |
| 3043 | return annos |
| 3044 | else: |
| 3045 | # Empty NamedTuple |
| 3046 | field_names = [] |
| 3047 | annotate = lambda format: {} |
| 3048 | default_names = [] |
| 3049 | for field_name in field_names: |
| 3050 | if field_name in ns: |
| 3051 | default_names.append(field_name) |
| 3052 | elif default_names: |
| 3053 | raise TypeError(f"Non-default namedtuple field {field_name} " |
| 3054 | f"cannot follow default field" |
| 3055 | f"{'s' if len(default_names) > 1 else ''} " |
| 3056 | f"{', '.join(default_names)}") |
| 3057 | nm_tpl = _make_nmtuple(typename, field_names, annotate, |
| 3058 | defaults=[ns[n] for n in default_names], |
| 3059 | module=ns['__module__']) |
| 3060 | nm_tpl.__bases__ = bases |
| 3061 | if Generic in bases: |
| 3062 | class_getitem = _generic_class_getitem |
| 3063 | nm_tpl.__class_getitem__ = classmethod(class_getitem) |
| 3064 | # update from user namespace without overriding special namedtuple attributes |
| 3065 | for key, val in ns.items(): |
| 3066 | if key in _prohibited: |
| 3067 | raise AttributeError("Cannot overwrite NamedTuple attribute " + key) |
| 3068 | elif key not in _special: |
| 3069 | if key not in nm_tpl._fields: |
| 3070 | setattr(nm_tpl, key, val) |
| 3071 | try: |
nothing calls this directly
no test coverage detected