views:

130

answers:

2

Given the output of inspect.stack(), is it possible to get the function objects from anywhere from the stack frame and call these? If so, how?

(I already know how to get the names of the functions.)

Here is what I'm getting at: Let's say I'm a function and I'm trying to determine if my caller is a generator or a regular function? I need to call inspect.isgeneratorfunction() on the function object. And how do you figure out who called you? inspect.stack(), right? So if I can somehow put those together, I'll have the answer to my question. Perhaps there is an easier way to do this?

+1  A: 

Here is a code snippet that do it. There is no error checking. The idea is to find in the locals of the grand parent the function object that was called. The function object returned should be the parent. If you want to also search the builtins, then simply look into stacks[2][0].f_builtins.

def f():
    stacks  = inspect.stack()
    grand_parent_locals = stacks[2][0].f_locals
    caller_name = stacks[1][3]
    candidate = grand_parent_locals[caller_name]

In the case of a class, one can write the following (inspired by Marcin solution)

class test(object):
    def f(self):
        stack = inspect.stack()
        parent_func_name = stack[1][3]
        parent_func = getattr(self, parent_func_name).im_func
Eolmar
Sorry, this didn't work for me :( With a few tweaks I managed to get it to work though. Thanks for the guidance.
Marcin
By looking at your code, I guess you are inside a class and retrieve member function.
Eolmar
It would be nice to have code that works regardless of whether we are in a function or class method
Casebash
In Python 3.0 it is simply `__func__`
Casebash
It should be added that this only works if the parent function is within the same class
Casebash
A: 

I took the following approach, very similar to Eolmar's answer.

stack = inspect.stack()
parent_locals = stack[1][0].f_locals['self']
parent_func_name = stack[1][3]
parent_func_attr = getattr(parent_locals,parent_func_name)
parent_func = parent_func_attr.im_func
is_parent_gen = inspect.isgeneratorfunction(func)
Marcin
What is the isgeneratorfunction for?
Casebash