Skip to content

infinite recursion in pylint (new case 2020-12) #3985

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
arielf opened this issue Dec 16, 2020 · 2 comments
Closed

infinite recursion in pylint (new case 2020-12) #3985

arielf opened this issue Dec 16, 2020 · 2 comments
Assignees
Labels
Bug 🪲 Crash 💥 A bug that makes pylint crash
Milestone

Comments

@arielf
Copy link

arielf commented Dec 16, 2020

This case is different than similar cases reported before.

Is your issue fixed on the preview release?: pip install pylint astroid --pre -U
NO, I'm on latest: see below.

Steps to reproduce

python3 in env is 3.7.9

Put the following python code in a file li.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# vim: ts=4 sw=4 expandtab
"""
This causes an infinite recursion in pylint:

    % pylint --version
    pylint 2.6.0
    astroid 2.4.2
    Python 3.7.9 (default, Aug 18 2020, 06:22:45)
    [GCC 7.5.0]
"""
import pandas as pd
from addict import Dict

class Validator(Dict):
    """validator class"""
    def __init__(self, sep=',', filename=None):
        self.sep = sep
        self.filename = filename
        self.df = None

    def fubar(self, **kwargs):
        """
        reproduce pylint inf-recursion
        """
        self.df = pd.read_csv(self.filename, sep=self.sep, **kwargs)

        # problem is triggered here:
        # This doesn't crash:
        #   for fieldname in self.df:
        # But this crashes ('columns' member added by pandas):
        for fieldname in self.df.columns:
            pass

Current behavior

% pylint li.py
Traceback (most recent call last):
  File "/home/user/.local/lib/python3.7/site-packages/astroid/decorators.py", line 32, in cached
    return cache[func]
KeyError: <bound method ClassDef._get_assign_nodes of <ClassDef.DatetimeIndex l.72 at 0x7f9850c228d0>>

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/user/.local/lib/python3.7/site-packages/astroid/decorators.py", line 32, in cached
    return cache[func]
KeyError: <bound method MultiLineBlockMixin._get_assign_nodes of <FunctionDef.get_loc l.577 at 0x7f9850328910>>

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/user/.local/lib/python3.7/site-packages/astroid/decorators.py", line 32, in cached
    return cache[func]
KeyError: <bound method MultiLineBlockMixin._get_assign_nodes of <If l.592 at 0x7f9850240990>>

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/user/.local/lib/python3.7/site-packages/astroid/decorators.py", line 32, in cached
    return cache[func]
KeyError: <bound method MultiLineBlockMixin._get_assign_nodes of <If l.596 at 0x7f9850240e90>>

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/user/.local/lib/python3.7/site-packages/astroid/decorators.py", line 32, in cached
    return cache[func]
