Skip to content

private (name mangled) attributes within inherited classes can not have different types #19598

Open

Description

@krcb197

Bug Report

mypy does not recognise that a dunder class attribute does not clash with the inherited one

To Reproduce

Consider the following example:

class BaseSpecialValue:

    def __init__(self, special_value:int):
        self.__special_value = special_value

    @property
    def base_special_value(self) -> int:
        return self.__special_value

class SpecialValue(BaseSpecialValue):

    def __init__(self, base_special_value:int, special_value:str):
        super().__init__(special_value=base_special_value)
        self.__special_value = special_value

    @property
    def special_value(self) -> str:
        return self.__special_value

if __name__ == '__main__':

    foo = SpecialValue(special_value='one', base_special_value=1)
    print(f'special_value={foo.special_value}, base_special_value={foo.base_special_value}')

In this case both SpecialValue and BaseSpecialValue define __special_value, when run it is clear that python treats them separately as the result is:

special_value=one, base_special_value=1

Expected Behavior

No mypy error reported

Actual Behavior

However, when mypy is run the following result is returned by mypy:

mypy --config-file=default_mypy.ini mypy_dunder_test.py   
mypy_dunder_test.py:15: error: Incompatible types in assignment (expression has type "str", variable has type "int")  [assignment]
mypy_dunder_test.py:19: error: Incompatible return value type (got "int", expected "str")  [return-value]
Found 2 errors in 1 file (checked 1 source file)

Your Environment

  • Mypy version used: 1.17.1
  • Mypy command-line flags: None
  • Mypy configuration options from mypy.ini (and other config files): See below
  • Python version used: 3.12.0

default configuration used

# Global options:

[mypy]
warn_return_any = True
warn_unused_configs = True

Activity

  1. sterliakov commented on Aug 6, 2025

    @sterliakov
    Collaborator

    Very similar to #8267 (please note that "dunder attributes" usually refer to __module__ and similar attributes that start and end with two underscores, this is just mangled/private name). Mypy indeed does not fully support name mangling, and we really should.

  2. changed the title [-]dunder attributes within inherited classes can not have different types[/-] [+]private (name mangled) attributes within inherited classes can not have different types[/+] on Aug 6, 2025
  3. krcb197 commented on Aug 6, 2025

    @krcb197
    Author

    @sterliakov

    Thank you for the feedback. I agree that the terminology "dunder" was not quite right. I have updated the description and title to match the terminology used within the Python documentation Private Variables.

  4. krcb197 commented on Aug 6, 2025

    @krcb197
    Author

    I believe this issue was previously fixed but may have regressed, see #6505

    There is even a unit test for the case, see testIgnorePrivateAttributesTypeCheck

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrongtopic-runtime-semanticsmypy doesn't model runtime semantics correctly

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions