classification
Title: Dataclasses derived from empty frozen bases skip immutability checks
Type: behavior Stage: needs patch
Components: Library (Lib) Versions: Python 3.10, Python 3.9, Python 3.8
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: eric.smith Nosy List: eric.smith, hbq1, miss-islington, ulope
Priority: normal Keywords: 3.8regression, 3.9regression

Created on 2021-02-09 07:12 by hbq1, last changed 2021-05-13 05:17 by eric.smith.

Pull Requests
URL Status Linked Edit
PR 24484 merged hbq1, 2021-02-09 07:12
PR 25205 merged miss-islington, 2021-04-06 05:14
PR 25206 merged miss-islington, 2021-04-06 05:14
PR 25215 merged eric.smith, 2021-04-06 13:52
PR 25217 merged miss-islington, 2021-04-06 14:08
PR 25218 merged miss-islington, 2021-04-06 14:08
Messages (12)
msg386695 - (view) Author: Iurii Kemaev (hbq1) * Date: 2021-02-09 07:12
Dataclasses derived from empty frozen bases skip immutability checks.

Repro snippet:

```
import dataclasses

@dataclasses.dataclass(frozen=True)
class Base:
  pass

@dataclasses.dataclass
class Derived(Base):
  a: int

d = Derived(2)
# OK
```

Usecase: sometimes developers define an empty frozen base dataclass with detailed docs and require other dataclasses to inherit from it as a code contract to avoid accidental in-place modifications. 
This bug makes this strategy ineffective.

Affects all versions of Python that support dataclasses (including the backport for py3.6).
msg390277 - (view) Author: miss-islington (miss-islington) Date: 2021-04-06 05:14
New changeset 376ffc6ac491da74920aed1b8e35bc371cb766ac by Iurii Kemaev in branch 'master':
bpo-43176: Fix processing of empty dataclasses (GH-24484)
https://github.com/python/cpython/commit/376ffc6ac491da74920aed1b8e35bc371cb766ac
msg390278 - (view) Author: miss-islington (miss-islington) Date: 2021-04-06 05:32
New changeset b132be8b43afa739b7eda271b82711d64a83da4f by Miss Islington (bot) in branch '3.8':
bpo-43176: Fix processing of empty dataclasses (GH-24484)
https://github.com/python/cpython/commit/b132be8b43afa739b7eda271b82711d64a83da4f
msg390280 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2021-04-06 06:04
Thanks!
msg390332 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2021-04-06 13:46
New changeset 8a34a0793bcb830350dac675524310bb285e5e4f by Miss Islington (bot) in branch '3.9':
bpo-43176: Fix processing of empty dataclasses (GH-24484) (GH-25205)
https://github.com/python/cpython/commit/8a34a0793bcb830350dac675524310bb285e5e4f
msg390336 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2021-04-06 14:08
New changeset 1744c96ebc98b240f2564f75191097704b37244f by Eric V. Smith in branch 'master':
Fix blurb for bpo-43176. (GH-25215)
https://github.com/python/cpython/commit/1744c96ebc98b240f2564f75191097704b37244f
msg390339 - (view) Author: miss-islington (miss-islington) Date: 2021-04-06 14:19
New changeset 76c4a9fb8ae370901b387a4edb609295bcc159e7 by Miss Islington (bot) in branch '3.8':
[3.8] Fix blurb for bpo-43176. (GH-25215) (GH-25218)
https://github.com/python/cpython/commit/76c4a9fb8ae370901b387a4edb609295bcc159e7
msg390344 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2021-04-06 15:07
New changeset 2df971afd5f29574be3bb44f2d8569cc240b800d by Miss Islington (bot) in branch '3.9':
Fix blurb for bpo-43176. (GH-25215) (GH-25217)
https://github.com/python/cpython/commit/2df971afd5f29574be3bb44f2d8569cc240b800d
msg393101 - (view) Author: Ulrich Petri (ulope) * Date: 2021-05-06 15:40
Wether the original behaviour was intentional or not this change introduces backwards incompatibility (and in our case, breakage) between 3.8.10 and previous releases (I expect the same to be true for the equivalent 3.9 releases).
msg393103 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2021-05-06 15:58
Can you provide a small snippet of code showing the kind of thing that broke?
msg393151 - (view) Author: Ulrich Petri (ulope) * Date: 2021-05-06 21:34
@eric.smith Sure, here you go:


