summaryrefslogtreecommitdiffstats
path: root/Lib/dataclasses.py
diff options
context:
space:
mode:
authorNikita Sobolev <mail@sobolevn.me>2023-10-12 13:05:23 (GMT)
committerGitHub <noreply@github.com>2023-10-12 13:05:23 (GMT)
commitb6000d287407cbccfbb1157dc1fc6128497badc7 (patch)
tree165c3c724b6331dd342c096e8ebc51a94321923d /Lib/dataclasses.py
parent7dd3c2b80064c39f1f0ebbc1f8486897b3148aa5 (diff)
downloadcpython-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.py14
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')