diff options
author | Eric V. Smith <ericvsmith@users.noreply.github.com> | 2021-12-11 21:12:17 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-11 21:12:17 (GMT) |
commit | e029c53e1a408b89a4e3edf30a9b38b094f9c880 (patch) | |
tree | a439835a4dd477b67b500e5d09ff82b739973791 /Lib/dataclasses.py | |
parent | bfc59ed0a00106f5ba4a32a0c5b3dbe71d12665d (diff) | |
download | cpython-e029c53e1a408b89a4e3edf30a9b38b094f9c880.zip cpython-e029c53e1a408b89a4e3edf30a9b38b094f9c880.tar.gz cpython-e029c53e1a408b89a4e3edf30a9b38b094f9c880.tar.bz2 |
bpo-44674: Use unhashability as a proxy for mutability for default dataclass __init__ arguments. (GH-29867)
`@dataclass` in 3.10 prohibits using list, dict, or set as default values. It does this to avoid the mutable default problem. This test is both too strict, and not strict enough. Too strict, because some immutable subclasses should be safe, and not strict enough, because other mutable types should be prohibited. With this change applied, `@dataclass` now uses unhashability as a proxy for mutability: if objects aren't hashable, they're assumed to be mutable.
Diffstat (limited to 'Lib/dataclasses.py')
-rw-r--r-- | Lib/dataclasses.py | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index 3f85d85..b327462 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -808,8 +808,10 @@ def _get_field(cls, a_name, a_type, default_kw_only): raise TypeError(f'field {f.name} is a ClassVar but specifies ' 'kw_only') - # For real fields, disallow mutable defaults for known types. - if f._field_type is _FIELD and isinstance(f.default, (list, dict, set)): + # For real fields, disallow mutable defaults. Use unhashable as a proxy + # indicator for mutability. Read the __hash__ attribute from the class, + # not the instance. + if f._field_type is _FIELD and f.default.__class__.__hash__ is None: raise ValueError(f'mutable default {type(f.default)} for field ' f'{f.name} is not allowed: use default_factory') |