From fba7aa120b77390edb189a9316d5fb4556886f61 Mon Sep 17 00:00:00 2001 From: Dmitry Pribysh Date: Wed, 21 Oct 2015 16:07:05 +0300 Subject: Add unit test that crashes inference with 'maximum call depth exceeded' error. --- astroid/tests/unittest_inference.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/astroid/tests/unittest_inference.py b/astroid/tests/unittest_inference.py index 6756838..cd27962 100644 --- a/astroid/tests/unittest_inference.py +++ b/astroid/tests/unittest_inference.py @@ -1018,6 +1018,18 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): self.assertEqual(len(inferred), 1) self.assertEqual(inferred[0], util.YES) + def test_binary_op_on_self(self): + 'test correct handling of applying binary operator to self' + code = ''' + import sys + sys.path = ['foo'] + sys.path + sys.path.insert(0, 'bar') + path = sys.path + ''' + ast = parse(code, __name__) + inferred = ast['path'].inferred() + self.assertIsInstance(inferred[0], nodes.List) + def test_binary_op_tuple_add(self): ast = builder.string_build('a = (1,) + (2,)', __name__, __file__) inferred = list(ast['a'].infer()) -- cgit v1.2.1 From 6b2f28cf6f4d83112a60946d6dcaa0d889dd516e Mon Sep 17 00:00:00 2001 From: Dmitry Pribysh Date: Wed, 21 Oct 2015 16:16:01 +0300 Subject: Fix binary operation inference crash by using cloned contexts Idea is that we shouldn't use the same context to infer left-hand side and right-hand side of the binary operation because inferring lhs may leave some metadata in context.path that is irrelevant (and can even break inference) to inference of rhs. So we make two clones of the original context and use them to infer left-hand side and right-hand side independently. And then we use the original context to infer the result of the operation applied to inferred values. This patch fixes pylint's issue #646 and may be also related to other similar astroid issues (#198, #199). --- astroid/inference.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/astroid/inference.py b/astroid/inference.py index 010607c..16d5311 100644 --- a/astroid/inference.py +++ b/astroid/inference.py @@ -575,18 +575,18 @@ def _infer_binop(self, context): right = self.right op = self.op - for lhs in left.infer(context=context): + # we use two separate contexts for evaluating lhs and rhs because + # 1. evaluating lhs may leave some undesired entries in context.path + # which may not let us infer right value of rhs + lhs_context = context.clone() + rhs_context = context.clone() + + for lhs in left.infer(context=lhs_context): if lhs is util.YES: # Don't know how to process this. yield util.YES return - # TODO(cpopa): if we have A() * A(), trying to infer - # the rhs with the same context will result in an - # inferrence 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 right.infer(context=rhs_context): if rhs is util.YES: # Don't know how to process this. -- cgit v1.2.1