Version 1 (modified by 18 years ago) ( diff ) | ,
---|
Inspect call stack
While playing arround with djangos internals I have found the following decorator usefull. It shows the call stack up to the decorated function:
def who_called_me(show_filename=False, out=None, indent=' '): def _wrapper(fn): def _inner_wrapper(*args, **kwargs): import sys import inspect output = out or sys.stdout assert hasattr(output, 'write'), \ 'argument \'out\' of function \'who_called_me\' must have a write method' index = 0 stack = inspect.stack() stack.reverse() # remove ourself from the stack list stack.pop() for record in stack: frame = record[0] line = frame.f_lineno func_name = frame.f_code.co_name if show_filename: descr = frame.f_code.co_filename else: descr = frame.f_globals["__name__"] print >>output, '%s%s@%s:%d' % (indent*index, descr, func_name, line) # to be safe explicitly delete the stack frame reference # @see http://docs.python.org/lib/inspect-stack.html del frame index += 1 del stack if hasattr(output, 'flush'): output.flush() return fn(*args, **kwargs) return _inner_wrapper return _wrapper
Usage Examples:
@who_called_me() def index(request): return render_to_response('phc/index.html', None, context_instance=RequestContext(request))
Prints this to stdout:
django.core.management@inner_run:995 django.core.servers.basehttp@run:643 SocketServer@serve_forever:201 SocketServer@handle_request:222 SocketServer@process_request:241 SocketServer@finish_request:254 django.core.servers.basehttp@__init__:537 SocketServer@__init__:521 django.core.servers.basehttp@handle:586 django.core.servers.basehttp@run:272 django.core.servers.basehttp@__call__:615 django.core.handlers.wsgi@__call__:145 django.core.handlers.base@get_response:74
Show filenames instead of module:
@who_called_me(show_filename=True) def index(request): return render_to_response('phc/index.html', None, context_instance=RequestContext(request))
Prints this to stdout:
/home/me/projects/django_ma/django/core/management.py@inner_run:995 /home/me/projects/django_ma/django/core/servers/basehttp.py@run:643 /usr/lib/python2.4/SocketServer.py@serve_forever:201 /usr/lib/python2.4/SocketServer.py@handle_request:222 /usr/lib/python2.4/SocketServer.py@process_request:241 /usr/lib/python2.4/SocketServer.py@finish_request:254 /home/me/projects/django_ma/django/core/servers/basehttp.py@__init__:537 /usr/lib/python2.4/SocketServer.py@__init__:521 /home/me/projects/django_ma/django/core/servers/basehttp.py@handle:586 /home/me/projects/django_ma/django/core/servers/basehttp.py@run:272 /home/me/projects/django_ma/django/core/servers/basehttp.py@__call__:615 /home/me/projects/django_ma/django/core/handlers/wsgi.py@__call__:145 /home/me/projects/django_ma/django/core/handlers/base.py@get_response:74
Or write output to a file:
@who_called_me(out=open('/tmp/who_called_me', 'a')) def index(request): return render_to_response('phc/index.html', None, context_instance=RequestContext(request))
Note:
See TracWiki
for help on using the wiki.