Sections
Timeline
View Tickets
New Ticket
Sub-Sections
Download
Unified Diff
Zip Archive
Metanav
Preferences
About Trac
Links
Slowchop Studios
Gerald Kaszuba
Advertisement

Changeset 16 for trunk/pycallgraph.py

Show
Ignore:
Timestamp:
13/02/07 23:33:45 (2 years ago)
Author:
gak
Message:

callback filter patch by Alec Thomas

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/pycallgraph.py

    r11 r16  
    3737 
    3838reset_trace() 
     39 
     40trace_filter = None 
    3941 
    4042# graphviz settings 
     
    5961    'node_color': lambda calls, : '%f %f %f' % (calls / 2 + .5, calls, 0.9), 
    6062    'edge_color': lambda calls, : '%f %f %f' % (calls / 2 + .5, calls, 0.7), 
    61     'exclude_module': [], 
    62     'exclude_class': [], 
    63     'exclude_func': [], 
    64     'exclude_specific': ['stop_trace', 'make_graph'], 
    65     'include_module': [], 
    66     'include_class': [], 
    67     'include_func': [], 
    68     'include_specific': [], 
    6963    'dont_exclude_anything': False, 
    7064} 
     
    7367    pass 
    7468 
    75 def start_trace(reset=True): 
     69class GlobbingFilter(object): 
     70    """Filter module names using a set of globs. 
     71 
     72    Objects are matched against the exclude list first, then the include list. 
     73    Anything that passes through without matching either, is excluded.""" 
     74    def __init__(self, include=None, exclude=None, max_depth=None): 
     75        if include is None and exclude is None: 
     76            include = ['*'] 
     77            exclude = [] 
     78        elif include is None: 
     79            include = ['*'] 
     80        elif exclude is None: 
     81            exclude = [] 
     82        self.include = include 
     83        self.exclude = exclude 
     84        self.max_depth = max_depth or 9999 
     85 
     86    def __call__(self, call_stack, module_name, class_name, func_name, 
     87    full_name): 
     88        from fnmatch import fnmatch 
     89        if len(call_stack) > self.max_depth: 
     90            return False 
     91        for pattern in self.exclude: 
     92            if fnmatch(full_name, pattern): 
     93                return False 
     94        for pattern in self.include: 
     95            if fnmatch(full_name, pattern): 
     96                return True 
     97        return False 
     98 
     99def start_trace(reset=True, filter=None): 
     100    global trace_filter 
    76101    if reset: 
    77102        reset_trace() 
     103    if filter is None: 
     104        trace_filter = GlobbingFilter(exclude=['pycallgraph.*']) 
     105    else: 
     106        trace_filter = filter 
    78107    sys.settrace(tracer) 
    79108 
     
    82111 
    83112def tracer(frame, event, arg): 
    84     global func_count_max 
     113    global func_count_max, trace_filter 
    85114 
    86115    if event == 'call': 
    87         dont_keep = False 
     116        keep = True 
    88117        code = frame.f_code 
    89118    
     
    94123            if module_name == '__main__': 
    95124                module_name = '' 
    96             else: 
    97                 if settings['include_module']: 
    98                     if module_name not in settings['include_module']: 
    99                         dont_keep = True 
    100                 else: 
    101                     if module_name in settings['exclude_module']: 
    102                         dont_keep = True 
    103                 module_name += '.' 
    104125        else: 
    105             module_name = 'unknown.' 
    106             dont_keep = True 
     126            module_name = 'unknown' 
     127            keep = False 
    107128 
    108129        # work out the instance, if we're in a class 
    109130        try: 
    110131            class_name = frame.f_locals['self'].__class__.__name__ 
    111             if settings['include_class']: 
    112                 if class_name not in settings['include_class']: 
    113                     dont_keep = True 
    114             else: 
    115                 if class_name in settings['exclude_class']: 
    116                     dont_keep = True 
    117             class_name += '.' 
    118132        except (KeyError, AttributeError): 
    119133            class_name = '' 
     
    123137        if func_name == '?': 
    124138            func_name = '__main__' 
    125         else: 
    126             if settings['include_func']: 
    127                 if func_name not in settings['include_func']: 
    128                     dont_keep = True 
    129             else: 
    130                 if func_name in settings['exclude_func']: 
    131                     dont_keep = True 
    132139 
    133140        # join em together in a readable form 
    134         full_name = '%s%s%s' % (module_name, class_name, func_name) 
    135  
    136         if full_name in settings['exclude_specific']: 
    137             dont_keep = True 
     141        full_name = '.'.join(filter(None, [module_name, class_name, 
     142                                           func_name])) 
     143 
     144        if trace_filter: 
     145            keep = trace_filter(call_stack, module_name, class_name, 
     146                                func_name, full_name) 
    138147 
    139148        # throw it all in dictonaires 
    140149        fr = call_stack[-1] 
    141         if not dont_keep or settings['dont_exclude_anything']: 
     150        if keep or settings['dont_exclude_anything']: 
    142151            if fr not in call_dict: 
    143152                call_dict[fr] = {}