KeyError: <bound method MultiLineBlockMixin._get_assign_nodes of <If l.607 at 0x7f9850247190>>

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/user/.local/bin/pylint", line 8, in <module>
    sys.exit(run_pylint())
  File "/home/user/.local/lib/python3.7/site-packages/pylint/__init__.py", line 22, in run_pylint
    PylintRun(sys.argv[1:])
  File "/home/user/.local/lib/python3.7/site-packages/pylint/lint/run.py", line 349, in __init__
    linter.check(args)
  File "/home/user/.local/lib/python3.7/site-packages/pylint/lint/pylinter.py", line 863, in check
    self.get_ast, self._iterate_file_descrs(files_or_modules)
  File "/home/user/.local/lib/python3.7/site-packages/pylint/lint/pylinter.py", line 896, in _check_files
    self._check_file(get_ast, check_astroid_module, name, filepath, modname)
  File "/home/user/.local/lib/python3.7/site-packages/pylint/lint/pylinter.py", line 922, in _check_file
    check_astroid_module(ast_node)
  File "/home/user/.local/lib/python3.7/site-packages/pylint/lint/pylinter.py", line 1055, in check_astroid_module
    ast_node, walker, rawcheckers, tokencheckers
  File "/home/user/.local/lib/python3.7/site-packages/pylint/lint/pylinter.py", line 1099, in _check_astroid_module
    walker.walk(ast_node)
  File "/home/user/.local/lib/python3.7/site-packages/pylint/utils/ast_walker.py", line 75, in walk
    self.walk(child)
  File "/home/user/.local/lib/python3.7/site-packages/pylint/utils/ast_walker.py", line 75, in walk
    self.walk(child)
  File "/home/user/.local/lib/python3.7/site-packages/pylint/utils/ast_walker.py", line 75, in walk
    self.walk(child)
  File "/home/user/.local/lib/python3.7/site-packages/pylint/utils/ast_walker.py", line 72, in walk
    callback(astroid)
  File "/home/user/.local/lib/python3.7/site-packages/pylint/checkers/typecheck.py", line 1825, in visit_for
    self._check_iterable(node.iter)
  File "/home/user/.local/lib/python3.7/site-packages/pylint/checkers/typecheck.py", line 1806, in _check_iterable
    inferred = safe_infer(node)
  File "/home/user/.local/lib/python3.7/site-packages/pylint/checkers/utils.py", line 1143, in safe_infer
    value = next(infer_gen)
  File "/home/user/.local/lib/python3.7/site-packages/astroid/decorators.py", line 132, in raise_if_nothing_inferred
    yield next(generator)
  File "/home/user/.local/lib/python3.7/site-packages/astroid/decorators.py", line 96, in wrapped
    res = next(generator)
  File "/home/user/.local/lib/python3.7/site-packages/astroid/inference.py", line 293, in infer_attribute
    for owner in self.expr.infer(context):
  File "/home/user/.local/lib/python3.7/site-packages/astroid/util.py", line 160, in limit_inference
    yield from islice(iterator, size)
  File "/home/user/.local/lib/python3.7/site-packages/astroid/context.py", line 113, in cache_generator
    for result in generator:
  File "/home/user/.local/lib/python3.7/site-packages/astroid/decorators.py", line 142, in raise_if_nothing_inferred
    yield from generator
  File "/home/user/.local/lib/python3.7/site-packages/astroid/decorators.py", line 96, in wrapped
    res = next(generator)
  File "/home/user/.local/lib/python3.7/site-packages/astroid/inference.py", line 319, in infer_attribute
    yield from owner.igetattr(self.attrname, context)
  File "/home/user/.local/lib/python3.7/site-packages/astroid/bases.py", line 222, in igetattr
    self._wrap_attr(get_attr, context), context, frame=self
  File "/home/user/.local/lib/python3.7/site-packages/astroid/bases.py", line 136, in _infer_stmts
    for inferred in stmt.infer(context=context):
  File "/home/user/.local/lib/python3.7/site-packages/astroid/util.py", line 160, in limit_inference
    yield from islice(iterator, size)
  File "/home/user/.local/lib/python3.7/site-packages/astroid/context.py", line 113, in cache_generator
    for result in generator:
  File "/home/user/.local/lib/python3.7/site-packages/astroid/decorators.py", line 142, in raise_if_nothing_inferred
    yield from generator
  File "/home/user/.local/lib/python3.7/site-packages/astroid/decorators.py", line 96, in wrapped
    res = next(generator)
  File "/home/user/.local/lib/python3.7/site-packages/astroid/bases.py", line 136, in _infer_stmts
    for inferred in stmt.infer(context=context):
  File "/home/user/.local/lib/python3.7/site-packages/astroid/util.py", line 160, in limit_inference
    yield from islice(iterator, size)
  File "/home/user/.local/lib/python3.7/site-packages/astroid/context.py", line 113, in cache_generator
    for result in generator:
  File "/home/user/.local/lib/python3.7/site-packages/astroid/decorators.py", line 142, in raise_if_nothing_inferred
    yield from generator
  File "/home/user/.local/lib/python3.7/site-packages/astroid/decorators.py", line 96, in wrapped
    res = next(generator)
  File "/home/user/.local/lib/python3.7/site-packages/astroid/inference.py", line 233, in infer_call
    yield from callee.infer_call_result(caller=self, context=callcontext)
  File "/home/user/.local/lib/python3.7/site-packages/astroid/scoped_nodes.py", line 1722, in infer_call_result
    yield from returnnode.value.infer(context)
  File "/home/user/.local/lib/python3.7/site-packages/astroid/util.py", line 160, in limit_inference

