On Wed, Mar 20, 2013 at 7:36 PM, Amaury Forgeot d'Arc <[email protected]>wrote:

> 2013/3/20 anatoly techtonik <[email protected]>
>
>> On Wed, Mar 20, 2013 at 5:28 PM, Amaury Forgeot d'Arc <[email protected]
>> > wrote:
>>
>>> 2013/3/20 anatoly techtonik <[email protected]>
>>>
>>>> Hi,
>>>>
>>>> I've created a module to dump function trace during execution of Python
>>>> script. You can see session example in attachment. The format is of PHP
>>>> Xdebug tool [2] just because I had some scripts from the past to analyze 
>>>> it.
>>>>
>>>> The module uses sys.settrace() to analyse frames in 'call' events with
>>>> callback(frame, event, arg).
>>>>
>>>> Recently I've got an anonymous report that some frame misses filename
>>>> information when run under IDE:
>>>>
>>>> https://bitbucket.org/techtonik/xtrace/issue/2/use-of-xtrace-module-within-ide-causes
>>>>
>>>> There is unlikely to be any more feedback from the user to make me
>>>> understand and reproduce the behavior, nor there is a sufficient
>>>> documentation in sys.trace description [1]. So I am on my own. But I can
>>>> not read C code the CPython is written in, so I ask here.
>>>>
>>>> What are possible execution contexts for Python?
>>>> How each execution context affects data structure that is passed to
>>>> trace function (frame and arg)?
>>>>
>>>
>>>  It's simpler than that: when running from an interactive session,
>>> f_back is empty...
>>>
>>> >>> def trace(frame, event, arg):
>>> ...     funcname = frame.f_code.co_name
>>> ...     if funcname == '<module>':
>>> ...         print frame.f_back.f_code.co_filename
>>> ...
>>> >>> import sys
>>> >>> sys.settrace(trace)
>>> >>> 1
>>> Traceback (most recent call last):
>>>   File "<stdin>", line 1, in <module>
>>>   File "<stdin>", line 4, in trace
>>> AttributeError: 'NoneType' object has no attribute 'f_code'
>>>
>>
>> Thanks a lot. =)
>>
>> User said he was using module from the IDE and at first I thought it
>> wasn't possible to use module without previous stack frame (f_back), but I
>> was wrong:
>>
>> > py -2 -s -S
>> Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)]
>> on win32
>> >>> import xtrace
>> >>> xtrace.start()
>> TRACE START [2013-03-20 18:49:27]
>> >>> z = 0
>>   -> decode() C:\Python27\lib\encodings\cp437.py:14
>> Traceback (most recent call last):
>>   File "<stdin>", line 1, in <module>
>>   File "xtrace.py", line 66, in function_trace_xdebug
>>     filename = self._strip_cwd(frame.f_back.f_code.co_filename)
>> AttributeError: 'NoneType' object has no attribute 'f_code'
>>
>>
>> On the way I've discovered that my Python is hacked. Without -s -S key it
>> executes modules from local temp directory.
>> ...
>>           -> ensure_unicode()
>> c:\users\user\appdata\local\temp\easy_install-k8gvbp\pyreadline-1.7.1-py2.7-win32.egg.tmp\pyre
>> dline\unicode_helper.py:20
>> ...
>>
>>
>> So there are absolutely no differences in running code in these execution
>> contexts?
>> - code runs from a file
>> - code runs from a interactive console
>>
>
> Of course there is a difference; the code below works run from a file, but
> not when pasted into the interactive console:
>
> def trace(frame, event, arg):
>     funcname = frame.f_code.co_name
>     print frame.f_code, repr(frame.f_code.co_code), event, arg
>     if funcname == '<module>':
>         print "    module", repr(frame.f_back.f_code.co_code)
>
> import sys
> sys.settrace(trace)
> exec '1 + 1'
>

For console it pretty clear why no previous frame exists - stack is
resolved at >>> prompt. But what is this top frame that appears inside file
context? The following code gives:
<module> 7
<module> 1

def trace(frame, event, arg):
    print frame.f_back.f_code.co_name, frame.f_back.f_lineno
    print frame.f_code.co_name, frame.f_lineno

import sys
sys.settrace(trace)
exec '1 + 1'

How to identify the frames here? How come that 7th line of module is
executed before 1 st? I expected to have module name available somewhere
for <module> object. All right, this kind of tricky - '1 +1' a separate
module, right? It is anonymous and doesn't have a name. Still is it
possible to identify it somehow? For printing in function traces.


>
>> I realize that I don't know how to set trace function for external file,
>> so that when the file is executed, the first frame won't have the previous
>> stack frame. I do it like so:
>>     start()
>>     execfile(script)
>>     stop()
>>
>
> I'ts indeed difficult to detach the "script" from the frame running the
> execfile statement.
> You could handle this case specially in your trace function, though.
>

Now that I understand, I can handle it. I guess stripping the 0 level calls
(where it will be only one) will help. Thanks again.
_______________________________________________
pypy-dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-dev

Reply via email to