[Python-checkins] CVS: python/dist/src/Python pythonrun.c,2.127,2.128 sysmodule.c,2.83,2.84

Ka-Ping Yee ping@users.sourceforge.net
Thu, 22 Mar 2001 18:46:54 -0800


Update of /cvsroot/python/python/dist/src/Python
In directory usw-pr-cvs1:/tmp/cvs-serv9091/Python

Modified Files:
	pythonrun.c sysmodule.c 
Log Message:
Add sys.excepthook.
Update docstring and library reference section on 'sys' module.
New API PyErr_Display, just for displaying errors, called by excepthook.
Uncaught exceptions now call sys.excepthook; if that fails, we fall back
    to calling PyErr_Display directly.
Also comes with sys.__excepthook__ and sys.__displayhook__.


Index: pythonrun.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v
retrieving revision 2.127
retrieving revision 2.128
diff -C2 -r2.127 -r2.128
*** pythonrun.c	2001/03/22 02:47:58	2.127
--- pythonrun.c	2001/03/23 02:46:52	2.128
***************
*** 802,807 ****
  PyErr_PrintEx(int set_sys_last_vars)
  {
! 	int err = 0;
! 	PyObject *exception, *v, *tb, *f;
  	PyErr_Fetch(&exception, &v, &tb);
  	PyErr_NormalizeException(&exception, &v, &tb);
--- 802,806 ----
  PyErr_PrintEx(int set_sys_last_vars)
  {
! 	PyObject *exception, *v, *tb, *hook;
  	PyErr_Fetch(&exception, &v, &tb);
  	PyErr_NormalizeException(&exception, &v, &tb);
***************
*** 845,850 ****
  		PySys_SetObject("last_value", v);
  		PySys_SetObject("last_traceback", tb);
  	}
! 	f = PySys_GetObject("stderr");
  	if (f == NULL)
  		fprintf(stderr, "lost sys.stderr\n");
--- 844,881 ----
  		PySys_SetObject("last_value", v);
  		PySys_SetObject("last_traceback", tb);
+ 	}
+ 	hook = PySys_GetObject("excepthook");
+ 	if (hook) {
+ 		PyObject *args = Py_BuildValue("(OOO)",
+                     exception, v ? v : Py_None, tb ? tb : Py_None);
+ 		PyObject *result = PyEval_CallObject(hook, args);
+ 		if (result == NULL) {
+ 			PyObject *exception2, *v2, *tb2;
+ 			PyErr_Fetch(&exception2, &v2, &tb2);
+ 			PyErr_NormalizeException(&exception2, &v2, &tb2);
+ 			if (Py_FlushLine())
+ 				PyErr_Clear();
+ 			fflush(stdout);
+ 			PySys_WriteStderr("Error in sys.excepthook:\n");
+ 			PyErr_Display(exception2, v2, tb2);
+ 			PySys_WriteStderr("\nOriginal exception was:\n");
+ 			PyErr_Display(exception, v, tb);
+ 		}
+ 		Py_XDECREF(result);
+ 		Py_XDECREF(args);
+ 	} else {
+ 		PySys_WriteStderr("sys.excepthook is missing\n");
+ 		PyErr_Display(exception, v, tb);
  	}
