diff options
author | Bryce Guinta <bryce.guinta@protonmail.com> | 2020-06-22 02:22:16 -0400 |
---|---|---|
committer | Bryce Guinta <bryce.guinta@protonmail.com> | 2020-06-23 22:16:21 -0400 |
commit | 25384d4bebf0187b6704c818c7df64945793362c (patch) | |
tree | da56f7e09c07a735294f6c36141aecfb72356c64 /astroid/helpers.py | |
parent | ec96745c0fdb9432549d182e381164d1836e8a4b (diff) | |
download | astroid-git-25384d4bebf0187b6704c818c7df64945793362c.tar.gz |
Squash one-off inference utility functions to help reduce recursion errors (#804)
This also makes debugging a lot simpler reducing the complexity of the
function stack.
Diffstat (limited to 'astroid/helpers.py')
-rw-r--r-- | astroid/helpers.py | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/astroid/helpers.py b/astroid/helpers.py index 8ab68799..a7764d7a 100644 --- a/astroid/helpers.py +++ b/astroid/helpers.py @@ -237,13 +237,31 @@ def object_len(node, context=None): :raises AstroidTypeError: If an invalid node is returned from __len__ method or no __len__ method exists :raises InferenceError: If the given node cannot be inferred - or if multiple nodes are inferred + or if multiple nodes are inferred or if the code executed in python + would result in a infinite recursive check for length :rtype int: Integer length of node """ # pylint: disable=import-outside-toplevel; circular import from astroid.objects import FrozenSet inferred_node = safe_infer(node, context=context) + + # prevent self referential length calls from causing a recursion error + # see https://github.com/PyCQA/astroid/issues/777 + node_frame = node.frame() + if ( + isinstance(node_frame, scoped_nodes.FunctionDef) + and node_frame.name == "__len__" + and inferred_node._proxied == node_frame.parent + ): + message = ( + "Self referential __len__ function will " + "cause a RecursionError on line {} of {}".format( + node.lineno, node.root().file + ) + ) + raise exceptions.InferenceError(message) + if inferred_node is None or inferred_node is util.Uninferable: raise exceptions.InferenceError(node=node) if isinstance(inferred_node, nodes.Const) and isinstance( |