Re: How to get function string name from i-th stack position?

2011-12-31 Thread Ian Kelly
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?

2011-12-31 Thread Ian Kelly
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?

2011-12-31 Thread Lie Ryan

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?

2011-12-31 Thread dmitrey
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?

2011-12-30 Thread Ian Kelly
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?

2011-12-30 Thread dmitrey
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?

2011-12-30 Thread Tim Chase

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