Skip to content
Snippets Groups Projects
Commit 3fae32f9 authored by Bryce Guinta's avatar Bryce Guinta
Browse files

Fix augassign recursion error

The augmented assign rhs context path was deleted most likely
due to a recently fixed inference bug where InferenceContext path
attributes were shared between objects.

Recursive functions on the right hand side of the augmented assign would
forget that they were already called, causing an eventual RecursionError
in astroid inference

Now that the InferenceContext clone() method properly copies the
inference path between Contexts, it's fine to remove this hack.

Fixes #437, Fixes #447, Fixes #313, Fixes PyCQA/pylint#1642, Fixes PyCQA/pylint#1805, Fixes PyCQA/pylint#1854, Fixes PyCQA/pylint#1452
parent 53516228
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -38,6 +38,10 @@ Change log for the astroid package (used to be astng)
 
* Include new hashlib classes added in python 3.6
 
* Fix RecursionError for augmented assign
Close #437, #447, #313, PyCQA/pylint#1642, PyCQA/pylint#1805, PyCQA/pylint#1854, PyCQA/pylint#1452
 
2017-12-15 -- 1.6.0
 
Loading
Loading
Loading
Loading
@@ -713,12 +713,7 @@ def _infer_augassign(self, context=None):
yield util.Uninferable
return
 
# TODO(cpopa): if we have A() * A(), trying to infer
# the rhs with the same context will result in an
# inference error, so we create another context for it.
# This is a bug which should be fixed in InferenceContext at some point.
rhs_context = context.clone()
rhs_context.path = set()
for rhs in self.value.infer(context=rhs_context):
if rhs is util.Uninferable:
# Don't know how to process this.
Loading
Loading
Loading
Loading
@@ -4329,5 +4329,24 @@ class ObjectDunderNewTest(unittest.TestCase):
self.assertIsInstance(inferred, Instance)
 
 
def test_augassign_recursion():
"""Make sure inference doesn't throw a RecursionError
Regression test for augmented assign dropping context.path
causing recursion errors
"""
# infinitely recurses in python
code = """
def rec():
a = 0
a += rec()
return a
rec()
"""
cls_node = extract_node(code)
assert next(cls_node.infer()) is util.Uninferable
if __name__ == '__main__':
unittest.main()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment