summaryrefslogtreecommitdiff
path: root/astroid/helpers.py
diff options
context:
space:
mode:
authorBryce Guinta <bryce.guinta@protonmail.com>2020-06-22 02:22:16 -0400
committerBryce Guinta <bryce.guinta@protonmail.com>2020-06-23 22:16:21 -0400
commit25384d4bebf0187b6704c818c7df64945793362c (patch)
treeda56f7e09c07a735294f6c36141aecfb72356c64 /astroid/helpers.py
parentec96745c0fdb9432549d182e381164d1836e8a4b (diff)
downloadastroid-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.py20
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(