Skip to content

No-field class derived from dataclass_transform base class uses base class's constructor signature #19452

Open

Description

@caoculus

Bug Report

When a class derives from a base class marked with dataclass_transform and the derived class has no fields, mypy incorrectly infers that the derived class does not provide its own constructor. This issue does not happen if the derived class has any fields.

Pyright infers the correct constructor signature here.

To Reproduce

from typing import dataclass_transform, reveal_type

@dataclass_transform()
class Base:
   def __init__( self, a: int ) -> None:
      pass

class DerivedNoFields( Base ):
   pass

class DerivedWithFields( Base ):
   b: str

reveal_type( DerivedNoFields.__init__ )
reveal_type( DerivedWithFields.__init__ )

Playground link

Expected Behavior

main.py:14: note: Revealed type is "def (self: __main__.DerivedNoFields)"
main.py:15: note: Revealed type is "def (self: __main__.DerivedWithFields, b: builtins.str)"

Actual Behavior

main.py:14: note: Revealed type is "def (self: __main__.Base, a: builtins.int)"
main.py:15: note: Revealed type is "def (self: __main__.DerivedWithFields, b: builtins.str)"

Your Environment

  • Mypy version used: 3.16.1
  • Python version used: 3.13
  • No command-line flags or configuration options

Activity

  1. changed the title [-]No-field class derived from `dataclass_transform` base uses base class's constructor signature[/-] [+]No-field class derived from `dataclass_transform` base class uses base class's constructor signature[/+] on Jul 15, 2025
  2. sterliakov commented on Jul 15, 2025

    @sterliakov
    Collaborator

    # If there are no attributes, it may be that the semantic analyzer has not
    # processed them yet. In order to work around this, we can simply skip generating
    # __init__ if there are no attributes, because if the user truly did not define any,
    # then the object default __init__ with an empty signature will be present anyway.
    if (
    decorator_arguments["init"]
    and ("__init__" not in info.names or info.names["__init__"].plugin_generated)
    and attributes
    ):

    There's a wrong premise in this comment, default __init__ is not always applicable. It predates @dataclass_transform and just wasn't noticed before.

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