how to wrap automatically functions from certain file
<p>It's a well known fact there are many ways to get a function name using python standard library, here's a little example:</p>

<pre><code>import sys
import dis
import traceback


def get_name():
    stack = traceback.extract_stack()
    filename, codeline, funcName, text = stack[-2]
    return funcName


def foo1():
    print("Foo0 start")
    print("Inside-_getframe {0}".format(sys._getframe().f_code.co_name))
    print("Inside-traceback {0}".format(get_name()))
    print("Foo1 end")


def foo2():
    print("Foo2 start")
    print("Inside {0}".format(sys._getframe().f_code.co_name))
    print("Inside-traceback {0}".format(get_name()))
    print("Foo2 end")


def foo3():
    print("Foo3 start")
    print("Inside {0}".format(sys._getframe().f_code.co_name))
    print("Inside-traceback {0}".format(get_name()))
    print("Foo3 end")

for f in [foo1, foo2, foo3]:
    print("Outside: {0}".format(f.__name__))
    f()
    print('-' * 80)
</code></pre>

<p>You can use <a href="https://docs.python.org/2/library/traceback.html" rel="nofollow">traceback</a>, <a href="https://docs.python.org/2/library/sys.html#sys._getframe" rel="nofollow">sys._getframe</a>, <a href="https://docs.python.org/2/library/dis.html" rel="nofollow">dis</a> and maybe there is a lot of more options... so far so good, python is awesome to do this kind of introspection.</p>

<p>Now, here's the thing, I'd like to know how to wrap automatically functions (at file level) to print its name and also measuring the execution time when they are executed. For instance, something like this:</p>

<pre><code>def foo1():
    print("Foo0 processing")


def foo2():
    print("Foo2 processing")


def foo3():
    print("Foo3 processing")

wrap_function_from_this_file()

for f in [foo1, foo2, foo3]:
    f()
    print('-' * 80)
</code></pre>

<p>Would print something like:</p>

<pre><code>foo1 started
Foo1 processing
foo1 finished, elapsed time=1ms
--------------------------------------------------------------------------------
foo2 started
Foo2 processing
foo2 finished, elapsed time=2ms
--------------------------------------------------------------------------------
foo3 started
Foo3 processing
foo3 finished, elapsed time=3ms
--------------------------------------------------------------------------------
</code></pre>

<p>As you can see, the idea would be not adding any wrapper per-function manually to the file's functions. <strong>wrap_function_from_this_file</strong> would automagically introspect the file where is executed and it'd modify functions wrapping them somewhat, in this case, wrapping the functions with some code printing its name and execution time.</p>

<p>Just for the record, <strong>I'm not asking for any profiler</strong>. I'd like to know whether this is possible to do and how.</p>

<p>A solution could be to use <code>globals()</code> for getting information about currently defined objects. Here is a simple wrapper function, which replaces the functions within the given globals data by a wrapped version of them:</p>

<pre><code>import types

def my_tiny_wrapper(glb):
    def wrp(f):
        # create a function which is not in 
        # local space of my_tiny_wrapper
        def _inner(*args, **kwargs):
            print('wrapped', f.__name__)
            return f(*args, **kwargs)
            print('end wrap', f.__name__)
        return _inner
    for f in [f for f in glb.values() if type(f) == types.FunctionType 
              and f.__name__ != 'my_tiny_wrapper']:
        print('WRAP FUNCTION', f.__name__) 
        glb[f.__name__] = wrp(f)
</code></pre>

<p>It can be used like this:</p>

<pre><code>def peter(): pass
def pan(a): print('salat and onions')   
def g(a,b,c='A'): print(a,b,c)

# pass the current globals to the funcion
my_tiny_wrapper(globals())
g(4,b=2,c='D')  # test keyword arguments
peter()         # test no arguments
pan(4)          # single argument
</code></pre>

<p>generating the following result:</p>

<pre><code>~ % python derp.py
('WRAP FUNCTION', 'g')
('WRAP FUNCTION', 'pan')
('WRAP FUNCTION', 'peter')
('wrapped', 'g')
(4, 2, 'D')
('end wrap', 'g')
('wrapped', 'peter')
('end wrap', 'peter')
('wrapped', 'pan')
salat and onions
('end wrap', 'pan')
</code></pre>

python python-2.7 python-3.x introspection