Code

Changes between Initial Version and Version 1 of CookBookDeveloperTools


Ignore:
Timestamp:
06/01/06 10:42:07 (8 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}}}