mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +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 | ||||
|   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 | ||||
|   local variable in a function that is handling an exception will | ||||
|   cause a circular reference.  This will prevent anything referenced | ||||
|  | @ -115,6 +120,21 @@ It is always available. | |||
|   efficient to avoid creating cycles.} | ||||
| \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} | ||||
| \dataline{exc_value} | ||||
| \dataline{exc_traceback} | ||||
|  |  | |||
|  | @ -2451,14 +2451,15 @@ a module defines.  It returns a sorted list of strings: | |||
| ['__name__', 'fib', 'fib2'] | ||||
| >>> dir(sys) | ||||
| ['__displayhook__', '__doc__', '__excepthook__', '__name__', '__stderr__', | ||||
|  '__stdin__', '__stdout__', '_getframe', 'argv', 'builtin_module_names', | ||||
|  'byteorder', 'copyright', 'displayhook', 'exc_info', 'exc_type', | ||||
|  'excepthook', 'exec_prefix', 'executable', 'exit', 'getdefaultencoding', | ||||
|  'getdlopenflags', 'getrecursionlimit', 'getrefcount', 'hexversion', | ||||
|  'maxint', 'maxunicode', 'modules', 'path', 'platform', 'prefix', 'ps1', | ||||
|  'ps2', 'setcheckinterval', 'setdlopenflags', 'setprofile', | ||||
|  'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout', 'version', | ||||
|  'version_info', 'warnoptions'] | ||||
|  '__stdin__', '__stdout__', '_getframe', 'api_version', 'argv',  | ||||
|  'builtin_module_names', 'byteorder', 'callstats', 'copyright', | ||||
|  'displayhook', 'exc_clear', 'exc_info', 'exc_type', 'excepthook', | ||||
|  'exec_prefix', 'executable', 'exit', 'getdefaultencoding', 'getdlopenflags', | ||||
|  'getrecursionlimit', 'getrefcount', 'hexversion', 'maxint', 'maxunicode', | ||||
|  'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache', | ||||
|  'platform', 'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setdlopenflags', | ||||
|  'setprofile', 'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout', | ||||
|  'version', 'version_info', 'warnoptions'] | ||||
| \end{verbatim} | ||||
| 
 | ||||
| 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 | ||||
|     # 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): | ||||
|         self.assertRaises(TypeError, sys.exit, 42, 42) | ||||
| 
 | ||||
|  |  | |||
|  | @ -12,6 +12,12 @@ What's New in Python 2.3 beta 1? | |||
| 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 | ||||
|   if the key value was larger than 2**32.  See SF bug #689659. | ||||
| 
 | ||||
|  |  | |||
|  | @ -132,7 +132,7 @@ PyDoc_STRVAR(excepthook_doc, | |||
| ); | ||||
| 
 | ||||
| static PyObject * | ||||
| sys_exc_info(PyObject *self) | ||||
| sys_exc_info(PyObject *self, PyObject *noargs) | ||||
| { | ||||
| 	PyThreadState *tstate; | ||||
| 	tstate = PyThreadState_Get(); | ||||
|  | @ -147,8 +147,39 @@ sys_exc_info(PyObject *self) | |||
| PyDoc_STRVAR(exc_info_doc, | ||||
| "exc_info() -> (type, value, traceback)\n\
 | ||||
| \n\ | ||||
| Return information about the exception that is currently being handled.\n\ | ||||
| This should be called from inside an except clause only." | ||||
| Return information about the most recent exception caught by an except\n\ | ||||
| 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 * | ||||
|  | @ -600,7 +631,8 @@ static PyMethodDef sys_methods[] = { | |||
| 	{"callstats", (PyCFunction)PyEval_GetCallStats, METH_NOARGS,  | ||||
| 	 callstats_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}, | ||||
| 	{"exit",	sys_exit, METH_VARARGS, exit_doc}, | ||||
| #ifdef Py_USING_UNICODE | ||||
|  | @ -786,6 +818,7 @@ Functions:\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\ | ||||
| exc_clear() -- clear the exception state for the current thread\n\ | ||||
| exit() -- exit the interpreter by raising SystemExit\n\ | ||||
| getdlopenflags() -- returns flags to be used for dlopen() calls\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