Implementation of PEP-0217.
This closes the PEP, and patch 103170
diff --git a/Doc/lib/libsys.tex b/Doc/lib/libsys.tex
index 2fda26e..df32182 100644
--- a/Doc/lib/libsys.tex
+++ b/Doc/lib/libsys.tex
@@ -44,6 +44,15 @@
 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 5110746..8012b83 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -1245,36 +1245,26 @@
 
 		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 33d71ac..037b567 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -68,6 +68,50 @@
 }
 
 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)
 {
 	PyThreadState *tstate;
@@ -332,6 +376,7 @@
 
 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 @@
 \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\