Mailing List Archive

At the interactive port
Continuing the recent debate about what is appropriate to the interactive
prompt printing, and the wide agreement that whatever we decide, users
might think otherwise, I've written up a patch to have the user control
via a function in __builtin__ the way things are printed at the prompt.
This is not patches@python level stuff for two reasons:

1. I'm not sure what to call this function. Currently, I call it
__print_expr__, but I'm not sure it's a good name

2. I haven't yet supplied a default in __builtin__, so the user *must*
override this. This is unacceptable, of course.

I'd just like people to tell me if they think this is worth while, and if
there is anything I missed.

*** ../python/dist/src/Python/ceval.c Fri Mar 31 04:42:47 2000
--- Python/ceval.c Sat Apr 29 03:55:36 2000
***************
*** 1014,1047 ****

case PRINT_EXPR:
v = POP();
! /* Print value except if None */
! /* After printing, also assign to '_' */
! /* Before, set '_' to None to avoid recursion */
! if (v != Py_None &&
! (err = PyDict_SetItemString(
! f->f_builtins, "_", Py_None)) == 0) {
! err = Py_FlushLine();
! if (err == 0) {
! x = PySys_GetObject("stdout");
! if (x == NULL) {
! PyErr_SetString(
! PyExc_RuntimeError,
! "lost sys.stdout");
! err = -1;
! }
! }
! if (err == 0)
! err = PyFile_WriteObject(v, x, 0);
! if (err == 0) {
! PyFile_SoftSpace(x, 1);
! err = Py_FlushLine();
! }
! if (err == 0) {
! err = PyDict_SetItemString(
! f->f_builtins, "_", v);
! }
}
! Py_DECREF(v);
break;

case PRINT_ITEM:
--- 1014,1035 ----

case PRINT_EXPR:
v = POP();
! x = PyDict_GetItemString(f->f_builtins,
! "__print_expr__");
! if (x == NULL) {
! PyErr_SetString(PyExc_SystemError,
! "__print_expr__ not found");
! Py_DECREF(v);
! break;
! }
! t = PyTuple_New(1);
! if (t != NULL) {
! PyTuple_SET_ITEM(t, 0, v);
! w = PyEval_CallObject(x, t);
! Py_XDECREF(w);
}
! /*Py_DECREF(x);*/
! Py_XDECREF(t);
break;

case PRINT_ITEM:

--
Moshe Zadka <mzadka@geocities.com>.
http://www.oreilly.com/news/prescod_0300.html
http://www.linux.org.il -- we put the penguin in .com
Re: At the interactive port [ In reply to ]
Moshe Zadka writes:
> 1. I'm not sure what to call this function. Currently, I call it
> __print_expr__, but I'm not sure it's a good name

It's not. ;) How about printresult?
Another thing to think about is interface; formatting a result and
"printing" it may be different, and you may want to overload them
separately in an environment like IDLE. Some people may want to just
say:

import sys
sys.formatresult = str

I'm inclined to think that level of control may be better left to
the application; if one hook is provided as you've described, the
application can build different layers as appropriate.

> 2. I haven't yet supplied a default in __builtin__, so the user *must*
> override this. This is unacceptable, of course.

You're right! But a default is easy enough to add. I'd put it in
sys instead of __builtin__ though.


-Fred

--
Fred L. Drake, Jr. <fdrake at acm.org>
Corporation for National Research Initiatives
Re: At the interactive port [ In reply to ]
On Mon, 1 May 2000, Fred L. Drake, Jr. wrote:

> It's not. ;) How about printresult?

Hmmmm...better then mine at least.

> import sys
> sys.formatresult = str

And where does the "don't print if it's None" enter? I doubt if there is a
really good way to divide functionality. OF course, specific IDEs may
provide their own hooks.

> You're right! But a default is easy enough to add.

I agree. It was more to spur discussion -- with the advantage that there
is already a way to include Python sessions.

> I'd put it in
> sys instead of __builtin__ though.

Hmmm.. that's a Guido Issue(TM). Guido?
--
Moshe Zadka <moshez@math.huji.ac.il>
http://www.oreilly.com/news/prescod_0300.html
http://www.linux.org.il -- we put the penguin in .com
Re: At the interactive port [ In reply to ]
> Continuing the recent debate about what is appropriate to the interactive
> prompt printing, and the wide agreement that whatever we decide, users
> might think otherwise, I've written up a patch to have the user control
> via a function in __builtin__ the way things are printed at the prompt.
> This is not patches@python level stuff for two reasons:
>
> 1. I'm not sure what to call this function. Currently, I call it
> __print_expr__, but I'm not sure it's a good name
>
> 2. I haven't yet supplied a default in __builtin__, so the user *must*
> override this. This is unacceptable, of course.
>
> I'd just like people to tell me if they think this is worth while, and if
> there is anything I missed.

