diff --git a/Doc/lib/libsys.tex b/Doc/lib/libsys.tex index 2fda26e429c..df32182e666 100644 --- a/Doc/lib/libsys.tex +++ b/Doc/lib/libsys.tex @@ -44,6 +44,15 @@ Integer specifying the handle of the Python DLL. Availability: Windows. \end{datadesc} +\begin{funcdesc}{displayhook}{\var{value}} +If \var{value} is not \code{None}, this function prints it to +\code{sys.stdout}, and saves it in \code{__builtin__._}. + +This function is called when an expression is entered at the prompt +of an interactive Python session. It exists mainly so it can be +overridden. +\end{funcdesc} + \begin{funcdesc}{exc_info}{} This function returns a tuple of three values that give information about the exception that is currently being handled. The information diff --git a/Python/ceval.c b/Python/ceval.c index 5110746441d..8012b8357f2 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1245,36 +1245,26 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals, 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); - } + w = PySys_GetObject("displayhook"); + if (w == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "lost sys.displayhook"); + err = -1; + } + if (err == 0) { + x = Py_BuildValue("(O)", v); + if (x == NULL) + err = -1; + } + if (err == 0) { + w = PyEval_CallObject(w, x); + if (w == NULL) + err = -1; } Py_DECREF(v); + Py_XDECREF(x); break; - + case PRINT_ITEM_TO: w = stream = POP(); /* fall through to PRINT_ITEM */ diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 33d71ac1d8f..037b567f33a 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -67,6 +67,50 @@ PySys_SetObject(char *name, PyObject *v) return PyDict_SetItemString(sd, name, v); } +static PyObject * +sys_displayhook(PyObject *self, PyObject *args) +{ + PyObject *o, *stdout; + PyInterpreterState *interp = PyThreadState_Get()->interp; + PyObject *modules = interp->modules; + PyObject *builtins = PyDict_GetItemString(modules, "__builtin__"); + + /* parse arguments */ + if (!PyArg_ParseTuple(args, "O:displayhook", &o)) + return NULL; + + /* Print value except if None */ + /* After printing, also assign to '_' */ + /* Before, set '_' to None to avoid recursion */ + if (o == Py_None) { + Py_INCREF(Py_None); + return Py_None; + } + if (PyObject_SetAttrString(builtins, "_", Py_None) != 0) + return NULL; + if (Py_FlushLine() != 0) + return NULL; + stdout = PySys_GetObject("stdout"); + if (stdout == NULL) { + PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout"); + return NULL; + } + if (PyFile_WriteObject(o, stdout, 0) != 0) + return NULL; + PyFile_SoftSpace(stdout, 1); + if (Py_FlushLine() != 0) + return NULL; + if (PyObject_SetAttrString(builtins, "_", o) != 0) + return NULL; + Py_INCREF(Py_None); + return Py_None; +} + +static char displayhook_doc[] = +"displayhook(o) -> None\n" +"\n" +"Print o to the stdout, and save it in __builtin__._\n"; + static PyObject * sys_exc_info(PyObject *self, PyObject *args) { @@ -332,6 +376,7 @@ extern PyObject *_Py_GetDXProfile(PyObject *, PyObject *); static PyMethodDef sys_methods[] = { /* Might as well keep this in alphabetic order */ + {"displayhook", sys_displayhook, 1, displayhook_doc}, {"exc_info", sys_exc_info, 1, exc_info_doc}, {"exit", sys_exit, 0, exit_doc}, {"getdefaultencoding", sys_getdefaultencoding, 1, @@ -475,6 +520,7 @@ __stderr__ -- the original stderr; don't use!\n\ \n\ Functions:\n\ \n\ +displayhook() -- print an object to the screen, and save it in __builtin__._\n\ exc_info() -- return thread-safe information about the current exception\n\ exit() -- exit the interpreter by raising SystemExit\n\ getrefcount() -- return the reference count for an object (plus one :-)\n\