[hundreds of similar lines trimmed for brevity]

  File "/home/user/.local/lib/python3.7/site-packages/astroid/decorators.py", line 34, in cached
    cache[func] = result = func(*args, **kwargs)
  File "/home/user/.local/lib/python3.7/site-packages/astroid/mixins.py", line 153, in _get_assign_nodes
    return list(itertools.chain.from_iterable(children_assign_nodes))
  File "/home/user/.local/lib/python3.7/site-packages/astroid/mixins.py", line 151, in <genexpr>
    for child_node in block
  File "/home/user/.local/lib/python3.7/site-packages/astroid/decorators.py", line 34, in cached
    cache[func] = result = func(*args, **kwargs)
  File "/home/user/.local/lib/python3.7/site-packages/astroid/mixins.py", line 153, in _get_assign_nodes
    return list(itertools.chain.from_iterable(children_assign_nodes))
  File "/home/user/.local/lib/python3.7/site-packages/astroid/mixins.py", line 151, in <genexpr>
    for child_node in block
  File "/home/user/.local/lib/python3.7/site-packages/astroid/decorators.py", line 34, in cached
    cache[func] = result = func(*args, **kwargs)
  File "/home/user/.local/lib/python3.7/site-packages/astroid/mixins.py", line 150, in _get_assign_nodes
    for block in self._multi_line_blocks
  File "/home/user/.local/lib/python3.7/site-packages/astroid/decorators.py", line 72, in __get__
    val = self.wrapped(inst)
  File "/home/user/.local/lib/python3.7/site-packages/astroid/mixins.py", line 130, in _multi_line_blocks
    return tuple(getattr(self, field) for field in self._multi_line_block_fields)
  File "/home/user/.local/lib/python3.7/site-packages/astroid/mixins.py", line 130, in <genexpr>
    return tuple(getattr(self, field) for field in self._multi_line_block_fields)
RecursionError: maximum recursion depth exceeded while calling a Python object

Expected behavior

pylint issues lint errors but completes without a RecursionError + crash.

pylint --version output

% pylint --version
pylint 2.6.0
astroid 2.4.2
Python 3.7.9 (default, Aug 18 2020, 06:22:45)
[GCC 7.5.0]

@Pierre-Sassoulas
Copy link
Member

I can't reproduce with pandas==1.2.2 and astroid 2.4.2 or 2.5.0 with current pylint or with pylint 2.6.0 or 2.6.2. (except by changing the limit with init-hook='import sys; sys.setrecursionlimit(600)' ). I'm using python 3.8, I'll check with python 3.7 later.

@Pierre-Sassoulas Pierre-Sassoulas modified the milestones: 2.7.0, 2.7.1, 2.7.2 Feb 21, 2021
@Pierre-Sassoulas Pierre-Sassoulas modified the milestones: 2.7.2, 2.7.x Feb 28, 2021
@Pierre-Sassoulas
Copy link
Member

Look like it's fixed with 2.7.2, if you encounter a maximum recursion depth exceeded on pylint > 2.7 with astroid > 2.5.1, please open a new issue.

@Pierre-Sassoulas Pierre-Sassoulas modified the milestones: 2.8.x, 2.8.0 Apr 24, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug 🪲 Crash 💥 A bug that makes pylint crash
Projects
None yet
Development

No branches or pull requests

3 participants