Thanks for bringing this up again. I think it should be called
sys.displayhook. The default could be something like

import __builtin__
def displayhook(obj):
if obj is None:
return
__builtin__._ = obj
sys.stdout.write("%s\n" % repr(obj))

to be nearly 100% compatible with current practice; or use str(obj) to
do what most people would probably prefer.

(Note that you couldn't do "%s\n" % obj because obj might be a tuple.)

--Guido van Rossum (home page: http://www.python.org/~guido/)
Re: At the interactive port [ In reply to ]
> Thanks for bringing this up again. I think it should be called
> sys.displayhook.

That should be the easy part -- I'll do it as soon as I'm home.

> The default could be something like
>
> import __builtin__
import sys # Sorry, I couldn't resist
> def displayhook(obj):
> if obj is None:
> return
> __builtin__._ = obj
> sys.stdout.write("%s\n" % repr(obj))

This brings up a painful point -- the reason I haven't wrote the default
is because it was way much easier to write it in Python. Of course, I
shouldn't be preaching Python-is-easier-to-write-then-C here, but it
pains me Python cannot be written with more Python and less C.

A while ago we started talking about the mini-interpreter idea, which
would then freeze Python code into itself, and then it sort of died out.
What have become of it?

--
Moshe Zadka <moshez@math.huji.ac.il>
http://www.oreilly.com/news/prescod_0300.html
http://www.linux.org.il -- we put the penguin in .com
Re: At the interactive port [ In reply to ]
> > import __builtin__
> import sys # Sorry, I couldn't resist
> > def displayhook(obj):
> > if obj is None:
> > return
> > __builtin__._ = obj
> > sys.stdout.write("%s\n" % repr(obj))
>
> This brings up a painful point -- the reason I haven't wrote the default
> is because it was way much easier to write it in Python. Of course, I
> shouldn't be preaching Python-is-easier-to-write-then-C here, but it
> pains me Python cannot be written with more Python and less C.
>

But the C code on how to do it was present in the code you deleted
from ceval.c!

> A while ago we started talking about the mini-interpreter idea,
> which would then freeze Python code into itself, and then it sort of
> died out. What have become of it?

Nobody sent me a patch :-(

--Guido van Rossum (home page: http://www.python.org/~guido/)
Re: At the interactive port [ In reply to ]
On Tue, 2 May 2000, Moshe Zadka wrote:
>
> > Thanks for bringing this up again. I think it should be called
> > sys.displayhook.

I apologize profusely for dropping the ball on this. I
was going to do it; i have been having a tough time lately
figuring out a Big Life Decision. (Hate those BLDs.)

I was partway through hacking the patch and didn't get back
to it, but i wanted to at least air the plan i had in mind.
I hope you'll allow me this indulgence.

I was planning to submit a patch that adds the built-in routines

sys.display
sys.displaytb

sys.__display__
sys.__displaytb__

sys.display(obj) would be implemented as 'print repr(obj)'
and sys.displaytb(tb, exc) would call the same built-in
traceback printer we all know and love.

I assumed that sys.__stdin__ was added to make it easier to
restore sys.stdin to its original value. In the same vein,
sys.__display__ and sys.__displaytb__ would be saved references
to the original sys.display and sys.displaytb.

I hate to contradict Guido, but i'll gently suggest why i
like "display" better than "displayhook": "display" is a verb,
and i prefer function names to be verbs rather than nouns
describing what the functions are (e.g. "read" rather than
"reader", etc.)


-- ?!ng
Re: At the interactive port [ In reply to ]
> I was planning to submit a patch that adds the built-in routines
>
> sys.display
> sys.displaytb
>
> sys.__display__
> sys.__displaytb__
>
> sys.display(obj) would be implemented as 'print repr(obj)'
> and sys.displaytb(tb, exc) would call the same built-in
> traceback printer we all know and love.

Sure. Though I would recommend to separate the patch in two parts,
because their implementation is totally unrelated.

> I assumed that sys.__stdin__ was added to make it easier to
> restore sys.stdin to its original value. In the same vein,
> sys.__display__ and sys.__displaytb__ would be saved references
> to the original sys.display and sys.displaytb.

Good idea.

> I hate to contradict Guido, but i'll gently suggest why i
> like "display" better than "displayhook": "display" is a verb,
> and i prefer function names to be verbs rather than nouns
> describing what the functions are (e.g. "read" rather than
> "reader", etc.)

Good idea. But I hate the "displaytb" name (when I read your message
I had no idea what the "tb" stood for until you explained it).

Hm, perhaps we could do showvalue and showtraceback?
("displaytraceback" is a bit long.)

--Guido van Rossum (home page: http://www.python.org/~guido/)