David M. Kaplan | 8 Jul 17:30

help with embedding

Hi,

I am starting to use ipython as a replacement for matlab.  I have been
trying to use IPShellEmbed to create a "keyboard-like" command for
ipython and have some problems/questions.  keyboard is a command in
matlab that you stick in a script that allows you to drop out of the
script and into a manual entry state where you have access to the same
namespace as the script and can look at and modify variables.  As I
understand, this is the purpose of IPShellEmbed (except for modifying
variables, which I don't think it allows - correct me if I am wrong).
However, I can't seem to get it quite right.  I think I have also found
some bugs, or at the very least some very strange behavior.

First I generate an IPShellEmbed instance:

from IPython.Shell import IPShellEmbed
keyboard = IPShellEmbed(['-pi1','keyboard <\\#>'], \
	'Entering Keyboard','Exiting Keyboard')

Then I use it with keyboard().  This basically works, but I have the
following questions:

1) Calling keyboard() from ipython itself seems to drop me into a new
namespace that doesn't know anything about the variables in the original
ipython namespace.  I can fix this by setting the local or global
namespace to _ip.user_ns.  Can someone explain why this is necessary?
Naively, I would expect to end up in the ipython namespace just as
calling keyboard() from a script does.    

2) The restriction to not being able to modify variables is a bit of a
(Continue reading)

Fernando Perez | 11 Jul 13:01

Re: help with embedding

Howdy,

thanks for these detailed comments.  I'll do my best to help a bit...

On Tue, Jul 8, 2008 at 8:31 AM, David M. Kaplan <dmk <at> ucsc.edu> wrote:
> Hi,

> 1) Calling keyboard() from ipython itself seems to drop me into a new
> namespace that doesn't know anything about the variables in the original
> ipython namespace.  I can fix this by setting the local or global
> namespace to _ip.user_ns.  Can someone explain why this is necessary?
> Naively, I would expect to end up in the ipython namespace just as
> calling keyboard() from a script does.

The embedded shells are intended to study the *local* namespace of
where they are called, not to manipulate the enclosing ipython
namespace.  I should note that you can pass the namespace that you
want to hold in the locals/globals when you construct the instance,
but that may be already what you are doing (I wasn't sure if you were
doing it at construction time or manually later).

But more importantly: you are nesting embedded shells inside a running
ipython.  Unfortunately there's enough global state in ipython and
readline that having embedded instances without any funny business is
a bit tricky.  Some of it can be cleaned up via more careful handling
of the readline state when going in/out of the embedded shell, other
parts would require a bit more work on the assumptions ipython makes
about global state.  It's all fixable, but there could be some
relatively serious surgery required.

(Continue reading)

David M. Kaplan | 11 Jul 16:23

Re: help with embedding

Hi

Thanks for the response.  I will submit a bug report.  I have a few
comments/responses below.

On Fri, 2008-07-11 at 04:01 -0700, Fernando Perez wrote:
> > 2) The restriction to not being able to modify variables is a bit of a
> > pain.  In matlab, I often use keyboard to give information to my
> > scripts.  Is there a way around this?  Or is there another approach I
> > should be using?
> 
> There's no way around it, it's a limitation imposed by python itself:
> the locals dict obtained from the stack is read-only.
> 

It has been hard for me to figure out how python treats namespaces, but
if I understand correctly, the local namespace is read-only, while the
global is writable.  If this is true, I would naively think that the
following would enable you to modify ipython variables:

IPShellEmbed(local_ns=globals(),global_ns=locals())
globals['nameofvar']=100

But this doesn't work at all, probably because I don't completely
understand how locals and globals work.  I imagine the answer is that
locals() is always read-only, no matter which namespace IPShellEmbed
tries to attach it to.

This relates to one potential solution I found for having a more
"keyboard" like experience (except for being able to modify variables),
(Continue reading)


Gmane