11import ast
2+ import logging
23
34from .alias_helper import handle_aliases_in_calls
45from ..core .ast_helper import (
3031from .stmt_visitor import StmtVisitor
3132from .stmt_visitor_helper import CALL_IDENTIFIER
3233
34+ log = logging .getLogger (__name__ )
35+
3336
3437class ExprVisitor (StmtVisitor ):
3538 def __init__ (
@@ -52,6 +55,7 @@ def __init__(
5255 self .undecided = False
5356 self .function_names = list ()
5457 self .function_return_stack = list ()
58+ self .function_definition_stack = list () # used to avoid recursion
5559 self .module_definitions_stack = list ()
5660 self .prev_nodes_to_avoid = list ()
5761 self .last_control_flow_nodes = list ()
@@ -543,6 +547,7 @@ def process_function(self, call_node, definition):
543547 first_node
544548 )
545549 self .function_return_stack .pop ()
550+ self .function_definition_stack .pop ()
546551
547552 return self .nodes [- 1 ]
548553
@@ -560,11 +565,15 @@ def visit_Call(self, node):
560565 last_attribute = _id .rpartition ('.' )[- 1 ]
561566
562567 if definition :
568+ if definition in self .function_definition_stack :
569+ log .debug ("Recursion encountered in function %s" , _id )
570+ return self .add_blackbox_or_builtin_call (node , blackbox = True )
563571 if isinstance (definition .node , ast .ClassDef ):
564572 self .add_blackbox_or_builtin_call (node , blackbox = False )
565573 elif isinstance (definition .node , ast .FunctionDef ):
566574 self .undecided = False
567575 self .function_return_stack .append (_id )
576+ self .function_definition_stack .append (definition )
568577 return self .process_function (node , definition )
569578 else :
570579 raise Exception ('Definition was neither FunctionDef or ' +
0 commit comments