64 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			64 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Python
		
	
	
	
| 
 | |
| """ magic - some operations which helps to extend PDB with some magic data.
 | |
| Actually there is only explicit tracking of data, might be extended to
 | |
| automatic at some point.
 | |
| """
 | |
| 
 | |
| # some magic stuff to have singleton of DocStorage, but initialised explicitely
 | |
| 
 | |
| import weakref
 | |
| 
 | |
| import py
 | |
| from py.__.apigen.tracer.docstorage import DocStorage
 | |
| from py.__.apigen.tracer.tracer import Tracer
 | |
| import sys
 | |
| 
 | |
| class DocStorageKeeper(object):
 | |
|     doc_storage = DocStorage()
 | |
|     doc_storage.tracer = Tracer(doc_storage)
 | |
|     doc_storage.from_dict({})
 | |
|     
 | |
|     def set_storage(cl, ds):
 | |
|         cl.doc_storage = ds
 | |
|         cl.doc_storage.tracer = Tracer(ds)
 | |
|     set_storage = classmethod(set_storage)
 | |
| 
 | |
| def get_storage():
 | |
|     return DocStorageKeeper.doc_storage
 | |
| 
 | |
| def stack_copier(frame):
 | |
|     # copy all stack, not only frame
 | |
|     num = 0
 | |
|     gather = False
 | |
|     stack = []
 | |
|     try:
 | |
|         while 1:
 | |
|             if gather:
 | |
|                 stack.append(py.code.Frame(sys._getframe(num)))
 | |
|             else:
 | |
|                 if sys._getframe(num) is frame.raw:
 | |
|                     gather = True
 | |
|             num += 1
 | |
|     except ValueError:
 | |
|         pass
 | |
|     return stack
 | |
| 
 | |
| def trace(keep_frames=False, frame_copier=lambda x:x):
 | |
|     def decorator(fun):
 | |
|         ds = get_storage()
 | |
|         # in case we do not have this function inside doc storage, we
 | |
|         # want to have it
 | |
|         desc = ds.find_desc(py.code.Code(fun.func_code))
 | |
|         if desc is None:
 | |
|             desc = ds.add_desc(fun.func_name, fun, keep_frames=keep_frames,
 | |
|                 frame_copier=frame_copier)
 | |
|         
 | |
|         def wrapper(*args, **kwargs):
 | |
|             ds.tracer.start_tracing()
 | |
|             retval = fun(*args, **kwargs)
 | |
|             ds.tracer.end_tracing()
 | |
|             return retval
 | |
|         
 | |
|         return wrapper
 | |
|     return decorator
 |