I have a C++ library that I am wrapping and exposing via python. For various reasons I need to overload the __call__ of the functions when exposing them via python.
A minimal example is below using time.sleep to mimic functions with various compute times
import sys
import time
class Wrap_Func(object):
    def __init__(self, func, name):
        self.name = name
        self.func = func
    def __call__(self, *args, **kwargs):
        # do stuff
        return self.func(*args, **kwargs)
def wrap_funcs():
    thismodule = sys.modules[__name__]
    for i in range(3):
        fname = 'example{}'.format(i)
        setattr(thismodule, fname, Wrap_Func(lambda: time.sleep(i), fname))
wrap_funcs()
When profiling my code via cProfile I get a list of __call__ routines.
I am unable to ascertain which routines are taking the majority of the compute time.
>>> import cProfile
>>> cProfile.runctx('example0(); example1(); example2()', globals(), locals())
         11 function calls in 6.000 seconds
   Ordered by: standard name
   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        3    0.000    0.000    6.000    2.000 <ipython-input-48-e8126c5f6ea3>:11(__call__)
        3    0.000    0.000    6.000    2.000 <ipython-input-48-e8126c5f6ea3>:20(<lambda>)
        1    0.000    0.000    6.000    6.000 <string>:1(<module>)
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
        3    6.000    2.000    6.000    2.000 {time.sleep}
Expected
By manually defining the functions (this needs to be dynamic and wrapper as above) as
def example0():
    time.sleep(0)
def example1():
    time.sleep(1)
def example2():
    time.sleep(2)
I get the expected output of
>>> import cProfile
>>> cProfile.runctx('example0(); example1(); example2()', globals(), locals())
     11 function calls in 6.000 seconds
             8 function calls in 3.000 seconds
   Ordered by: standard name
   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    0.000    0.000 <ipython-input-58-688d247cb941>:1(example0)
        1    0.000    0.000    0.999    0.999 <ipython-input-58-688d247cb941>:4(example1)
        1    0.000    0.000    2.000    2.000 <ipython-input-58-688d247cb941>:7(example2)
        1    0.000    0.000    3.000    3.000 <string>:1(<module>)
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
        3    3.000    1.000    3.000    1.000 {time.sleep}
