Skip to content

Commit

Permalink
Fix object_len infererence without context causing RecursionError (#660)
Browse files Browse the repository at this point in the history
The dropped context was causing RecursionErrors
in self referential assignment

Example:

    self.a = len(self.a)

There is a bigger problem of inference not understanding control flow
that this fix does not solve.

Close pylint-dev/pylint#2736
Close pylint-dev/pylint#2734
Close pylint-dev/pylint#2740
  • Loading branch information
brycepg authored and PCManticore committed Apr 1, 2019
1 parent 70ed2cf commit 3bdec73
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 1 deletion.
7 changes: 7 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ Release Date: TBA
Close PyCQA/pylint#2791


* Fix recursion error involving ``len`` and self referential attributes

Close PyCQA/pylint#2736
Close PyCQA/pylint#2734
Close PyCQA/pylint#2740


What's New in astroid 2.2.0?
============================
Release Date: 2019-02-27
Expand Down
2 changes: 1 addition & 1 deletion astroid/brain/brain_builtin_inference.py
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ def infer_len(node, context=None):
)
[argument_node] = call.positional_arguments
try:
return nodes.Const(helpers.object_len(argument_node))
return nodes.Const(helpers.object_len(argument_node, context=context))
except (AstroidTypeError, InferenceError) as exc:
raise UseInferenceDefault(str(exc)) from exc

Expand Down
20 changes: 20 additions & 0 deletions astroid/tests/unittest_brain.py
Original file line number Diff line number Diff line change
Expand Up @@ -1652,6 +1652,26 @@ def test_len_builtin_inference_attribute_error_str(self):
except astroid.InferenceError:
pass

def test_len_builtin_inference_recursion_error_self_referential_attribute(self):
"""Make sure len calls do not trigger
recursion errors for self referential assignment
See https://github.com/PyCQA/pylint/issues/2734
"""
code = """
class Data:
def __init__(self):
self.shape = []
data = Data()
data.shape = len(data.shape)
data.shape #@
"""
try:
astroid.extract_node(code).inferred()
except RecursionError:
pytest.fail("Inference call should not trigger a recursion error")


def test_infer_str():
ast_nodes = astroid.extract_node(
Expand Down

0 comments on commit 3bdec73

Please sign in to comment.