Skip to content

Crash with AstroidBuildingError when inheriting from a generic dataclass that has __init_subclass__ #10519

@jphells

Description

@jphells

Bug description

I have a file testi.py with the following code:

"""Playground file. Do not commit"""

from abc import ABC
from collections.abc import Callable
from dataclasses import dataclass, field
from typing import ParamSpec

_P = ParamSpec("_P")


@dataclass
class Foo[T](ABC):

    _foo: T | None = field(init=False)
    _bar: dict[str, str] = field(init=False)

    def __init_subclass__(cls) -> None:
        def _wrap(func: Callable[_P, None]) -> Callable[_P, None]:
            def _w(*args: _P.args, **kwds: _P.kwargs) -> None:
                self = args[0]
                func(*args, **kwds)
                if not hasattr(self, "_foo"):
                    object.__setattr__(self, "_foo", None)
                if not hasattr(self, "_bar"):
                    object.__setattr__(self, "_bar", {})

            return _w

        cls.__init__ = _wrap(cls.__init__)  # type: ignore[method-assign]


@dataclass
class Bar(Foo): ...

This crashes pylint with an AstroidBuildingError. I noticed it probably has something to do with my __init_subclass__ -method in class Foo and not having subscribed Foo with a type when defining class Bar. If I either remove __init_subclass__ from Foo or say eg. class Bar(Foo[str]) etc., then pylint does not crash.

Configuration

Command used

pylint testi.py

Pylint output

Traceback (most recent call last):
  File "C:\Users\j\project\venv\Lib\site-packages\pylint\lint\pylinter.py", line 979, in get_ast
    return MANAGER.ast_from_file(filepath, modname, source=True)
           ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\j\project\venv\Lib\site-packages\astroid\manager.py", line 166, in ast_from_file
    return AstroidBuilder(self).file_build(filepath, modname)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
  File "C:\Users\j\project\venv\Lib\site-packages\astroid\builder.py", line 145, in file_build
    return self._post_build(module, builder, encoding)
           ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\j\project\venv\Lib\site-packages\astroid\builder.py", line 173, in _post_build
    module = self._manager.visit_transforms(module)
  File "C:\Users\j\project\venv\Lib\site-packages\astroid\manager.py", line 127, in visit_transforms
    return self._transform.visit(node)
           ~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "C:\Users\j\project\venv\Lib\site-packages\astroid\transforms.py", line 158, in visit
    return self._visit(node)
           ~~~~~~~~~~~^^^^^^
  File "C:\Users\j\project\venv\Lib\site-packages\astroid\transforms.py", line 82, in _visit
    visited = self._visit_generic(value)
  File "C:\Users\j\project\venv\Lib\site-packages\astroid\transforms.py", line 108, in _visit_generic
    return [self._visit_generic(child) for child in node]
            ~~~~~~~~~~~~~~~~~~~^^^^^^^
  File "C:\Users\j\project\venv\Lib\site-packages\astroid\transforms.py", line 115, in _visit_generic
    return self._visit(node)
           ~~~~~~~~~~~^^^^^^
  File "C:\Users\j\project\venv\Lib\site-packages\astroid\transforms.py", line 85, in _visit
    return self._transform(node)
           ~~~~~~~~~~~~~~~^^^^^^
  File "C:\Users\j\project\venv\Lib\site-packages\astroid\transforms.py", line 67, in _transform
    ret = transform_func(node)
  File "C:\Users\j\project\venv\Lib\site-packages\astroid\brain\brain_dataclasses.py", line 84, in dataclass_transform
    init_str = _generate_dataclass_init(
        node,
        list(_get_dataclass_attributes(node, init=True)),
        kw_only_decorated,
    )
  File "C:\Users\j\project\venv\Lib\site-packages\astroid\brain\brain_dataclasses.py", line 249, in _generate_dataclass_init
    prev_pos_only_store, prev_kw_only_store = _find_arguments_from_base_classes(node)
                                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "C:\Users\j\project\venv\Lib\site-packages\astroid\brain\brain_dataclasses.py", line 182, in _find_arguments_from_base_classes
    pos_only, kw_only = base_init.args._get_arguments_data()
                        ^^^^^^^^^^^^^^
AttributeError: 'AssignAttr' object has no attribute 'args'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\j\project\venv\Lib\site-packages\pylint\lint\pylinter.py", line 716, in _get_asts
    ast_per_fileitem[fileitem] = self.get_ast(
                                 ~~~~~~~~~~~~^
        fileitem.filepath, fileitem.name, data
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "C:\Users\j\project\venv\Lib\site-packages\pylint\lint\pylinter.py", line 1001, in get_ast
    raise astroid.AstroidBuildingError(
    ...<2 lines>...
    ) from ex
astroid.exceptions.AstroidBuildingError: Building error when trying to create ast representation of module 'testi'
************* Module testi
testi.py:1:0: F0002: testi.py: Fatal error while checking 'testi.py'. Please open an issue in our bug tracker so we address this. There is a pre-filled template that you can use in 'C:\Users\j\AppData\Local\pylint\pylint\Cache\pylint-crash-2025-08-28-17-42-25.txt'. (astroid-error)

Expected behavior

No crash

Pylint version

pylint 3.3.8
astroid 3.3.11
Python 3.13.5 (tags/v3.13.5:6cb20a2, Jun 11 2025, 16:15:46) [MSC v.1943 64 bit (AMD64)]

OS / Environment

Windows 11 64bit

Additional dependencies

Metadata

Metadata

Assignees

No one assigned

    Labels

    AstroidRelated to astroidCrash 💥A bug that makes pylint crashNeeds PRThis issue is accepted, sufficiently specified and now needs an implementationNeeds astroid updateNeeds an astroid update (probably a release too) before being mergable

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions