Skip to content

Commit ed42e0c

Browse files
committed
Pass an inference context to metaclass() when inferring an object type
This should prevent a bunch of recursion errors happening in pylint. Also refactor the inference of `IfExp` nodes to use separate contexts for each potential branch. Close pylint-dev/pylint#3152 Close pylint-dev/pylint#3159
1 parent 0088cc0 commit ed42e0c

File tree

3 files changed

+23
-6
lines changed

3 files changed

+23
-6
lines changed

ChangeLog

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@ Release Date: TBA
1414
Close PyCQA/pylint#3174
1515

1616

17+
* Pass an inference context to `metaclass()` when inferring an object type
18+
19+
This should prevent a bunch of recursion errors happening in pylint.
20+
Also refactor the inference of `IfExp` nodes to use separate contexts
21+
for each potential branch.
22+
23+
Close PyCQA/pylint#3152
24+
Close PyCQA/pylint#3159
25+
26+
1727
What's New in astroid 2.3.1?
1828
============================
1929
Release Date: 2019-09-30

astroid/helpers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def _object_type(node, context=None):
5252
for inferred in node.infer(context=context):
5353
if isinstance(inferred, scoped_nodes.ClassDef):
5454
if inferred.newstyle:
55-
metaclass = inferred.metaclass()
55+
metaclass = inferred.metaclass(context=context)
5656
if metaclass:
5757
yield metaclass
5858
continue

astroid/inference.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -916,21 +916,28 @@ def infer_ifexp(self, context=None):
916916
depending on the condition.
917917
"""
918918
both_branches = False
919+
# We use two separate contexts for evaluating lhs and rhs because
920+
# evaluating lhs may leave some undesired entries in context.path
921+
# which may not let us infer right value of rhs.
922+
923+
context = context or contextmod.InferenceContext()
924+
lhs_context = contextmod.copy_context(context)
925+
rhs_context = contextmod.copy_context(context)
919926
try:
920-
test = next(self.test.infer(context=context))
927+
test = next(self.test.infer(context=context.clone()))
921928
except exceptions.InferenceError:
922929
both_branches = True
923930
else:
924931
if test is not util.Uninferable:
925932
if test.bool_value():
926-
yield from self.body.infer(context=context)
933+
yield from self.body.infer(context=lhs_context)
927934
else:
928-
yield from self.orelse.infer(context=context)
935+
yield from self.orelse.infer(context=rhs_context)
929936
else:
930937
both_branches = True
931938
if both_branches:
932-
yield from self.body.infer(context=context)
933-
yield from self.orelse.infer(context=context)
939+
yield from self.body.infer(context=lhs_context)
940+
yield from self.orelse.infer(context=rhs_context)
934941

935942

936943
nodes.IfExp._infer = infer_ifexp

0 commit comments

Comments
 (0)