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 …
[View More]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(a)geocities.com>.
http://www.oreilly.com/news/prescod_0300.htmlhttp://www.linux.org.il -- we put the penguin in .com
[View Less]
Here is how i was planning to take care of exceptions in
sys.displaytb...
1. When the 'sys' module does not contain a 'stderr'
attribute, Python currently prints 'lost sys.stderr'
to the original stderr instead of printing the traceback.
I propose that it proceed to try to print the traceback
to the real stderr in this case.
2. If 'sys.stderr' is buffered, the traceback does not
appear in the file. I propose that Python flush
'sys.…
[View More]stderr' immediately after printing a traceback.
3. Tracebacks get printed to whatever object happens to
be in 'sys.stderr'. If the object is not a file (or
other problems occur during printing), nothing gets
printed anywhere. I propose that Python warn about
this on stderr, then try to print the traceback to
the real stderr as above.
4. Similarly, 'sys.displaytb' may cause an exception.
I propose that when this happens, Python invoke its
default traceback printer to print the exception from
'sys.displaytb' as well as the original exception.
#4 may seem a little convoluted, so here is the exact logic
i suggest (described here in Python but to be implemented in C),
where 'handle_exception()' is the routine the interpreter uses
to handle an exception, 'print_exception' is the built-in
exception printer currently implemented in PyErr_PrintEx and
PyTraceBack_Print, and 'err' is the actual, original stderr.
def print_double_exception(tb, exc, disptb, dispexc, file):
file.write("Exception occured during traceback display:\n")
print_exception(disptb, dispexc, file)
file.write("\n")
file.write("Original exception passed to display routine:\n")
print_exception(tb, exc, file)
def handle_double_exception(tb, exc, disptb, dispexc):
if hasattr(sys, 'stderr'):
err.write("Missing sys.stderr; printing exception to stderr.\n")
print_double_exception(tb, exc, disptb, dispexc, err)
return
try:
print_double_exception(tb, exc, disptb, dispexc, sys.stderr)
except:
err.write("Error on sys.stderr; printing exception to stderr.\n")
print_double_exception(tb, exc, disptb, dispexc, err)
def handle_exception():
tb, exc = sys.exc_traceback, sys.exc_value
try:
sys.displaytb(tb, exc)
except:
disptb, dispexc = sys.exc_traceback, sys.exc_value
try:
handle_double_exception(tb, exc, disptb, dispexc)
except: pass
def default_displaytb(tb, exc):
if hasattr(sys, 'stderr'):
print_exception(tb, exc, sys.stderr)
else:
print "Missing sys.stderr; printing exception to stderr."
print_exception(tb, exc, err)
sys.displaytb = sys.__displaytb__ = default_displaytb
-- ?!ng
"In the sciences, we are now uniquely privileged to sit side by side
with the giants on whose shoulders we stand."
-- Gerald Holton
[View Less]
I'd like to propose that we invite Neil Hodgson to join the
python-dev family.
Neil is the author of the Scintilla editor control, now used by
wxPython and Pythonwin... Smart guy, and very experienced with
Python (scintilla was originally written because he had trouble
converting Pythonwin to be a color'd editor :-)
But most relevant at the moment is his Unicode experience. He
worked for along time with Fujitsu, working with Japanese and all
the encoding issues there. I have heard him echo …
[View More]the exact
sentiments of Andy. He is also in the process of polishing the
recent Unicode support in Scintilla.
As this Unicode debate seems to be going nowhere fast, and appears
to simply need more people with _experience_, I think he would be
valuable. Further, he is a pretty quiet guy - you wont find him
offering his opinion on every post that moves through here :-)
Thoughts?
Mark.
[View Less]