Skip to content

Commit

Permalink
Make use of cache while transform builtin containers
Browse files Browse the repository at this point in the history
Under the certain circumstances invocation of `safe_infer` helper
without a proper context leads to an infinite recursion.

Related: pylint-dev/pylint#3245
Signed-off-by: Stanislav Levin <slev@altlinux.org>
  • Loading branch information
stanislavlevin committed Dec 22, 2019
1 parent 1cce208 commit d2f6469
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 2 deletions.
7 changes: 5 additions & 2 deletions astroid/brain/brain_builtin_inference.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,15 +169,17 @@ def _container_generic_inference(node, context, node_type, transform):
return transformed


def _container_generic_transform(arg, klass, iterables, build_elts):
def _container_generic_transform(arg, context, klass, iterables, build_elts):
if isinstance(arg, klass):
return arg
elif isinstance(arg, iterables):
if all(isinstance(elt, nodes.Const) for elt in arg.elts):
elts = [elt.value for elt in arg.elts]
else:
# TODO: Does not handle deduplication for sets.
elts = filter(None, map(helpers.safe_infer, arg.elts))
elts = filter(None,
map(partial(helpers.safe_infer, context=context), arg.elts)
)
elif isinstance(arg, nodes.Dict):
# Dicts need to have consts as strings already.
if not all(isinstance(elt[0], nodes.Const) for elt in arg.items):
Expand All @@ -197,6 +199,7 @@ def _infer_builtin_container(
):
transform_func = partial(
_container_generic_transform,
context=context,
klass=klass,
iterables=iterables,
build_elts=build_elts,
Expand Down
13 changes: 13 additions & 0 deletions tests/unittest_inference.py
Original file line number Diff line number Diff line change
Expand Up @@ -5502,5 +5502,18 @@ class A:
assert inferred.value == 42


def test_recursion_error_inferring_builtin_containers():
node = extract_node(
"""
class Foo:
a = "foo"
inst = Foo()
b = tuple([inst.a]) #@
inst.a = b
""")
helpers.safe_infer(node.targets[0])


if __name__ == "__main__":
unittest.main()

0 comments on commit d2f6469

Please sign in to comment.