[IPython-user] Problem with IPShellEmbed

Michael Foord mike at pcblokes.com
Wed Feb 2 06:25:49 CST 2005

Fernando Perez wrote:

> mike at pcblokes.com wrote:
>> Right... I'm afraid stack frames are still a deeply black art to me.
>> Perhaps a better solution would be to put IPython in a 'Psyco proof 
>> bubble' ?
>> Surely IPython doesn't go deeper into the stack than the 
>> function/scope that
>> *called* IPython. So long as the locals are available from this frame 
>> we should
>> be alright ?
>> So if you can guarantee (by hook or by crook) that we can access that 
>> frame ok
>> everything is fine ? I'm probably being naive of course.......
> The problem is that an ipython user can request information about a 
> psyco-ized object, whose stack is unavailable.
> I had a look at the embedding calls, and it would be easy to change 
> the code to avoid the _getframe() calls IF you call it with a 
> locals/globals pair of dicts.  In iplib.py, around line 1066, change 
> the version I put up yesterday with this:
>         # Get locals and globals from caller
>         if local_ns is None or global_ns is None:
>             call_frame = sys._getframe(stack_depth).f_back
>             if local_ns is None:
>                 local_ns = call_frame.f_locals
>             if global_ns is None:
>                 global_ns = call_frame.f_globals
> This will avoid the _getframe call IF you provide BOTH a locals and a 
> globals dict.  In this case, users will NOT be able to call the 
> embedded instance with a simple
> ipshell()
> since they will HAVE to give ipython something to go with as a 
> namespace.  So the call will have to be:
> ipshell(local_ns=localdict,global_ns=globaldict)
> or positionally:
> ipshell('header string',localdict,globaldict)

Hmmm... even with these changes I still die if 
``ipshell(local_ns=localdict,global_ns=globaldict)`` is called.

I have made sure to call ``psyco.cannotcompile(interactive)`` so the 
interactive function *shouldn't* be bound by psyco. I am explicitly 
passing in locals() and globals() to the interactive function.

The error I get is as follows  :
D:\Python Projects\modules in progress\movpy\files\test>movpy.py  -i 
Movable Python
IPython Interactive Shell. See the manual for a list of features and tips.
Ctrl-D to exit.
Invalid frame in the stack, no globals/locals available.
Frame object: <psyco.support.PsycoFrame instance at 0x015E7828>

This message just cycles until I hit ctrl-D. In this case psyco.full() 
is not called by my script but in ptest2.py which is compiled and 
eval'd. My problem is that I have no way of knowing whether a script we 
run will call psyco.full() - I just have to warn my users that if they 
call scripts that have psyco they can't use IPython. In some ways this 
situation is worse - at least before IPython actually bombed out  (so I 
could trap the error and do something else) !!

I have asked Armin Rigo for help on this - including *either* a way to 
just apply psyco to the code object returned by compile (at the moment 
psyco.bind(object) doesn't work with code objects) - *or* a way of 
telling if psyco.full() has been called.

Note the following from the psyco user guide (which might or might not 
be helpful) :

*Frame objects* are emulated. The sys._getframe function returns an 
instance of a custom class which emulates the standard frame objects' 
behavior as much as possible. The frames corresponding to a 
Psyco-accelerated frame have some placeholder attributes, notably 
f_locals. /There is no way to read the local variables of a 
Psyco-accelerated frame./ Actually, only the f_code, f_globals, f_back 
and f_lineno fields are well-tested. Also keep in mind that if you 
obtain a real frame object (which you can do with some other mean than 
sys._getframe, e.g. via a traceback object), the f_back chained list 
will not include the Psyco-accelerated frames.

Best Regards,

Michael Foord

>> Psyco is a common tool, so it would be *better* if IPython could work 
>> with it
>> (or at least around it). If there are any changes to psyco that would 
>> help this
>> then I'm sure Armin would be willing to consider them.
> I agree, and I'd like to play nice with psyco.  But I hope you realize 
> that embedding a live interpreter into a function where psyco has 
> explicitly destroyed the stack is not exactly easy :)

> Cheers,
> f

More information about the IPython-user mailing list