2929context_manager : Optional [ContextManager ] = None
3030write_line : Optional [Callable [[dict ], None ]] = None
3131
32- FUNCTION_CALL_OP_NAMES = {
33- "CALL_METHOD" ,
34- "CALL_FUNCTION" ,
35- "CALL_FUNCTION_KW" ,
36- "CALL_FUNCTION_EX" ,
37- "LOAD_ATTR" ,
38- "BINARY_SUBSCR" ,
39- }
40-
4132
4233def get_tracer () -> Tracer :
4334 global TRACER
@@ -282,7 +273,6 @@ def log_call(
282273 fn : Callable ,
283274 args : Iterable = (),
284275 kwargs : Mapping [str , Any ] = {},
285- return_type : Any = None ,
286276) -> None :
287277 bound = Bound .create (fn , args , kwargs )
288278 line : Dict = {"location" : location , "function" : preprocess (fn )}
@@ -294,8 +284,6 @@ def log_call(
294284 line ["params" ]["kwargs" ] = {k : preprocess (v ) for k , v in kwargs .items ()}
295285 else :
296286 line ["bound_params" ] = bound .as_dict ()
297- if return_type :
298- line ['return_type' ] = return_type
299287 assert write_line
300288 write_line (line )
301289
@@ -307,16 +295,11 @@ class Stack:
307295 NULL : ClassVar [object ] = object ()
308296 current_i : int = dataclasses .field (init = False , default = 0 )
309297 opcode : int = dataclasses .field (init = False )
310- previous_stack : Optional [Stack ] = None
311- log_call_args : Tuple = ()
312298
313299 def __post_init__ (self ):
314300 self .op_stack = get_stack .OpStack (self .frame )
315301 self .opcode = self .frame .f_code .co_code [self .frame .f_lasti ]
316302
317- if self .previous_stack and self .previous_stack .previous_stack :
318- del self .previous_stack .previous_stack
319-
320303 @property
321304 def oparg (self ):
322305 # sort of replicates logic in dis._unpack_opargs but doesn't account for extended
@@ -377,24 +360,14 @@ def pop_n(self, n: int) -> List:
377360 return l
378361
379362 def process (
380- self ,
381- keyed_args : Tuple ,
382- fn : Callable ,
383- args : Iterable ,
384- kwargs : Mapping = {},
385- delay : bool = False
363+ self , keyed_args : Tuple , fn : Callable , args : Iterable , kwargs : Mapping = {}
386364 ) -> None :
387-
388- # Note: This take args as an iterable, instead of as a varargs, so that if
389- # we don't trace we don't have to expand the iterable
365+ # Note: This take args as an iterable, instead of as a varargs, so that if we don't trace we don't have to expand the iterable
390366 if self .tracer .should_trace (* keyed_args ):
391367 filename = self .frame .f_code .co_filename
392368 line = self .frame .f_lineno
393369 # Don't pass kwargs if not used, so we can more easily test mock calls
394- if not delay :
395- log_call (f"{ filename } :{ line } " , fn , tuple (args ), * ((kwargs ,) if kwargs else ()))
396- else :
397- self .log_call_args = (filename , line , fn , tuple (args ), kwargs )
370+ log_call (f"{ filename } :{ line } " , fn , tuple (args ), * ((kwargs ,) if kwargs else ()))
398371
399372 def __call__ (self ) -> None :
400373 """
@@ -410,34 +383,14 @@ def __call__(self) -> None:
410383 (self .TOS , self .TOS1 ), BINARY_OPS [opname ], (self .TOS1 , self .TOS )
411384 )
412385
413- if self .previous_stack and self .previous_stack .opname in FUNCTION_CALL_OP_NAMES :
414- self .log_called_method ()
415-
416386 method_name = f"op_{ opname } "
417387 if hasattr (self , method_name ):
418388 getattr (self , method_name )()
419389 return None
420390
421- def log_called_method (self ):
422- if self .previous_stack .log_call_args :
423- tos = self .TOS
424- if type (tos ) is type and issubclass (tos , Exception ):
425- # Don't record exception
426- return
427- return_type = type (tos ) if type (tos ) != type else tos
428- filename , line , fn , args , * kwargs = self .previous_stack .log_call_args
429- kwargs = kwargs [0 ] if kwargs else {}
430- log_call (
431- f"{ filename } :{ line } " ,
432- fn ,
433- tuple (args ),
434- * ((kwargs ,) if kwargs else ()),
435- return_type = return_type ,
436- )
437-
438391 # special case subscr b/c we only check first arg, not both
439392 def op_BINARY_SUBSCR (self ):
440- self .process ((self .TOS1 ,), op .getitem , (self .TOS1 , self .TOS ), delay = True )
393+ self .process ((self .TOS1 ,), op .getitem , (self .TOS1 , self .TOS ))
441394
442395 def op_STORE_SUBSCR (self ):
443396 self .process ((self .TOS1 ,), op .setitem , (self .TOS1 , self .TOS , self .TOS2 ))
@@ -446,7 +399,7 @@ def op_DELETE_SUBSCR(self):
446399 self .process ((self .TOS1 ,), op .delitem , (self .TOS1 , self .TOS ))
447400
448401 def op_LOAD_ATTR (self ):
449- self .process ((self .TOS ,), getattr , (self .TOS , self .opvalname ), delay = True )
402+ self .process ((self .TOS ,), getattr , (self .TOS , self .opvalname ))
450403
451404 def op_STORE_ATTR (self ):
452405 self .process ((self .TOS ,), setattr , (self .TOS , self .opvalname , self .TOS1 ))
@@ -505,7 +458,7 @@ def op_COMPARE_OP(self):
505458 def op_CALL_FUNCTION (self ):
506459 args = self .pop_n (self .oparg )
507460 fn = self .pop ()
508- self .process ((fn ,), fn , args , delay = True )
461+ self .process ((fn ,), fn , args )
509462
510463 def op_CALL_FUNCTION_KW (self ):
511464 kwargs_keys = self .pop ()
@@ -515,7 +468,7 @@ def op_CALL_FUNCTION_KW(self):
515468 args = self .pop_n (self .oparg - n_kwargs )
516469 fn = self .pop ()
517470
518- self .process ((fn ,), fn , args , kwargs , delay = True )
471+ self .process ((fn ,), fn , args , kwargs )
519472
520473 def op_CALL_FUNCTION_EX (self ):
521474 has_kwarg = self .oparg & int ("01" , 2 )
@@ -529,21 +482,20 @@ def op_CALL_FUNCTION_EX(self):
529482 fn = self .pop ()
530483 if inspect .isgenerator (args ):
531484 return
532- self .process ((fn ,), fn , args , kwargs , delay = True )
485+ self .process ((fn ,), fn , args , kwargs )
533486
534487 def op_CALL_METHOD (self ):
535488 args = self .pop_n (self .oparg )
536489 function_or_self = self .pop ()
537490 null_or_method = self .pop ()
538491 if null_or_method is self .NULL :
539492 function = function_or_self
540- self .process ((function ,), function , args , delay = True )
493+ self .process ((function ,), function , args )
541494 else :
542495 self_ = function_or_self
543496 method = null_or_method
544497 self .process (
545498 (self_ ,), method , itertools .chain ((self_ ,), args ),
546- delay = True
547499 )
548500
549501
@@ -596,7 +548,6 @@ class Tracer:
596548 calls_to_modules : List [str ]
597549 # the modules we should trace calls from
598550 calls_from_modules : List [str ]
599- previous_stack : Optional [Stack ] = None
600551
601552 def __enter__ (self ):
602553 sys .settrace (self )
@@ -626,13 +577,7 @@ def __call__(self, frame, event, arg) -> Optional[Tracer]:
626577 return None
627578
628579 if self .should_trace_frame (frame ):
629- stack = Stack (
630- self ,
631- frame ,
632- previous_stack = self .previous_stack ,
633- )
634- stack ()
635- self .previous_stack = stack if stack .log_call_args else None
580+ Stack (self , frame )()
636581 return None
637582
638583 def should_trace_frame (self , frame ) -> bool :
0 commit comments