dataclass_empty.py:
```
from dataclasses import dataclass


@dataclass
class A:
    pass


@dataclass(frozen=True)
class B(A):
    x: int

print("42")
```

Running this on < 3.8.10:
```
$ ~/.pythonz/pythons/CPython-3.8.1/bin/python3.8 --version
Python 3.8.1

$ ~/.pythonz/pythons/CPython-3.8.1/bin/python3.8 dataclass_empty.py
42
```

And on 3.8.10:
```
$ /usr/local/opt/python@3.8/bin/python3 --version
Python 3.8.10

$ /usr/local/opt/python@3.8/bin/python3 dataclass_empty.py
Traceback (most recent call last):
  File "dataclass_empty.py", line 10, in <module>
    class B(A):
  File "/usr/local/Cellar/python@3.8/3.8.10/Frameworks/Python.framework/Versions/3.8/lib/python3.8/dataclasses.py", line 1011, in wrap
    return _process_class(cls, init, repr, eq, order, unsafe_hash, frozen)
  File "/usr/local/Cellar/python@3.8/3.8.10/Frameworks/Python.framework/Versions/3.8/lib/python3.8/dataclasses.py", line 896, in _process_class
    raise TypeError('cannot inherit frozen dataclass from a '
TypeError: cannot inherit frozen dataclass from a non-frozen one
```
msg393152 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2021-05-06 21:51
Hmm. I think maybe the intent was that if you're frozen, treat all the fields as frozen, including ones you inherit, regardless if the base classes are frozen or not.
History
Date User Action Args
2021-05-13 05:17:57eric.smithsetassignee: eric.smith
2021-05-07 00:10:04eric.smithsetkeywords: + 3.8regression, 3.9regression, - patch
status: closed -> open
resolution: fixed ->
stage: resolved -> needs patch
2021-05-06 21:51:52eric.smithsetmessages: + msg393152
2021-05-06 21:34:30ulopesetmessages: + msg393151
2021-05-06 15:58:12eric.smithsetmessages: + msg393103
2021-05-06 15:40:08ulopesetnosy: + ulope
messages: + msg393101
2021-04-06 15:07:14eric.smithsetmessages: + msg390344
2021-04-06 14:19:05miss-islingtonsetmessages: + msg390339
2021-04-06 14:08:47eric.smithsetmessages: + msg390336
2021-04-06 14:08:45miss-islingtonsetpull_requests: + pull_request23956
2021-04-06 14:08:34miss-islingtonsetpull_requests: + pull_request23955
2021-04-06 13:52:16eric.smithsetpull_requests: + pull_request23953
2021-04-06 13:46:37eric.smithsetmessages: + msg390332
2021-04-06 06:04:27eric.smithsetstatus: open -> closed
versions: - Python 3.6, Python 3.7
messages: + msg390280

resolution: fixed
stage: patch review -> resolved
2021-04-06 05:32:02miss-islingtonsetmessages: + msg390278
2021-04-06 05:14:45miss-islingtonsetpull_requests: + pull_request23945
2021-04-06 05:14:36miss-islingtonsetkeywords: + patch
stage: patch review
pull_requests: + pull_request23944
2021-04-06 05:14:08miss-islingtonsetnosy: + miss-islington
messages: + msg390277
2021-02-09 07:14:17xtreaksetnosy: + eric.smith
2021-02-09 07:12:39hbq1create