Skip to content

RecursionError: maximum recursion depth exceeded while linting a large chained method calls #8842

@yilei

Description

@yilei

Bug description

When parsing the following file:

from a import b

(
    b.builder('name')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .add('name', value='value')
    .Build()
)

Configuration

No response

Command used

pylint t.py

Pylint output

Traceback (most recent call last):
  File "pylint/lint/pylinter.py", line 1044, in get_ast
    return MANAGER.ast_from_file(filepath, modname, source=True)
  File "astroid/manager.py", line 124, in ast_from_file
    return AstroidBuilder(self).file_build(filepath, modname)
  File "astroid/builder.py", line 145, in file_build
    return self._post_build(module, builder, encoding)
  File "astroid/builder.py", line 173, in _post_build
    module = self._manager.visit_transforms(module)
  File "astroid/manager.py", line 95, in visit_transforms
    return self._transform.visit(node)
  File "astroid/transforms.py", line 89, in visit
    return self._visit(module)
  File "astroid/transforms.py", line 54, in _visit
    visited = self._visit_generic(value)
  File "astroid/transforms.py", line 61, in _visit_generic
    return [self._visit_generic(child) for child in node]
  File "astroid/transforms.py", line 61, in <listcomp>
    return [self._visit_generic(child) for child in node]
  File "astroid/transforms.py", line 67, in _visit_generic
    return self._visit(node)
  File "astroid/transforms.py", line 54, in _visit
    visited = self._visit_generic(value)
  File "astroid/transforms.py", line 67, in _visit_generic
    return self._visit(node)
  File "astroid/transforms.py", line 54, in _visit
    visited = self._visit_generic(value)
  File "astroid/transforms.py", line 67, in _visit_generic
    return self._visit(node)
  File "astroid/transforms.py", line 54, in _visit
    visited = self._visit_generic(value)
  File "astroid/transforms.py", line 67, in _visit_generic
    return self._visit(node)
  File "astroid/transforms.py", line 54, in _visit
    visited = self._visit_generic(value)
  File "astroid/transforms.py", line 67, in _visit_generic
    return self._visit(node)
  File "astroid/transforms.py", line 54, in _visit
    visited = self._visit_generic(value)
  File "astroid/transforms.py", line 67, in _visit_generic
    return self._visit(node)

  <.... SKIPPED ....>

  File "astroid/transforms.py", line 54, in _visit
    visited = self._visit_generic(value)
  File "astroid/transforms.py", line 67, in _visit_generic
    return self._visit(node)
  File "astroid/transforms.py", line 54, in _visit
    visited = self._visit_generic(value)
  File "astroid/transforms.py", line 67, in _visit_generic
    return self._visit(node)
  File "astroid/transforms.py", line 54, in _visit
    visited = self._visit_generic(value)
  File "astroid/transforms.py", line 67, in _visit_generic
    return self._visit(node)
  File "astroid/transforms.py", line 54, in _visit
    visited = self._visit_generic(value)
  File "astroid/transforms.py", line 67, in _visit_generic
    return self._visit(node)
  File "astroid/transforms.py", line 54, in _visit
    visited = self._visit_generic(value)
  File "astroid/transforms.py", line 67, in _visit_generic
    return self._visit(node)
  File "astroid/transforms.py", line 54, in _visit
    visited = self._visit_generic(value)
  File "astroid/transforms.py", line 67, in _visit_generic
    return self._visit(node)
  File "astroid/transforms.py", line 57, in _visit
    return self._transform(node)
  File "astroid/transforms.py", line 38, in _transform
    if predicate is None or predicate(node):
  File "astroid/brain/brain_builtin_inference.py", line 141, in _builtin_filter_predicate
    and node.root().name == "re"
  File "astroid/nodes/node_ng.py", line 371, in root
    return self.parent.root()
  File "astroid/nodes/node_ng.py", line 371, in root
    return self.parent.root()
  File "astroid/nodes/node_ng.py", line 371, in root
    return self.parent.root()
  [Previous line repeated 319 more times]
RecursionError: maximum recursion depth exceeded

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

Traceback (most recent call last):
  File "pylint/lint/pylinter.py", line 730, in _get_asts
    ast_per_fileitem[fileitem] = self.get_ast(
  File "pylint/lint/pylinter.py", line 1066, in get_ast
    raise astroid.AstroidBuildingError(
astroid.exceptions.AstroidBuildingError: Building error when trying to create ast representation of module 't'

Expected behavior

It should not crash.

Pylint version

pylint 2.17.4
astroid 2.15.5
Python 3.10.8 (main, Mar  9 2023, 10:11:52) [GCC 12.2.0]

OS / Environment

No response

Additional dependencies

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Crash 💥A bug that makes pylint crash

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions