Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dataclasses derived from empty frozen bases skip immutability checks #87342

Closed
hbq1 mannequin opened this issue Feb 9, 2021 · 13 comments
Closed

Dataclasses derived from empty frozen bases skip immutability checks #87342

hbq1 mannequin opened this issue Feb 9, 2021 · 13 comments
Assignees
Labels
3.8 only security fixes 3.9 only security fixes 3.10 only security fixes stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@hbq1
Copy link
Mannequin

hbq1 mannequin commented Feb 9, 2021

BPO 43176
Nosy @ericvsmith, @miss-islington, @hbq1
PRs
  • bpo-43176: Fix processing of empty dataclasses #24484
  • [3.9] bpo-43176: Fix processing of empty dataclasses (GH-24484) #25205
  • [3.8] bpo-43176: Fix processing of empty dataclasses (GH-24484) #25206
  • bpo-43176: Fix blurb #25215
  • [3.9] Fix blurb for bpo-43176. (GH-25215) #25217
  • [3.8] Fix blurb for bpo-43176. (GH-25215) #25218
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = 'https://github.com/ericvsmith'
    closed_at = None
    created_at = <Date 2021-02-09.07:12:39.343>
    labels = ['3.8', 'type-bug', 'library', '3.9', '3.10']
    title = 'Dataclasses derived from empty frozen bases skip immutability checks'
    updated_at = <Date 2021-05-13.05:17:57.697>
    user = 'https://github.com/hbq1'

    bugs.python.org fields:

    activity = <Date 2021-05-13.05:17:57.697>
    actor = 'eric.smith'
    assignee = 'eric.smith'
    closed = False
    closed_date = None
    closer = None
    components = ['Library (Lib)']
    creation = <Date 2021-02-09.07:12:39.343>
    creator = 'hbq1'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 43176
    keywords = ['3.8regression', '3.9regression']
    message_count = 12.0
    messages = ['386695', '390277', '390278', '390280', '390332', '390336', '390339', '390344', '393101', '393103', '393151', '393152']
    nosy_count = 4.0
    nosy_names = ['eric.smith', 'ulope', 'miss-islington', 'hbq1']
    pr_nums = ['24484', '25205', '25206', '25215', '25217', '25218']
    priority = 'normal'
    resolution = None
    stage = 'needs patch'
    status = 'open'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue43176'
    versions = ['Python 3.8', 'Python 3.9', 'Python 3.10']

    @hbq1
    Copy link
    Mannequin Author

    hbq1 mannequin commented Feb 9, 2021

    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).

    @hbq1 hbq1 mannequin added 3.7 (EOL) end of life 3.10 only security fixes 3.8 only security fixes 3.9 only security fixes stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error labels Feb 9, 2021
    @miss-islington
    Copy link
    Contributor

    New changeset 376ffc6 by Iurii Kemaev in branch 'master':
    bpo-43176: Fix processing of empty dataclasses (GH-24484)
    376ffc6

    @miss-islington
    Copy link
    Contributor

    New changeset b132be8 by Miss Islington (bot) in branch '3.8':
    bpo-43176: Fix processing of empty dataclasses (GH-24484)
    b132be8

    @ericvsmith
    Copy link
    Member

    Thanks!

    @ericvsmith ericvsmith removed the 3.7 (EOL) end of life label Apr 6, 2021
    @ericvsmith
    Copy link
    Member

    New changeset 8a34a07 by Miss Islington (bot) in branch '3.9':
    bpo-43176: Fix processing of empty dataclasses (GH-24484) (GH-25205)
    8a34a07

    @ericvsmith
    Copy link
    Member

    New changeset 1744c96 by Eric V. Smith in branch 'master':
    Fix blurb for bpo-43176. (GH-25215)
    1744c96

    @miss-islington
    Copy link
    Contributor

    New changeset 76c4a9f by Miss Islington (bot) in branch '3.8':
    [3.8] Fix blurb for bpo-43176. (GH-25215) (GH-25218)
    76c4a9f

    @ericvsmith
    Copy link
    Member

    New changeset 2df971a by Miss Islington (bot) in branch '3.9':
    Fix blurb for bpo-43176. (GH-25215) (GH-25217)
    2df971a

    @ulope
    Copy link
    Mannequin

    ulope mannequin commented May 6, 2021

    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).

    @ericvsmith
    Copy link
    Member

    Can you provide a small snippet of code showing the kind of thing that broke?

    @ulope
    Copy link
    Mannequin

    ulope mannequin commented May 6, 2021

    @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
    

    @ericvsmith
    Copy link
    Member

    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.

    @ericvsmith ericvsmith reopened this May 7, 2021
    @ericvsmith ericvsmith reopened this May 7, 2021
    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    @ericvsmith
    Copy link
    Member

    I think this was fixed with #109437, so I'm going to close this one.

    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    3.8 only security fixes 3.9 only security fixes 3.10 only security fixes stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    2 participants