Changeset 16
- Timestamp:
- 13/02/07 23:33:45 (22 months ago)
- Files:
-
- 1 modified
-
trunk/pycallgraph.py (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/pycallgraph.py
r11 r16 37 37 38 38 reset_trace() 39 40 trace_filter = None 39 41 40 42 # graphviz settings … … 59 61 'node_color': lambda calls, : '%f %f %f' % (calls / 2 + .5, calls, 0.9), 60 62 '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': [],69 63 'dont_exclude_anything': False, 70 64 } … … 73 67 pass 74 68 75 def start_trace(reset=True): 69 class 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 99 def start_trace(reset=True, filter=None): 100 global trace_filter 76 101 if reset: 77 102 reset_trace() 103 if filter is None: 104 trace_filter = GlobbingFilter(exclude=['pycallgraph.*']) 105 else: 106 trace_filter = filter 78 107 sys.settrace(tracer) 79 108 … … 82 111 83 112 def tracer(frame, event, arg): 84 global func_count_max 113 global func_count_max, trace_filter 85 114 86 115 if event == 'call': 87 dont_keep = False116 keep = True 88 117 code = frame.f_code 89 118 … … 94 123 if module_name == '__main__': 95 124 module_name = '' 96 else:97 if settings['include_module']:98 if module_name not in settings['include_module']:99 dont_keep = True100 else:101 if module_name in settings['exclude_module']:102 dont_keep = True103 module_name += '.'104 125 else: 105 module_name = 'unknown .'106 dont_keep = True126 module_name = 'unknown' 127 keep = False 107 128 108 129 # work out the instance, if we're in a class 109 130 try: 110 131 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 = True114 else:115 if class_name in settings['exclude_class']:116 dont_keep = True117 class_name += '.'118 132 except (KeyError, AttributeError): 119 133 class_name = '' … … 123 137 if func_name == '?': 124 138 func_name = '__main__' 125 else:126 if settings['include_func']:127 if func_name not in settings['include_func']:128 dont_keep = True129 else:130 if func_name in settings['exclude_func']:131 dont_keep = True132 139 133 140 # 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) 138 147 139 148 # throw it all in dictonaires 140 149 fr = call_stack[-1] 141 if not dont_keep or settings['dont_exclude_anything']:150 if keep or settings['dont_exclude_anything']: 142 151 if fr not in call_dict: 143 152 call_dict[fr] = {}