mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	- New function sys.exc_clear() clears the current exception. This is
rarely needed, but can sometimes be useful to release objects referenced by the traceback held in sys.exc_info()[2]. (SF patch #693195.) Thanks to Kevin Jacobs!
This commit is contained in:
		
							parent
							
								
									d1a283be26
								
							
						
					
					
						commit
						46d3dc37e4
					
				
					 5 changed files with 116 additions and 12 deletions
				
			
		|  | @ -99,6 +99,11 @@ It is always available. | ||||||
|   encapsulates the call stack at the point where the exception |   encapsulates the call stack at the point where the exception | ||||||
|   originally occurred.  \obindex{traceback} |   originally occurred.  \obindex{traceback} | ||||||
| 
 | 
 | ||||||
|  |   If \function{exc_clear()} is called, this function will return three | ||||||
|  |   \code{None} values until either another exception is raised in the | ||||||
|  |   current thread or the execution stack returns to a frame where | ||||||
|  |   another exception is being handled. | ||||||
|  | 
 | ||||||
|   \warning{Assigning the \var{traceback} return value to a |   \warning{Assigning the \var{traceback} return value to a | ||||||
|   local variable in a function that is handling an exception will |   local variable in a function that is handling an exception will | ||||||
|   cause a circular reference.  This will prevent anything referenced |   cause a circular reference.  This will prevent anything referenced | ||||||
|  | @ -115,6 +120,21 @@ It is always available. | ||||||
|   efficient to avoid creating cycles.} |   efficient to avoid creating cycles.} | ||||||
| \end{funcdesc} | \end{funcdesc} | ||||||
| 
 | 
 | ||||||
|  | \begin{funcdesc}{exc_clear}{} | ||||||
|  |   This function clears all information relating to the current or last | ||||||
|  |   exception that occured in the current thread.  After calling this | ||||||
|  |   function, \function{exc_info()} will return three \code{None} values until | ||||||
|  |   another exception is raised in the current thread or the execution stack | ||||||
|  |   returns to a frame where another exception is being handled. | ||||||
|  |    | ||||||
|  |   This function is only needed in only a few obscure situations.  These | ||||||
|  |   include logging and error handling systems that report information on the | ||||||
|  |   last or current exception.  This function can also be used to try to free | ||||||
|  |   resources and trigger object finalization, though no guarantee is made as | ||||||
|  |   to what objects will be freed, if any. | ||||||
|  | \versionadded{2.3} | ||||||
|  | \end{funcdesc} | ||||||
|  | 
 | ||||||
| \begin{datadesc}{exc_type} | \begin{datadesc}{exc_type} | ||||||
| \dataline{exc_value} | \dataline{exc_value} | ||||||
| \dataline{exc_traceback} | \dataline{exc_traceback} | ||||||
|  |  | ||||||
|  | @ -2451,14 +2451,15 @@ a module defines.  It returns a sorted list of strings: | ||||||
| ['__name__', 'fib', 'fib2'] | ['__name__', 'fib', 'fib2'] | ||||||
| >>> dir(sys) | >>> dir(sys) | ||||||
| ['__displayhook__', '__doc__', '__excepthook__', '__name__', '__stderr__', | ['__displayhook__', '__doc__', '__excepthook__', '__name__', '__stderr__', | ||||||
|  '__stdin__', '__stdout__', '_getframe', 'argv', 'builtin_module_names', |  '__stdin__', '__stdout__', '_getframe', 'api_version', 'argv',  | ||||||
|  'byteorder', 'copyright', 'displayhook', 'exc_info', 'exc_type', |  'builtin_module_names', 'byteorder', 'callstats', 'copyright', | ||||||
|  'excepthook', 'exec_prefix', 'executable', 'exit', 'getdefaultencoding', |  'displayhook', 'exc_clear', 'exc_info', 'exc_type', 'excepthook', | ||||||
|  'getdlopenflags', 'getrecursionlimit', 'getrefcount', 'hexversion', |  'exec_prefix', 'executable', 'exit', 'getdefaultencoding', 'getdlopenflags', | ||||||
|  'maxint', 'maxunicode', 'modules', 'path', 'platform', 'prefix', 'ps1', |  'getrecursionlimit', 'getrefcount', 'hexversion', 'maxint', 'maxunicode', | ||||||
|  'ps2', 'setcheckinterval', 'setdlopenflags', 'setprofile', |  'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache', | ||||||
|  'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout', 'version', |  'platform', 'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setdlopenflags', | ||||||
|  'version_info', 'warnoptions'] |  'setprofile', 'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout', | ||||||
|  |  'version', 'version_info', 'warnoptions'] | ||||||
| \end{verbatim} | \end{verbatim} | ||||||
| 
 | 
 | ||||||
| Without arguments, \function{dir()} lists the names you have defined | Without arguments, \function{dir()} lists the names you have defined | ||||||
|  |  | ||||||
|  | @ -63,6 +63,50 @@ def test_original_excepthook(self): | ||||||
|     # FIXME: testing the code for a lost or replaced excepthook in |     # FIXME: testing the code for a lost or replaced excepthook in | ||||||
|     # Python/pythonrun.c::PyErr_PrintEx() is tricky. |     # Python/pythonrun.c::PyErr_PrintEx() is tricky. | ||||||
| 
 | 
 | ||||||
|  |     def test_exc_clear(self): | ||||||
|  |         self.assertRaises(TypeError, sys.exc_clear, 42) | ||||||
|  | 
 | ||||||
|  |         # Verify that exc_info is present and matches exc, then clear it, and | ||||||
|  |         # check that it worked. | ||||||
|  |         def clear_check(exc): | ||||||
|  |           typ, value, traceback = sys.exc_info() | ||||||
|  |           self.assert_(typ is not None) | ||||||
|  |           self.assert_(value is exc) | ||||||
|  |           self.assert_(traceback is not None) | ||||||
|  | 
 | ||||||
|  |           sys.exc_clear() | ||||||
|  | 
 | ||||||
|  |           typ, value, traceback = sys.exc_info() | ||||||
|  |           self.assert_(typ is None) | ||||||
|  |           self.assert_(value is None) | ||||||
|  |           self.assert_(traceback is None) | ||||||
|  | 
 | ||||||
|  |         def clear(): | ||||||
|  |           try: | ||||||
|  |             raise ValueError, 42 | ||||||
|  |           except ValueError, exc: | ||||||
|  |             clear_check(exc) | ||||||
|  | 
 | ||||||
|  |         # Raise an exception and check that it can be cleared | ||||||
|  |         clear() | ||||||
|  | 
 | ||||||
|  |         # Verify that a frame currently handling an exception is | ||||||
|  |         # unaffected by calling exc_clear in a nested frame. | ||||||
|  |         try: | ||||||
|  |           raise ValueError, 13 | ||||||
|  |         except ValueError, exc: | ||||||
|  |           typ1, value1, traceback1 = sys.exc_info() | ||||||
|  |           clear() | ||||||
|  |           typ2, value2, traceback2 = sys.exc_info() | ||||||
|  | 
 | ||||||
|  |           self.assert_(typ1 is typ2) | ||||||
|  |           self.assert_(value1 is exc) | ||||||
|  |           self.assert_(value1 is value2) | ||||||
|  |           self.assert_(traceback1 is traceback2) | ||||||
|  | 
 | ||||||
|  |         # Check that an exception can be cleared outside of an except block | ||||||
|  |         clear_check(exc) | ||||||
|  | 
 | ||||||
|     def test_exit(self): |     def test_exit(self): | ||||||
|         self.assertRaises(TypeError, sys.exit, 42, 42) |         self.assertRaises(TypeError, sys.exit, 42, 42) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -12,6 +12,12 @@ What's New in Python 2.3 beta 1? | ||||||
| Core and builtins | Core and builtins | ||||||
| ----------------- | ----------------- | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | - New function sys.exc_clear() clears the current exception.  This is | ||||||
|  |   rarely needed, but can sometimes be useful to release objects | ||||||
|  |   referenced by the traceback held in sys.exc_info()[2].  (SF patch | ||||||
|  |   #693195.) | ||||||
|  | 
 | ||||||
| - On 64-bit systems, a dictionary could contain duplicate long/int keys | - On 64-bit systems, a dictionary could contain duplicate long/int keys | ||||||
|   if the key value was larger than 2**32.  See SF bug #689659. |   if the key value was larger than 2**32.  See SF bug #689659. | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -132,7 +132,7 @@ PyDoc_STRVAR(excepthook_doc, | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
| static PyObject * | static PyObject * | ||||||
| sys_exc_info(PyObject *self) | sys_exc_info(PyObject *self, PyObject *noargs) | ||||||
| { | { | ||||||
| 	PyThreadState *tstate; | 	PyThreadState *tstate; | ||||||
| 	tstate = PyThreadState_Get(); | 	tstate = PyThreadState_Get(); | ||||||
|  | @ -147,8 +147,39 @@ sys_exc_info(PyObject *self) | ||||||
| PyDoc_STRVAR(exc_info_doc, | PyDoc_STRVAR(exc_info_doc, | ||||||
| "exc_info() -> (type, value, traceback)\n\
 | "exc_info() -> (type, value, traceback)\n\
 | ||||||
| \n\ | \n\ | ||||||
| Return information about the exception that is currently being handled.\n\ | Return information about the most recent exception caught by an except\n\ | ||||||
| This should be called from inside an except clause only." | clause in the current stack frame or in an older stack frame." | ||||||
|  | ); | ||||||
|  | 
 | ||||||
|  | static PyObject * | ||||||
|  | sys_exc_clear(PyObject *self, PyObject *noargs) | ||||||
|  | { | ||||||
|  | 	PyThreadState *tstate = PyThreadState_Get(); | ||||||
|  | 	PyObject *tmp_type, *tmp_value, *tmp_tb; | ||||||
|  | 	tmp_type = tstate->exc_type; | ||||||
|  | 	tmp_value = tstate->exc_value; | ||||||
|  | 	tmp_tb = tstate->exc_traceback; | ||||||
|  | 	tstate->exc_type = NULL; | ||||||
|  | 	tstate->exc_value = NULL; | ||||||
|  | 	tstate->exc_traceback = NULL; | ||||||
|  | 	Py_XDECREF(tmp_type); | ||||||
|  | 	Py_XDECREF(tmp_value); | ||||||
|  | 	Py_XDECREF(tmp_tb); | ||||||
|  | 	/* For b/w compatibility */ | ||||||
|  | 	PySys_SetObject("exc_type", Py_None); | ||||||
|  | 	PySys_SetObject("exc_value", Py_None); | ||||||
|  | 	PySys_SetObject("exc_traceback", Py_None); | ||||||
|  | 	Py_INCREF(Py_None); | ||||||
|  | 	return Py_None; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | PyDoc_STRVAR(exc_clear_doc, | ||||||
|  | "exc_clear() -> None\n\
 | ||||||
|  | \n\ | ||||||
|  | Clear global information on the current exception.  Subsequent calls to\n\ | ||||||
|  | exc_info() will return (None,None,None) until another exception is raised\n\ | ||||||
|  | in the current thread or the execution stack returns to a frame where\n\ | ||||||
|  | another exception is being handled." | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
| static PyObject * | static PyObject * | ||||||
|  | @ -600,7 +631,8 @@ static PyMethodDef sys_methods[] = { | ||||||
| 	{"callstats", (PyCFunction)PyEval_GetCallStats, METH_NOARGS,  | 	{"callstats", (PyCFunction)PyEval_GetCallStats, METH_NOARGS,  | ||||||
| 	 callstats_doc}, | 	 callstats_doc}, | ||||||
| 	{"displayhook",	sys_displayhook, METH_O, displayhook_doc}, | 	{"displayhook",	sys_displayhook, METH_O, displayhook_doc}, | ||||||
| 	{"exc_info",	(PyCFunction)sys_exc_info, METH_NOARGS, exc_info_doc}, | 	{"exc_info",	sys_exc_info, METH_NOARGS, exc_info_doc}, | ||||||
|  | 	{"exc_clear",	sys_exc_clear, METH_NOARGS, exc_clear_doc}, | ||||||
| 	{"excepthook",	sys_excepthook, METH_VARARGS, excepthook_doc}, | 	{"excepthook",	sys_excepthook, METH_VARARGS, excepthook_doc}, | ||||||
| 	{"exit",	sys_exit, METH_VARARGS, exit_doc}, | 	{"exit",	sys_exit, METH_VARARGS, exit_doc}, | ||||||
| #ifdef Py_USING_UNICODE | #ifdef Py_USING_UNICODE | ||||||
|  | @ -786,6 +818,7 @@ Functions:\n\ | ||||||
| displayhook() -- print an object to the screen, and save it in __builtin__._\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\ | excepthook() -- print an exception and its traceback to sys.stderr\n\ | ||||||
| exc_info() -- return thread-safe information about the current exception\n\ | exc_info() -- return thread-safe information about the current exception\n\ | ||||||
|  | exc_clear() -- clear the exception state for the current thread\n\ | ||||||
| exit() -- exit the interpreter by raising SystemExit\n\ | exit() -- exit the interpreter by raising SystemExit\n\ | ||||||
| getdlopenflags() -- returns flags to be used for dlopen() calls\n\ | getdlopenflags() -- returns flags to be used for dlopen() calls\n\ | ||||||
| getrefcount() -- return the reference count for an object (plus one :-)\n\ | getrefcount() -- return the reference count for an object (plus one :-)\n\ | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Guido van Rossum
						Guido van Rossum