! 	Py_XDECREF(exception);
! 	Py_XDECREF(v);
! 	Py_XDECREF(tb);
! }
! 
! void PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb)
! {
! 	int err = 0;
! 	PyObject *v = value;
! 	PyObject *f = PySys_GetObject("stderr");
  	if (f == NULL)
  		fprintf(stderr, "lost sys.stderr\n");
***************
*** 853,857 ****
  			PyErr_Clear();
  		fflush(stdout);
! 		err = PyTraceBack_Print(tb, f);
  		if (err == 0 &&
  		    PyErr_GivenExceptionMatches(exception, PyExc_SyntaxError))
--- 884,889 ----
  			PyErr_Clear();
  		fflush(stdout);
! 		if (tb && tb != Py_None)
! 			err = PyTraceBack_Print(tb, f);
  		if (err == 0 &&
  		    PyErr_GivenExceptionMatches(exception, PyExc_SyntaxError))
***************
*** 876,881 ****
  				if (text != NULL)
  					print_error_text(f, offset, text);
- 				Py_INCREF(message);
- 				Py_DECREF(v);
  				v = message;
  				/* Can't be bothered to check all those
--- 908,911 ----
***************
*** 933,939 ****
  			err = PyFile_WriteString("\n", f);
  	}
- 	Py_XDECREF(exception);
- 	Py_XDECREF(v);
- 	Py_XDECREF(tb);
  	/* If an error happened here, don't show it.
  	   XXX This is wrong, but too many callers rely on this behavior. */
--- 963,966 ----

Index: sysmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/sysmodule.c,v
retrieving revision 2.83
retrieving revision 2.84
diff -C2 -r2.83 -r2.84
*** sysmodule.c	2001/01/13 22:06:05	2.83
--- sysmodule.c	2001/03/23 02:46:52	2.84
***************
*** 108,116 ****
  
  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)
  {
--- 108,132 ----
  
  static char displayhook_doc[] =
! "displayhook(object) -> None\n"
  "\n"
! "Print an object to sys.stdout and also save it in __builtin__._\n";
  
  static PyObject *
+ sys_excepthook(PyObject* self, PyObject* args)
+ {
+ 	PyObject *exc, *value, *tb;
+ 	if (!PyArg_ParseTuple(args, "OOO:excepthook", &exc, &value, &tb))
+ 		return NULL;
+ 	PyErr_Display(exc, value, tb);
+ 	Py_INCREF(Py_None);
+ 	return Py_None;
+ }
+ 
+ static char excepthook_doc[] =
+ "excepthook(exctype, value, traceback) -> None\n"
+ "\n"
+ "Handle an exception by displaying it with a traceback on sys.stderr.\n";
+ 
+ static PyObject *
  sys_exc_info(PyObject *self, PyObject *args)
  {
***************
*** 379,382 ****
--- 395,399 ----
  	{"displayhook",	sys_displayhook, 1, displayhook_doc},
  	{"exc_info",	sys_exc_info, 1, exc_info_doc},
+ 	{"excepthook",	sys_excepthook, 1, excepthook_doc},
  	{"exit",	sys_exit, 0, exit_doc},
  	{"getdefaultencoding", sys_getdefaultencoding, 1,
***************
*** 478,488 ****
  path -- module search path; path[0] is the script directory, else ''\n\
  modules -- dictionary of loaded modules\n\
! exitfunc -- you may set this to a function to be called when Python exits\n\
  \n\
  stdin -- standard input file object; used by raw_input() and input()\n\
  stdout -- standard output file object; used by the print statement\n\
  stderr -- standard error object; used for error messages\n\
!   By assigning another file object (or an object that behaves like a file)\n\
!   to one of these, it is possible to redirect all of the interpreter's I/O.\n\
  \n\
  last_type -- type of last uncaught exception\n\
--- 495,512 ----
  path -- module search path; path[0] is the script directory, else ''\n\
  modules -- dictionary of loaded modules\n\
! \n\
! displayhook -- called to show results in an interactive session\n\
! excepthook -- called to handle any uncaught exception other than SystemExit\n\
!   To customize printing in an interactive session or to install a custom\n\
!   top-level exception handler, assign other functions to replace these.\n\
! \n\
! exitfunc -- if sys.exitfunc exists, this routine is called when Python exits\n\
!   Assigning to sys.exitfunc is deprecated; use the atexit module instead.\n\
  \n\
  stdin -- standard input file object; used by raw_input() and input()\n\
  stdout -- standard output file object; used by the print statement\n\
  stderr -- standard error object; used for error messages\n\
!   By assigning other file objects (or objects that behave like files)\n\
!   to these, it is possible to redirect all of the interpreter's I/O.\n\
  \n\
  last_type -- type of last uncaught exception\n\
***************
*** 499,503 ****
  "
  #ifndef MS_WIN16
! /* Concatenating string here */
  "\n\
  Static objects:\n\
--- 523,527 ----
  "
  #ifndef MS_WIN16
! /* concatenating string here */
  "\n\
  Static objects:\n\
***************
*** 513,525 ****
  prefix -- prefix used to find the Python library\n\
  exec_prefix -- prefix used to find the machine-specific Python library\n\
! dllhandle -- [Windows only] integer handle of the Python DLL\n\
  winver -- [Windows only] version number of the Python DLL\n\
! __stdin__ -- the original stdin; don't use!\n\
! __stdout__ -- the original stdout; don't use!\n\
! __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\
--- 537,557 ----
  prefix -- prefix used to find the Python library\n\
  exec_prefix -- prefix used to find the machine-specific Python library\n\
! "
! #ifdef MS_WINDOWS
! /* concatenating string here */
! "dllhandle -- [Windows only] integer handle of the Python DLL\n\
  winver -- [Windows only] version number of the Python DLL\n\
! "
! #endif /* MS_WINDOWS */
! "__stdin__ -- the original stdin; don't touch!\n\
! __stdout__ -- the original stdout; don't touch!\n\
! __stderr__ -- the original stderr; don't touch!\n\
! __displayhook__ -- the original displayhook; don't touch!\n\
! __excepthook__ -- the original excepthook; don't touch!\n\
  \n\
  Functions:\n\
  \n\
  displayhook() -- print an object to the screen, and save it in __builtin__._\n\
+ excepthook() -- print an exception and its traceback to sys.stderr\n\
  exc_info() -- return thread-safe information about the current exception\n\
  exit() -- exit the interpreter by raising SystemExit\n\
***************
*** 531,535 ****
  settrace() -- set the global debug tracing function\n\
  "
! #endif
  /* end of sys_doc */ ;
  
--- 563,567 ----
  settrace() -- set the global debug tracing function\n\
  "
! #endif /* MS_WIN16 */
  /* end of sys_doc */ ;
  
***************
*** 556,559 ****
--- 588,595 ----
  	PyDict_SetItemString(sysdict, "__stdout__", sysout);
  	PyDict_SetItemString(sysdict, "__stderr__", syserr);
+ 	PyDict_SetItemString(sysdict, "__displayhook__",
+                              PyDict_GetItemString(sysdict, "displayhook"));
+ 	PyDict_SetItemString(sysdict, "__excepthook__",
+                              PyDict_GetItemString(sysdict, "excepthook"));
  	Py_XDECREF(sysin);
  	Py_XDECREF(sysout);