Skip to content

Incorrect argument names for dataclass with "private" (mangled) members #19755

Open

Description

@tmr232

Bug Report

Mypy infers dataclass arguments incorrectly when a class has private (__name) members.

To Reproduce

from dataclasses import dataclass


@dataclass(kw_only=True)
class Data:
    __mangled: int


Data(_Data__mangled=1)  # Runs correctly, but mypy complains
Data(__mangled=1)       # Fails, but mypy approves

https://mypy-play.net/?mypy=latest&python=3.13&gist=f585904f6f5652ee86cd11d6502de13f

Expected Behavior

I expect mypy's behaviour to match the execution and requrie the _Data__mangled argument.
Additionally, I expect it to reject the __mangled argument name as unexpected.

Actual Behavior

main.py:9: error: Unexpected keyword argument "_Data__mangled" for "Data"; did you mean "__mangled"? [call-arg]
Found 1 error in 1 file (checked 1 source file)

Your Environment

I reproduced this on mypy-play.net with Python 3.13

  • Mypy version used: 1.17.1
  • Mypy command-line flags: default mypy-play.net settings
  • Python version used: Python 3.13

Activity

  1. tmr232 commented on Aug 29, 2025

    @tmr232
    Author

    There's also a similar issue with attrs:

    import attrs
    
    
    @attrs.define(kw_only=True)
    class Attr:
        a: int
        _b: int
        __c: int
        __x__: int
    
    
    Attr(a=1, b=2, Attr__c=3, x__=4)  # Valid, but mypy complains
    Attr(a=1, b=2, c=3, x__=4)        # Invalid, but mypy approves
  2. A5rocks commented on Aug 30, 2025

    @A5rocks
    Collaborator

    This is basically #8267 but specifically supporting this for attrs might require more work so I'll keep this open. (e.g. only trimming a single underscore).

  3. added
    topic-runtime-semanticsmypy doesn't model runtime semantics correctly
    and removed
    bugmypy got something wrong
    on Aug 30, 2025
  4. tyralla commented on Sep 1, 2025

    @tyralla
    Collaborator

    Both problems would be fixed by merging #16715.

    [case testNameManglingAttrs]
    import attr
    
    @attr.define(kw_only=True)
    class X:
        a: int
        _b: int
        __c: int
        __d__: int
    
    X(a=1, b=2, X__c=3, d__=4)
    X(a=1, b=2, c=3, d__=4)   # E: Unexpected keyword argument "c" for "X"
    
    x: X
    reveal_type(x.a)  # N: Revealed type is "builtins.int"
    reveal_type(x._b)  # N: Revealed type is "builtins.int"
    reveal_type(x._X__c)  # N: Revealed type is "builtins.int"
    reveal_type(x.__d__)  # N: Revealed type is "builtins.int"
    
    [builtins fixtures/list.pyi]
    
    [case testNameManglingDataclasses]
    from dataclasses import dataclass
    
    @dataclass(kw_only=True)
    class X:
        a: int
        _b: int
        __c: int
        __d__: int
    
    X(a=1, _b=2, _X__c=3, __d__=4)
    X(a=1, _b=2, __c=3, __d__=4)   # E: Unexpected keyword argument "__c" for "X"
    
    x: X
    reveal_type(x.a)  # N: Revealed type is "builtins.int"
    reveal_type(x._b)  # N: Revealed type is "builtins.int"
    reveal_type(x._X__c)  # N: Revealed type is "builtins.int"
    reveal_type(x.__d__)  # N: Revealed type is "builtins.int"
    
    [builtins fixtures/dataclasses.pyi]
    [typing fixtures/typing-medium.pyi]
    

    I will include them as additional test cases. However, the PR has been sleeping for a long time now. A review from someone who has the time to read my lengthy monologue and help fine-tune the different assumptions would be greatly appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions