(cls, init, repr, eq, order, unsafe_hash, frozen,
match_args, kw_only, slots, weakref_slot)
| 984 | |
| 985 | |
| 986 | def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen, |
| 987 | match_args, kw_only, slots, weakref_slot): |
| 988 | # Now that dicts retain insertion order, there's no reason to use |
| 989 | # an ordered dict. I am leveraging that ordering here, because |
| 990 | # derived class fields overwrite base class fields, but the order |
| 991 | # is defined by the base class, which is found first. |
| 992 | fields = {} |
| 993 | |
| 994 | if cls.__module__ in sys.modules: |
| 995 | globals = sys.modules[cls.__module__].__dict__ |
| 996 | else: |
| 997 | # Theoretically this can happen if someone writes |
| 998 | # a custom string to cls.__module__. In which case |
| 999 | # such dataclass won't be fully introspectable |
| 1000 | # (w.r.t. typing.get_type_hints) but will still function |
| 1001 | # correctly. |
| 1002 | globals = {} |
| 1003 | |
| 1004 | setattr(cls, _PARAMS, _DataclassParams(init, repr, eq, order, |
| 1005 | unsafe_hash, frozen, |
| 1006 | match_args, kw_only, |
| 1007 | slots, weakref_slot)) |
| 1008 | |
| 1009 | # Find our base classes in reverse MRO order, and exclude |
| 1010 | # ourselves. In reversed order so that more derived classes |
| 1011 | # override earlier field definitions in base classes. As long as |
| 1012 | # we're iterating over them, see if all or any of them are frozen. |
| 1013 | any_frozen_base = False |
| 1014 | # By default `all_frozen_bases` is `None` to represent a case, |
| 1015 | # where some dataclasses does not have any bases with `_FIELDS` |
| 1016 | all_frozen_bases = None |
| 1017 | has_dataclass_bases = False |
| 1018 | for b in cls.__mro__[-1:0:-1]: |
| 1019 | # Only process classes that have been processed by our |
| 1020 | # decorator. That is, they have a _FIELDS attribute. |
| 1021 | base_fields = getattr(b, _FIELDS, None) |
| 1022 | if base_fields is not None: |
| 1023 | has_dataclass_bases = True |
| 1024 | for f in base_fields.values(): |
| 1025 | fields[f.name] = f |
| 1026 | if all_frozen_bases is None: |
| 1027 | all_frozen_bases = True |
| 1028 | current_frozen = getattr(b, _PARAMS).frozen |
| 1029 | all_frozen_bases = all_frozen_bases and current_frozen |
| 1030 | any_frozen_base = any_frozen_base or current_frozen |
| 1031 | |
| 1032 | # Annotations defined specifically in this class (not in base classes). |
| 1033 | # |
| 1034 | # Fields are found from cls_annotations, which is guaranteed to be |
| 1035 | # ordered. Default values are from class attributes, if a field |
| 1036 | # has a default. If the default value is a Field(), then it |
| 1037 | # contains additional info beyond (and possibly including) the |
| 1038 | # actual default value. Pseudo-fields ClassVars and InitVars are |
| 1039 | # included, despite the fact that they're not real fields. That's |
| 1040 | # dealt with later. |
| 1041 | cls_annotations = annotationlib.get_annotations( |
| 1042 | cls, format=annotationlib.Format.FORWARDREF) |
| 1043 |
no test coverage detected
searching dependent graphs…