1
1
import ast
2
+ import logging
2
3
3
4
from .alias_helper import handle_aliases_in_calls
4
5
from ..core .ast_helper import (
30
31
from .stmt_visitor import StmtVisitor
31
32
from .stmt_visitor_helper import CALL_IDENTIFIER
32
33
34
+ log = logging .getLogger (__name__ )
35
+
33
36
34
37
class ExprVisitor (StmtVisitor ):
35
38
def __init__ (
@@ -52,6 +55,7 @@ def __init__(
52
55
self .undecided = False
53
56
self .function_names = list ()
54
57
self .function_return_stack = list ()
58
+ self .function_definition_stack = list () # used to avoid recursion
55
59
self .module_definitions_stack = list ()
56
60
self .prev_nodes_to_avoid = list ()
57
61
self .last_control_flow_nodes = list ()
@@ -543,6 +547,7 @@ def process_function(self, call_node, definition):
543
547
first_node
544
548
)
545
549
self .function_return_stack .pop ()
550
+ self .function_definition_stack .pop ()
546
551
547
552
return self .nodes [- 1 ]
548
553
@@ -560,11 +565,15 @@ def visit_Call(self, node):
560
565
last_attribute = _id .rpartition ('.' )[- 1 ]
561
566
562
567
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 )
563
571
if isinstance (definition .node , ast .ClassDef ):
564
572
self .add_blackbox_or_builtin_call (node , blackbox = False )
565
573
elif isinstance (definition .node , ast .FunctionDef ):
566
574
self .undecided = False
567
575
self .function_return_stack .append (_id )
576
+ self .function_definition_stack .append (definition )
568
577
return self .process_function (node , definition )
569
578
else :
570
579
raise Exception ('Definition was neither FunctionDef or ' +
0 commit comments