1010from _appmap import wrapt
1111
1212from .env import Env
13- from .utils import FnType
13+ from .utils import FnType , Scope
1414
1515logger = Env .current .getLogger (__name__ )
1616
1717
18- Filterable = namedtuple ("Filterable" , "fqname obj" )
18+ Filterable = namedtuple ("Filterable" , "scope fqname obj" )
1919
2020
2121class FilterableMod (Filterable ):
2222 __slots__ = ()
2323
2424 def __new__ (cls , mod ):
2525 fqname = mod .__name__
26- return super (FilterableMod , cls ).__new__ (cls , fqname , mod )
27-
28- def classify_fn (self , _ ):
29- return FnType .MODULE
26+ return super (FilterableMod , cls ).__new__ (cls , Scope .MODULE , fqname , mod )
3027
3128
3229class FilterableCls (Filterable ):
3330 __slots__ = ()
3431
3532 def __new__ (cls , clazz ):
3633 fqname = "%s.%s" % (clazz .__module__ , clazz .__qualname__ )
37- return super (FilterableCls , cls ).__new__ (cls , fqname , clazz )
38-
39- def classify_fn (self , static_fn ):
40- return FnType .classify (static_fn )
34+ return super (FilterableCls , cls ).__new__ (cls , Scope .CLASS , fqname , clazz )
4135
4236
4337class FilterableFn (
4438 namedtuple (
4539 "FilterableFn" ,
46- Filterable ._fields
47- + (
48- "scope" ,
49- "static_fn" ,
50- ),
40+ Filterable ._fields + ("static_fn" ,),
5141 )
5242):
5343 __slots__ = ()
5444
5545 def __new__ (cls , scope , fn , static_fn ):
5646 fqname = "%s.%s" % (scope .fqname , fn .__name__ )
57- self = super (FilterableFn , cls ).__new__ (cls , fqname , fn , scope , static_fn )
47+ self = super (FilterableFn , cls ).__new__ (cls , scope . scope , fqname , fn , static_fn )
5848 return self
5949
6050 @property
6151 def fntype (self ):
62- return self .scope .classify_fn (self .static_fn )
52+ if self .scope == Scope .MODULE :
53+ return FnType .MODULE
54+
55+ return FnType .classify (self .static_fn )
6356
6457
6558class Filter (ABC ): # pylint: disable=too-few-public-methods
@@ -161,6 +154,17 @@ def initialize(cls):
161154 def use_filter (cls , filter_class ):
162155 cls .filter_stack .append (filter_class )
163156
157+ @classmethod
158+ def instrument_function (cls , fn_name , filterableFn : FilterableFn , selected_functions = None ):
159+ # Only instrument the function if it was specifically called out for the package
160+ # (e.g. because it should be labeled), or it's included by the filters
161+ matched = cls .filter_chain .filter (filterableFn )
162+ selected = selected_functions and fn_name in selected_functions
163+ if selected or matched :
164+ return cls .filter_chain .wrap (filterableFn )
165+
166+ return filterableFn .obj
167+
164168 @classmethod
165169 def do_import (cls , * args , ** kwargs ):
166170 mod = args [0 ]
@@ -177,15 +181,10 @@ def instrument_functions(filterable, selected_functions=None):
177181 logger .trace (" functions %s" , functions )
178182
179183 for fn_name , static_fn , fn in functions :
180- # Only instrument the function if it was specifically called out for the package
181- # (e.g. because it should be labeled), or it's included by the filters
182184 filterableFn = FilterableFn (filterable , fn , static_fn )
183- matched = cls .filter_chain .filter (filterableFn )
184- selected = selected_functions and fn_name in selected_functions
185- if selected or matched :
186- new_fn = cls .filter_chain .wrap (filterableFn )
187- if fn != new_fn :
188- wrapt .wrap_function_wrapper (filterable .obj , fn_name , new_fn )
185+ new_fn = cls .instrument_function (fn_name , filterableFn , selected_functions )
186+ if new_fn != fn :
187+ wrapt .wrap_function_wrapper (filterable .obj , fn_name , new_fn )
189188
190189 # Import Config here, to avoid circular top-level imports.
191190 from .configuration import Config # pylint: disable=import-outside-toplevel
0 commit comments