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

Cannot specify weakref_slot=True twice in dataclass MRO #93521

Closed
Bluenix2 opened this issue Jun 5, 2022 · 5 comments · Fixed by #93535
Closed

Cannot specify weakref_slot=True twice in dataclass MRO #93521

Bluenix2 opened this issue Jun 5, 2022 · 5 comments · Fixed by #93535
Assignees
Labels
3.11 stdlib type-bug

Comments

@Bluenix2
Copy link
Contributor

@Bluenix2 Bluenix2 commented Jun 5, 2022

Summary

If a child dataclass of a parent dataclass who specified weakref_slot, also decides to set weakref_slot to True, Python will raise a TypeError as seen below:

TypeError: __weakref__ slot disallowed: either we already got one, or __itemsize__ != 0

Description

I am porting dataclasses' slots and weakref slots kwargs into a decorator I can use. While doing so, I decided to change the default of the weakref_slot because I would like all of my classes to be weakref:able. This is when I ran into the issue which can be reproduced by the code below:

from dataclasses import dataclass


@dataclass(slots=True, weakref_slot=True)
class A:
    field: str


@dataclass(slots=True, weakref_slot=True)
class B(A):
    ...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "C:\Users\%username%\Projects\testing\copyclasses.py", line 1207, in wrap
    return _process_class(cls, init, repr, eq, order, unsafe_hash,
  File "C:\Users\%username%\Projects\testing\copyclasses.py", line 1108, in _process_class
    cls = _add_slots(cls, frozen, weakref_slot)
  File "C:\Users\%username%\Projects\testing\copyclasses.py", line 1176, in _add_slots    
    cls = type(cls)(cls.__name__, cls.__bases__, cls_dict)
TypeError: __weakref__ slot disallowed: either we already got one, or __itemsize__ != 0

Environment

This was tested by creating a file named copyclasses.py with the current contents of Lib/dataclasses.py ran using a 3.10 CPython interpreter. Note that I've restored the naming of the module in the codeblock above assuming those who will be running it will have a built 3.11 CPython interpreter.


Footnotes: I will mention @ericvsmith as the code owner of the dataclasses file.

@Bluenix2 Bluenix2 added the type-bug label Jun 5, 2022
@AlexWaygood AlexWaygood added the stdlib label Jun 5, 2022
@ericvsmith
Copy link
Member

@ericvsmith ericvsmith commented Jun 5, 2022

Here's an example of the same thing without dataclasses:

class A:
    __slots__='__weakref__'

class B(A):
    __slots__='__weakref__'
Traceback (most recent call last):
  File "gh-93521.py", line 4, in <module>
    class B(A):
TypeError: __weakref__ slot disallowed: either we already got one, or __itemsize__ != 0

@ericvsmith
Copy link
Member

@ericvsmith ericvsmith commented Jun 5, 2022

I'm not sure this is a bug, just the way things work.

@JelleZijlstra
Copy link
Member

@JelleZijlstra JelleZijlstra commented Jun 6, 2022

It would be nice if dataclasses took care of this issue automatically though.

Example scenario: I have a library in which I expose a dataclass. A user subclasses my class in another dataclass, and wants to use weakrefs, so they use weakref_slots. Then I change my library to allow weakrefs on the base class, but now the user's child class is broken.

@Bluenix2
Copy link
Contributor Author

@Bluenix2 Bluenix2 commented Jun 6, 2022

Locally I fixed this already, and I am planning on opening a PR with an added test. Should that PR point to main or the 3.11 branch (seeing as both branches should get the patch)?

@ericvsmith
Copy link
Member

@ericvsmith ericvsmith commented Jun 6, 2022

main

Bluenix2 added a commit to Bluenix2/cpython that referenced this issue Jun 6, 2022
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Jun 8, 2022
…sent in bases (pythonGH-93535)

(cherry picked from commit 5849af7)

Co-authored-by: Bluenix <bluenixdev@gmail.com>
miss-islington added a commit that referenced this issue Jun 8, 2022
…n bases (GH-93535)

(cherry picked from commit 5849af7)

Co-authored-by: Bluenix <bluenixdev@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.11 stdlib type-bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants