Changes between Initial Version and Version 1 of CookBookDeveloperTools


Ignore:
Timestamp:
06/01/06 12:42:07 (9 years ago)
Author:
anonymous
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • CookBookDeveloperTools

    v1 v1  
     1== Inspect call stack ==
     2
     3While playing arround with djangos internals I have found the following decorator usefull. It shows the call stack up to the decorated function:
     4
     5{{{
     6#!python
     7def who_called_me(show_filename=False, out=None, indent=' '):
     8    def _wrapper(fn):
     9        def _inner_wrapper(*args, **kwargs):
     10            import sys
     11            import inspect
     12            output = out or sys.stdout
     13            assert hasattr(output, 'write'), \
     14                'argument \'out\' of function \'who_called_me\' must have a write method'
     15            index = 0
     16            stack = inspect.stack()
     17            stack.reverse()
     18            # remove ourself from the stack list
     19            stack.pop()
     20            for record in stack:
     21                frame = record[0]
     22                line = frame.f_lineno
     23                func_name = frame.f_code.co_name
     24                if show_filename:
     25                    descr = frame.f_code.co_filename
     26                else:
     27                    descr = frame.f_globals["__name__"]
     28                print >>output, '%s%s@%s:%d' % (indent*index, descr, func_name, line)
     29                # to be safe explicitly delete the stack frame reference
     30                # @see http://docs.python.org/lib/inspect-stack.html
     31                del frame
     32                index += 1
     33            del stack
     34            if hasattr(output, 'flush'):
     35                output.flush()
     36            return fn(*args, **kwargs)
     37        return _inner_wrapper
     38    return _wrapper
     39
     40}}}
     41
     42Usage Examples:
     43{{{
     44#!python
     45@who_called_me()
     46def index(request):
     47    return render_to_response('phc/index.html', None, context_instance=RequestContext(request))
     48}}}
     49Prints this to stdout:
     50{{{
     51django.core.management@inner_run:995
     52 django.core.servers.basehttp@run:643
     53  SocketServer@serve_forever:201
     54   SocketServer@handle_request:222
     55    SocketServer@process_request:241
     56     SocketServer@finish_request:254
     57      django.core.servers.basehttp@__init__:537
     58       SocketServer@__init__:521
     59        django.core.servers.basehttp@handle:586
     60         django.core.servers.basehttp@run:272
     61          django.core.servers.basehttp@__call__:615
     62           django.core.handlers.wsgi@__call__:145
     63            django.core.handlers.base@get_response:74
     64}}}
     65
     66Show filenames instead of module:
     67{{{
     68#!python
     69@who_called_me(show_filename=True)
     70def index(request):
     71    return render_to_response('phc/index.html', None, context_instance=RequestContext(request))
     72}}}
     73
     74Prints this to stdout:
     75{{{
     76/home/me/projects/django_ma/django/core/management.py@inner_run:995
     77 /home/me/projects/django_ma/django/core/servers/basehttp.py@run:643
     78  /usr/lib/python2.4/SocketServer.py@serve_forever:201
     79   /usr/lib/python2.4/SocketServer.py@handle_request:222
     80    /usr/lib/python2.4/SocketServer.py@process_request:241
     81     /usr/lib/python2.4/SocketServer.py@finish_request:254
     82      /home/me/projects/django_ma/django/core/servers/basehttp.py@__init__:537
     83       /usr/lib/python2.4/SocketServer.py@__init__:521
     84        /home/me/projects/django_ma/django/core/servers/basehttp.py@handle:586
     85         /home/me/projects/django_ma/django/core/servers/basehttp.py@run:272
     86          /home/me/projects/django_ma/django/core/servers/basehttp.py@__call__:615
     87           /home/me/projects/django_ma/django/core/handlers/wsgi.py@__call__:145
     88            /home/me/projects/django_ma/django/core/handlers/base.py@get_response:74
     89}}}
     90
     91Or write output to a file:
     92{{{
     93#!python
     94@who_called_me(out=open('/tmp/who_called_me', 'a'))
     95def index(request):
     96    return render_to_response('phc/index.html', None, context_instance=RequestContext(request))
     97}}}
Back to Top