Re: How to get function string name from i-th stack position?
On Sat, Dec 31, 2011 at 1:44 AM, dmitrey wrote: > On Dec 30, 11:48 pm, Ian Kelly wrote: >> On Fri, Dec 30, 2011 at 11:43 AM, dmitrey wrote: >> > Thank you. And what should I do to get function by itself instead of >> > its string name, e.g. I want to know does this function is my_func or >> > any other? For example, I would like to check is this function Python >> > sum(), or maybe numpy.sum(), or anything else? >> >> The Python stack only includes Python code objects. Built-ins like >> sum won't appear in it because they're basically C functions and don't >> have associated code objects. If you really want to see them, you >> could probably do something with ctypes to inspect the C stack, but I >> don't recommend it. >> >> You can get the Python code objects from the stack by calling >> inspect.stack(), which includes each frame object currently on the >> stack as the first member of each tuple. E.g.: >> >> frames = map(operator.itemgetter(0), inspect.stack()) >> >> Each frame has an f_code attribute that stores the code object >> associated with that frame. Getting the actual function from the code >> object is tricky, for two reasons. One, not all code objects >> represent functions. There are also code objects for modules, class >> definitions, and probably other thing as well. Two, code objects >> don't have associated functions. The relationship is the reverse: >> functions have associated code objects. You would have to iterate >> over each function that you're interested in, looking for one with a >> func_code attribute that "is" the frame's f_code attribute. >> >> In any case, testing function identity is a rather large rabbit hole >> that is best avoided. These are mathematically the same function: >> >> def plus1(value): >> return value + 1 >> >> plus_one = lambda x: x + 1 >> >> But they are two distinct function objects, and there is no way >> programmatically to determine that they are the same function except >> by comparing the bytecode (which won't work generally because of the >> halting problem). >> >> What is it that you're trying to do? Perhaps the helpful folks on the >> list will be able to suggest a better solution if you can provide more >> details. >> >> Cheers, >> Ian > > Maybe it is somehow possible to compare function id with my candidates > id, e.g. > PythonSumID = id(sum) > import numpy > NumpySumID = id(numpy.sum) > func = getting_function_from_Nth_stack_level_above > if id(func) == PythonSumID: > > elif id(func) == NumpySumID: > > else: > > I need it due to the following reason: FuncDesigner users often use > Python or numpy sum on FuncDesigner objects, while FuncDesigner.sum() > is optimized for this case, works faster and doesn't lead to "Max > recursion dept exceeded", that sometimes trigger for numpy or Python > sum() when number of summarized elements is more than several > hundreds. I would like to print warning "you'd better use FuncDesigner > sum" if this case has been identified. The only think I can think of would be to replace the sum built-in with a wrapper that checks whether it's being called on FuncDesigner objects and issues a warning. Users might not like you messing with their built-ins in that way, though. -- http://mail.python.org/mailman/listinfo/python-list
Re: How to get function string name from i-th stack position?
On Sat, Dec 31, 2011 at 4:41 AM, Lie Ryan wrote: > On 12/31/2011 08:48 AM, Ian Kelly wrote: >> >> >> But they are two distinct function objects, and there is no way >> programmatically to determine that they are the same function except >> by comparing the bytecode (which won't work generally because of the >> halting problem). > > > Actually, it is often possible to determine that two functions are the same > function, you simply need a to compare whether the function object lives in > the same memory address. It is also possible to determine if two functions > are different, if the function object are in different memory address than > the function is different function. > > What is difficult to do due to the Halting problem is comparing whether two > different functions are "equivalent" (and therefore interchangeable). Yes, that is what I said. You can determine whether two function objects are the same, but not whether they are *mathematically* the same function. > I think the OP wants to find the former, not the latter. The former is > trivial, the latter impossible. Based on his subsequent clarification, I agree, although from his original post it sounded like he was just trying to identify summing functions in general. However, finding the built-in sum function on the stack is not trivial at all, perhaps not even possible. -- http://mail.python.org/mailman/listinfo/python-list
Re: How to get function string name from i-th stack position?
On 12/31/2011 08:48 AM, Ian Kelly wrote: But they are two distinct function objects, and there is no way programmatically to determine that they are the same function except by comparing the bytecode (which won't work generally because of the halting problem). Actually, it is often possible to determine that two functions are the same function, you simply need a to compare whether the function object lives in the same memory address. It is also possible to determine if two functions are different, if the function object are in different memory address than the function is different function. What is difficult to do due to the Halting problem is comparing whether two different functions are "equivalent" (and therefore interchangeable). I think the OP wants to find the former, not the latter. The former is trivial, the latter impossible. -- http://mail.python.org/mailman/listinfo/python-list
Re: How to get function string name from i-th stack position?
On Dec 30, 11:48 pm, Ian Kelly wrote: > On Fri, Dec 30, 2011 at 11:43 AM, dmitrey wrote: > > Thank you. And what should I do to get function by itself instead of > > its string name, e.g. I want to know does this function is my_func or > > any other? For example, I would like to check is this function Python > > sum(), or maybe numpy.sum(), or anything else? > > The Python stack only includes Python code objects. Built-ins like > sum won't appear in it because they're basically C functions and don't > have associated code objects. If you really want to see them, you > could probably do something with ctypes to inspect the C stack, but I > don't recommend it. > > You can get the Python code objects from the stack by calling > inspect.stack(), which includes each frame object currently on the > stack as the first member of each tuple. E.g.: > > frames = map(operator.itemgetter(0), inspect.stack()) > > Each frame has an f_code attribute that stores the code object > associated with that frame. Getting the actual function from the code > object is tricky, for two reasons. One, not all code objects > represent functions. There are also code objects for modules, class > definitions, and probably other thing as well. Two, code objects > don't have associated functions. The relationship is the reverse: > functions have associated code objects. You would have to iterate > over each function that you're interested in, looking for one with a > func_code attribute that "is" the frame's f_code attribute. > > In any case, testing function identity is a rather large rabbit hole > that is best avoided. These are mathematically the same function: > > def plus1(value): > return value + 1 > > plus_one = lambda x: x + 1 > > But they are two distinct function objects, and there is no way > programmatically to determine that they are the same function except > by comparing the bytecode (which won't work generally because of the > halting problem). > > What is it that you're trying to do? Perhaps the helpful folks on the > list will be able to suggest a better solution if you can provide more > details. > > Cheers, > Ian Maybe it is somehow possible to compare function id with my candidates id, e.g. PythonSumID = id(sum) import numpy NumpySumID = id(numpy.sum) func = getting_function_from_Nth_stack_level_above if id(func) == PythonSumID: elif id(func) == NumpySumID: else: I need it due to the following reason: FuncDesigner users often use Python or numpy sum on FuncDesigner objects, while FuncDesigner.sum() is optimized for this case, works faster and doesn't lead to "Max recursion dept exceeded", that sometimes trigger for numpy or Python sum() when number of summarized elements is more than several hundreds. I would like to print warning "you'd better use FuncDesigner sum" if this case has been identified. Regards, D. -- http://mail.python.org/mailman/listinfo/python-list
Re: How to get function string name from i-th stack position?
On Fri, Dec 30, 2011 at 11:43 AM, dmitrey wrote: > Thank you. And what should I do to get function by itself instead of > its string name, e.g. I want to know does this function is my_func or > any other? For example, I would like to check is this function Python > sum(), or maybe numpy.sum(), or anything else? The Python stack only includes Python code objects. Built-ins like sum won't appear in it because they're basically C functions and don't have associated code objects. If you really want to see them, you could probably do something with ctypes to inspect the C stack, but I don't recommend it. You can get the Python code objects from the stack by calling inspect.stack(), which includes each frame object currently on the stack as the first member of each tuple. E.g.: frames = map(operator.itemgetter(0), inspect.stack()) Each frame has an f_code attribute that stores the code object associated with that frame. Getting the actual function from the code object is tricky, for two reasons. One, not all code objects represent functions. There are also code objects for modules, class definitions, and probably other thing as well. Two, code objects don't have associated functions. The relationship is the reverse: functions have associated code objects. You would have to iterate over each function that you're interested in, looking for one with a func_code attribute that "is" the frame's f_code attribute. In any case, testing function identity is a rather large rabbit hole that is best avoided. These are mathematically the same function: def plus1(value): return value + 1 plus_one = lambda x: x + 1 But they are two distinct function objects, and there is no way programmatically to determine that they are the same function except by comparing the bytecode (which won't work generally because of the halting problem). What is it that you're trying to do? Perhaps the helpful folks on the list will be able to suggest a better solution if you can provide more details. Cheers, Ian -- http://mail.python.org/mailman/listinfo/python-list
Re: How to get function string name from i-th stack position?
On Dec 30, 8:35 pm, Tim Chase wrote: > On 12/30/11 11:51, dmitrey wrote: > > > how to get string name of a function that is n levels above > > the current Python interpreter position? > > Use the results of traceback.extract_stack() > > from traceback import extract_stack > def one(x): > print "one", x > stk = extract_stack() > for mod, lineno, fun_name, call_code_text in stk: > print "[%s:%i] in %s" % (mod, lineno, fun_name) > def two(x): > print "two", x > one(x) > def three(x): > print "three", x > two(x) > three("Hi") > > -tkc Thank you. And what should I do to get function by itself instead of its string name, e.g. I want to know does this function is my_func or any other? For example, I would like to check is this function Python sum(), or maybe numpy.sum(), or anything else? Regards, D. -- http://mail.python.org/mailman/listinfo/python-list
Re: How to get function string name from i-th stack position?
On 12/30/11 11:51, dmitrey wrote: how to get string name of a function that is n levels above the current Python interpreter position? Use the results of traceback.extract_stack() from traceback import extract_stack def one(x): print "one", x stk = extract_stack() for mod, lineno, fun_name, call_code_text in stk: print "[%s:%i] in %s" % (mod, lineno, fun_name) def two(x): print "two", x one(x) def three(x): print "three", x two(x) three("Hi") -tkc -- http://mail.python.org/mailman/listinfo/python-list