[IPython-dev] [IPython-user] Development plans update

Brian Granger ellisonbg.net at gmail.com
Sat Feb 2 17:59:55 EST 2008


> > 2.  Prompt display.  IPython prompts can include info from the users namespace.
>
> I think the prompt calculation should be done in the back-end. Isn't
> it trivial for the frontend to ask for the prompt string from the back
> end (even if it doesn't happen by merely writing out the characters)?

This is sort of possible.  We could have a method in the api called
something like get_next_prompt.  But, in practice, this won't work
well.  The reason is that the backend could be busy at the moment you
want a prompt.  And threads won't help this in any way.  I probably
need to explain a bit more about how the core works for this to make
sense.  Anytime you make a call to the core the call _may_ be put into
a queue if the core is busy.  This is a standard FIFO queue.  The
reason this happens is to enable a user to continue working on new
input lines while the old ones compute.  If you are familiar with
Mathematica, you can edit and submit new input cells while old ones
work.  But, when the queue is active, everything goes through the
queue - tab completion, prompt stuff. etc.  This is done to make sure
the entire thing is deterministic.

Now there will be times where the queue is not active, but our API
needs to be designed for the general case where a queue may be
present.

There is also another complication with prompts.  The architecture
already supports multiple users connecting to the same ipython
engine/core process.  All of the users frontends will have access to
the current prompt number, but, you can imagine that the frontend has
to in this case make decisions about what the prompts look like - the
core simply can't as is knows nothing about how many user are
connected.

So, get_next_prompt would be easy to implement, but it behavior will
not be quite what you really need to reliably create prompts in the
frontends.


> > 3.  Traceback printing.  Tracebacks are formatted (ACSII coloring,
> > etc) by ipython at the moment the exception is raised, when the full
> > state of the interpreter is available to look at.
>
> Why can't the back end just render the exception string, and let the
> display be handled by front end? We can change the color escape
> sequences to something more "universal", if need be (<red>foo</red>,
> <highlight>NOTE</highlight>, whatever).

That is exactly what we have in mind.  In this case it shouldn't be
too difficult.  But, the API is different in a sense as the actual
traceback formatter will be something that lives in the frontend.

> > whatever way is best.  While this doesn't look too bad there is a lot
> > of subtlety going on underneath the hood.  For example, the complete
> > method could actually trigger a network call to ipython core/engine
> > running on a remote system.  At the time the complete call gets made,
> > the engine could be executing some blocking C code the user had
> > started in a previous line.  In this case, the tab completion can't
> > happen until that C code finishes (threads won't help).  So, then, in
> > a case like that, the complete method will need to raise an exception
> > to reflect the fact that TAB completion can't happen right now.
>
> If we have the part that communicates with the front end in a separate
> thread, this won't be a problem. Completion can ALWAYS happen. This is
> probably easy stuff, apart from ctrl+c handling.

When we started out on this stuff 3 years ago (my gosh, I can't
believe it has been so long), that is what we thought.  We actually
had an initial prototype that used threads in this way.....then
Fernando gave an embarassing demo of it at a conference.  Here is the
problem.  Python threads are only useful in two cases:

1.  When running pure python code.
2.  When running extension code that releases the GIL

The killer problem is that there is lots of extension code that
doesn't release the GIL.  This is a problem because this code is not
IPython code, it is user code that we don't have any control over.
Furthermore, we can't even reliably detect when they are about to call
such code.  Thus, when we have used threads in this manner the system
simply locks up anytime non-GIL releasing code is run by the user -
this is what happened  in Fernando's talk before we solved these
problems.

But, there is another more important reason that tab completion can't
always happen.  I can give you an example - remember that every
command that is sent to the core _may_ be put into a queue and
executed later.

In [1]: run_some_long_calculation()             # the core starts
working on this and it will take 5 minutes

In [2]: a = Thing()                      # The user gets this prompt
immediately and enters this command.
                                               # because the first
command is still executing, this command is put on the
                                               # queue.  It will be
executed when the first one is done - in 5 minutes.

In [3]: a.     <TAB>                   # Again, the user gets this
prompt immediately.  They want to tab complete
                                               # on a, but it is truly
impossible as the command to create a has not been
                                               # run yet.

As you can see, the other really fundamental change in ipython1 is
that everything _may_ be completely asynchronous.  This requires a
huge paradigm shift in terms of thinking.

I should say that Fernando, Min and myself have spent months of our
time struggling to figure out the best model for all of this.  One
conclusion we have made is that what we are trying to do is extremely
difficult.

It is very likely that our model/architecture will need to be changed
further - especially to support things that the new frontends will
want/need.  But, the fundamental notion of things being possibly
asynchronous is probably here to stay.

With that said, it will be possible to make a terminal based frontend
that is not asynchronous and that always tab completes immediately.

> Yeah, this is what I referred to earlier. Changing what the back end
> blurts out to xml should be pretty easy, and a trivial front end
> implementation (a readline one) can just do string replace to convert
> it to the current ansi codes.

Yep.

> > to varous methods of the interpreter.  This is what I mean that the
> > "core" won't know anything about display hooks.  They will still
> > exist, but look very different.
>
> I think the display hooks should still be in core, but return strings
> instead of direct printing.

Yes, this is more of what it looks like.  Currently when you call the
method to run code in the core, it gives you back a python dict of
various things (stdout, stderr, etc.).  The display hooks could
possible manipulate those dictionaries.  But, it is important to
remember that multple users (with different display desires) could be
connected to the same core instance.  Thus, I think that much of the
display logic will need to be the frontends.

> > Does this help give a better idea about why the APIs will look so different?
>
> Yes. Meetings these expectations seems like a pretty fun project, though :-)

I think it will be a blast.  Thanks to everyone's great work IPython
is already extremely cool.  It we can pull this new stuff off, the
resulting system will be unparalleled in terms of interactive
computing environments.  I can't wait to use the new stuff myself :)

Brian



>
> --
> Ville M. Vainio - vivainio.googlepages.com
> blog=360.yahoo.com/villevainio - g[mail | talk]='vivainio'
>



More information about the IPython-dev mailing list