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
 |