diff options
author | Nikita Sobolev <mail@sobolevn.me> | 2023-10-12 13:05:23 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-12 13:05:23 (GMT) |
commit | b6000d287407cbccfbb1157dc1fc6128497badc7 (patch) | |
tree | 165c3c724b6331dd342c096e8ebc51a94321923d /Lib/dataclasses.py | |
parent | 7dd3c2b80064c39f1f0ebbc1f8486897b3148aa5 (diff) | |
download | cpython-b6000d287407cbccfbb1157dc1fc6128497badc7.zip cpython-b6000d287407cbccfbb1157dc1fc6128497badc7.tar.gz cpython-b6000d287407cbccfbb1157dc1fc6128497badc7.tar.bz2 |
gh-109409: Fix inheritance of frozen dataclass from non-frozen dataclass mixins (gh-109437)
Fix inheritance of frozen dataclass from non-frozen dataclass mixins
Diffstat (limited to 'Lib/dataclasses.py')
-rw-r--r-- | Lib/dataclasses.py | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index 31dc6f8..2fba32b 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -944,8 +944,11 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen, # Find our base classes in reverse MRO order, and exclude # ourselves. In reversed order so that more derived classes # override earlier field definitions in base classes. As long as - # we're iterating over them, see if any are frozen. + # we're iterating over them, see if all or any of them are frozen. any_frozen_base = False + # By default `all_frozen_bases` is `None` to represent a case, + # where some dataclasses does not have any bases with `_FIELDS` + all_frozen_bases = None has_dataclass_bases = False for b in cls.__mro__[-1:0:-1]: # Only process classes that have been processed by our @@ -955,8 +958,11 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen, has_dataclass_bases = True for f in base_fields.values(): fields[f.name] = f - if getattr(b, _PARAMS).frozen: - any_frozen_base = True + if all_frozen_bases is None: + all_frozen_bases = True + current_frozen = getattr(b, _PARAMS).frozen + all_frozen_bases = all_frozen_bases and current_frozen + any_frozen_base = any_frozen_base or current_frozen # Annotations defined specifically in this class (not in base classes). # @@ -1025,7 +1031,7 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen, 'frozen one') # Raise an exception if we're frozen, but none of our bases are. - if not any_frozen_base and frozen: + if all_frozen_bases is False and frozen: raise TypeError('cannot inherit frozen dataclass from a ' 'non-frozen one') |