Skip to content

Commit 15e1921

Browse files
authored
Fix strong references to mutable objects in context.clone (#927)
1 parent cd8b6a4 commit 15e1921

File tree

5 files changed

+43
-7
lines changed

5 files changed

+43
-7
lines changed

ChangeLog

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ Release Date: TBA
1414
Closes PyCQA/pylint#3970
1515
Closes PyCQA/pylint#3595
1616

17+
* Fix some spurious cycles detected in ``context.path`` leading to more cases
18+
that can now be inferred
19+
20+
Closes #926
21+
1722

1823
What's New in astroid 2.5.6?
1924
============================

astroid/context.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ def clone(self):
102102
starts with the same context but diverge as each side is inferred
103103
so the InferenceContext will need be cloned"""
104104
# XXX copy lookupname/callcontext ?
105-
clone = InferenceContext(self.path, inferred=self.inferred)
105+
clone = InferenceContext(self.path.copy(), inferred=self.inferred.copy())
106106
clone.callcontext = self.callcontext
107107
clone.boundnode = self.boundnode
108108
clone.extra_context = self.extra_context

tests/unittest_brain_numpy_core_umath.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
except ImportError:
1515
HAS_NUMPY = False
1616

17-
from astroid import bases, builder, nodes, util
17+
from astroid import bases, builder, nodes
1818

1919

2020
@unittest.skipUnless(HAS_NUMPY, "This test requires the numpy library.")
@@ -220,9 +220,7 @@ def test_numpy_core_umath_functions_return_type(self):
220220
with self.subTest(typ=func_):
221221
inferred_values = list(self._inferred_numpy_func_call(func_))
222222
self.assertTrue(
223-
len(inferred_values) == 1
224-
or len(inferred_values) == 2
225-
and inferred_values[-1].pytype() is util.Uninferable,
223+
len(inferred_values) == 1,
226224
msg="Too much inferred values ({}) for {:s}".format(
227225
inferred_values[-1].pytype(), func_
228226
),

tests/unittest_inference.py

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1704,7 +1704,8 @@ def __init__(self):
17041704
"""
17051705
ast = extract_node(code, __name__)
17061706
expr = ast.func.expr
1707-
self.assertIs(next(expr.infer()), util.Uninferable)
1707+
with pytest.raises(exceptions.InferenceError):
1708+
next(expr.infer())
17081709

17091710
def test_tuple_builtin_inference(self):
17101711
code = """
@@ -6032,5 +6033,37 @@ def test_infer_list_of_uninferables_does_not_crash():
60326033
assert not inferred.elts
60336034

60346035

6036+
# https://github.com/PyCQA/astroid/issues/926
6037+
def test_issue926_infer_stmts_referencing_same_name_is_not_uninferable():
6038+
code = """
6039+
pair = [1, 2]
6040+
ex = pair[0]
6041+
if 1 + 1 == 2:
6042+
ex = pair[1]
6043+
ex
6044+
"""
6045+
node = extract_node(code)
6046+
inferred = list(node.infer())
6047+
assert len(inferred) == 2
6048+
assert isinstance(inferred[0], nodes.Const)
6049+
assert inferred[0].value == 1
6050+
assert isinstance(inferred[1], nodes.Const)
6051+
assert inferred[1].value == 2
6052+
6053+
6054+
# https://github.com/PyCQA/astroid/issues/926
6055+
def test_issue926_binop_referencing_same_name_is_not_uninferable():
6056+
code = """
6057+
pair = [1, 2]
6058+
ex = pair[0] + pair[1]
6059+
ex
6060+
"""
6061+
node = extract_node(code)
6062+
inferred = list(node.infer())
6063+
assert len(inferred) == 1
6064+
assert isinstance(inferred[0], nodes.Const)
6065+
assert inferred[0].value == 3
6066+
6067+
60356068
if __name__ == "__main__":
60366069
unittest.main()

tests/unittest_regrtest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def test_numpy_crash(self):
9999
astroid = builder.string_build(data, __name__, __file__)
100100
callfunc = astroid.body[1].value.func
101101
inferred = callfunc.inferred()
102-
self.assertEqual(len(inferred), 2)
102+
self.assertEqual(len(inferred), 1)
103103

104104
def test_nameconstant(self):
105105
# used to fail for Python 3.4

0 commit comments

Comments
 (0)