Skip to content
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

Add regression test for #5679 #5725

Merged
merged 2 commits into from
Mar 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,11 @@ Release date: TBA

Closes #5557

* Fixed a crash on ``__init__`` nodes when the attribute was previously uninferable due to a cache
limit size. This limit can be hit when the inheritance pattern of a class (and therefore of the ``__init__`` attribute) is very large.

Closes #5679

* Fix ``unnecessary_dict_index_lookup`` false positive when deleting a dictionary's entry.

Closes #4716
Expand Down
5 changes: 5 additions & 0 deletions doc/whatsnew/2.13.rst
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,11 @@ Other Changes

Closes #5713

* Fixed a crash on ``__init__`` nodes when the attribute was previously uninferable due to a cache
limit size. This limit can be hit when the inheritance pattern of a class (and therefore of the ``__init__`` attribute) is very large.

Closes #5679

* Fixed extremely long processing of long lines with comma's.

Closes #5483
Expand Down
38 changes: 38 additions & 0 deletions tests/regrtest_data/max_inferable_limit_for_classes/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""This example is based on sqlalchemy.

See https://github.com/PyCQA/pylint/issues/5679
"""
from other_funcs import FromClause

from .nodes import roles


class HasMemoized(object):
...


class Generative(HasMemoized):
...


class ColumnElement(
roles.ColumnArgumentOrKeyRole,
roles.BinaryElementRole,
roles.OrderByRole,
roles.ColumnsClauseRole,
roles.LimitOffsetRole,
roles.DMLColumnRole,
roles.DDLConstraintColumnRole,
roles.StatementRole,
Generative,
):
...


class FunctionElement(ColumnElement, FromClause):
...


class months_between(FunctionElement):
def __init__(self):
super().__init__()
82 changes: 82 additions & 0 deletions tests/regrtest_data/max_inferable_limit_for_classes/nodes/roles.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
class SQLRole(object):
...


class UsesInspection(object):
...


class AllowsLambdaRole(object):
...


class ColumnArgumentRole(SQLRole):
...


class ColumnArgumentOrKeyRole(ColumnArgumentRole):
...


class ColumnListRole(SQLRole):
...


class ColumnsClauseRole(AllowsLambdaRole, UsesInspection, ColumnListRole):
...


class LimitOffsetRole(SQLRole):
...


class ByOfRole(ColumnListRole):
...


class OrderByRole(AllowsLambdaRole, ByOfRole):
...


class StructuralRole(SQLRole):
...


class ExpressionElementRole(SQLRole):
...


class BinaryElementRole(ExpressionElementRole):
...


class JoinTargetRole(AllowsLambdaRole, UsesInspection, StructuralRole):
...


class FromClauseRole(ColumnsClauseRole, JoinTargetRole):
...


class StrictFromClauseRole(FromClauseRole):
...


class AnonymizedFromClauseRole(StrictFromClauseRole):
...


class ReturnsRowsRole(SQLRole):
...


class StatementRole(SQLRole):
...


class DMLColumnRole(SQLRole):
...


class DDLConstraintColumnRole(SQLRole):
...
31 changes: 31 additions & 0 deletions tests/regrtest_data/max_inferable_limit_for_classes/other_funcs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from operator import attrgetter

from .nodes import roles


class HasCacheKey(object):
...


class HasMemoized(object):
...


class MemoizedHasCacheKey(HasCacheKey, HasMemoized):
...


class ClauseElement(MemoizedHasCacheKey):
...


class ReturnsRows(roles.ReturnsRowsRole, ClauseElement):
...


class Selectable(ReturnsRows):
...


class FromClause(roles.AnonymizedFromClauseRole, Selectable):
c = property(attrgetter("columns"))
21 changes: 21 additions & 0 deletions tests/test_self.py
Original file line number Diff line number Diff line change
Expand Up @@ -1287,6 +1287,27 @@ def test_regex_paths_csv_validator() -> None:
Run(["--ignore-paths", "test", join(HERE, "regrtest_data", "empty.py")])
assert ex.value.code == 0

@staticmethod
def test_max_inferred_for_complicated_class_hierarchy() -> None:
"""Regression test for a crash reported in https://github.com/PyCQA/pylint/issues/5679.

The class hierarchy of 'sqlalchemy' is so intricate that it becomes uninferable with
the standard max_inferred of 100. We used to crash when this happened.
"""
with pytest.raises(SystemExit) as ex:
Run(
[
join(
HERE,
"regrtest_data",
"max_inferable_limit_for_classes",
"main.py",
),
]
)
# Error code should not include bit-value 1 for crash
assert not ex.value.code % 2

def test_regression_recursive(self):
self._test_output(
[join(HERE, "regrtest_data", "directory", "subdirectory"), "--recursive=n"],
Expand Down