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 and __slots__ - non-default argument (member_descriptor) #77281

Closed
starhel mannequin opened this issue Mar 19, 2018 · 8 comments
Closed

dataclasses and __slots__ - non-default argument (member_descriptor) #77281

starhel mannequin opened this issue Mar 19, 2018 · 8 comments
Assignees
Labels
3.7 (EOL) end of life 3.8 only security fixes stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@starhel
Copy link
Mannequin

starhel mannequin commented Mar 19, 2018

BPO 33100
Nosy @ericvsmith, @starhel
PRs
  • bpo-33100: Dataclasses now handles __slots__ and default values correctly. #6152
  • [3.7] bpo-33100: Dataclasses now handles __slots__ and default values correctly. (GH-6152) #6153
  • 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 = <Date 2018-03-20.01:39:18.166>
    created_at = <Date 2018-03-19.03:30:15.896>
    labels = ['3.7', '3.8', 'type-bug', 'library']
    title = 'dataclasses and __slots__ - non-default argument (member_descriptor)'
    updated_at = <Date 2018-03-20.01:39:18.166>
    user = 'https://github.com/starhel'

    bugs.python.org fields:

    activity = <Date 2018-03-20.01:39:18.166>
    actor = 'eric.smith'
    assignee = 'eric.smith'
    closed = True
    closed_date = <Date 2018-03-20.01:39:18.166>
    closer = 'eric.smith'
    components = ['Library (Lib)']
    creation = <Date 2018-03-19.03:30:15.896>
    creator = 'stachel'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 33100
    keywords = ['patch']
    message_count = 8.0
    messages = ['314077', '314087', '314090', '314091', '314121', '314122', '314124', '314128']
    nosy_count = 2.0
    nosy_names = ['eric.smith', 'stachel']
    pr_nums = ['6152', '6153']
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue33100'
    versions = ['Python 3.7', 'Python 3.8']

    @starhel
    Copy link
    Mannequin Author

    starhel mannequin commented Mar 19, 2018

    I've tried to declare two classes

    @dataclass
    class Base:
        __slots__ = ('x',)
        x: Any
    
    
    @dataclass
    class Derived(Base):
        x: int
        y: int

    As long as I correctly understood PEP-557 (inheritance part), changing type of variable is possible. This code produce error:

    TypeError: non-default argument 'y' follows default argument

    'x' variable in Derived class has changed default from MISSING to member_descriptor and that's the reason of the exception.

    @starhel starhel mannequin added 3.7 (EOL) end of life 3.8 only security fixes stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error labels Mar 19, 2018
    @ericvsmith
    Copy link
    Member

    This is the same reason that this fails:

    class Base:
        __slots__ = ('x',)
        x = 3

    with:
    ValueError: 'x' in __slots__ conflicts with class variable

    In the dataclasses case, the error needs to be improved, and moved to when the base class is being defined.

    @starhel
    Copy link
    Mannequin Author

    starhel mannequin commented Mar 19, 2018

    I don't really get your point.

    @dataclass
    class Base:
        __slots__ = ('x',)
        x: Any

    This case is described in PEP-557 as correct, so I don't understand why you want to generate error. Also inheritance without defining slots is correct as stated in data model.

    In my opinion, member_descriptor should be treated same as MISSING and everything should work correctly.

    @ericvsmith
    Copy link
    Member

    My point is that the problem is that after:

    @dataclass
    class Base:
        __slots__ = ('x',)
        x: Any

    Base.x has a value (it's the member_descriptor for x). That's what's causing the problem that when adding a field to the derived class, it thinks you're adding a field without a default value after one that has a default value.

    I agree that I could detect this specific case and allow it. My comment about the error message was inaccurate.

    @starhel
    Copy link
    Mannequin Author

    starhel mannequin commented Mar 19, 2018

    There's also another major problem. Because Base.x has value, __init__ is not prepared correctly (member_descriptor is passed as default).

    @dataclass
    class Base:
        __slots__ = ('x',)
        x: Any
    
    Base()  # No TypeError exception

    Fixing this should be quite easy, if you want I can prepare PR.

    @ericvsmith
    Copy link
    Member

    Thanks, but I'm already looking at this in the context of a different bug.

    @ericvsmith
    Copy link
    Member

    New changeset 7389fd9 by Eric V. Smith in branch 'master':
    bpo-33100: Dataclasses now handles __slots__ and default values correctly. (GH-6152)
    7389fd9

    @ericvsmith
    Copy link
    Member

    New changeset 3d41f48 by Eric V. Smith (Miss Islington (bot)) in branch '3.7':
    bpo-33100: Dataclasses now handles __slots__ and default values correctly. (GH-6152) (GH-6153)
    3d41f48

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    3.7 (EOL) end of life 3.8 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

    1 participant