Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 46d3dc3

Browse files
committed
- 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!
1 parent d1a283b commit 46d3dc3

5 files changed

Lines changed: 116 additions & 12 deletions

File tree

Doc/lib/libsys.tex

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,11 @@ \section{\module{sys} ---
9999
encapsulates the call stack at the point where the exception
100100
originally occurred. \obindex{traceback}
101101

102+
If \function{exc_clear()} is called, this function will return three
103+
\code{None} values until either another exception is raised in the
104+
current thread or the execution stack returns to a frame where
105+
another exception is being handled.
106+
102107
\warning{Assigning the \var{traceback} return value to a
103108
local variable in a function that is handling an exception will
104109
cause a circular reference. This will prevent anything referenced
@@ -115,6 +120,21 @@ \section{\module{sys} ---
115120
efficient to avoid creating cycles.}
116121
\end{funcdesc}
117122

123+
\begin{funcdesc}{exc_clear}{}
124+
This function clears all information relating to the current or last
125+
exception that occured in the current thread. After calling this
126+
function, \function{exc_info()} will return three \code{None} values until
127+
another exception is raised in the current thread or the execution stack
128+
returns to a frame where another exception is being handled.
129+
130+
This function is only needed in only a few obscure situations. These
131+
include logging and error handling systems that report information on the
132+
last or current exception. This function can also be used to try to free
133+
resources and trigger object finalization, though no guarantee is made as
134+
to what objects will be freed, if any.
135+
\versionadded{2.3}
136+
\end{funcdesc}
137+
118138
\begin{datadesc}{exc_type}
119139
\dataline{exc_value}
120140
\dataline{exc_traceback}

Doc/tut/tut.tex

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2451,14 +2451,15 @@ \section{The \function{dir()} Function \label{dir}}
24512451
['__name__', 'fib', 'fib2']
24522452
>>> dir(sys)
24532453
['__displayhook__', '__doc__', '__excepthook__', '__name__', '__stderr__',
2454-
'__stdin__', '__stdout__', '_getframe', 'argv', 'builtin_module_names',
2455-
'byteorder', 'copyright', 'displayhook', 'exc_info', 'exc_type',
2456-
'excepthook', 'exec_prefix', 'executable', 'exit', 'getdefaultencoding',
2457-
'getdlopenflags', 'getrecursionlimit', 'getrefcount', 'hexversion',
2458-
'maxint', 'maxunicode', 'modules', 'path', 'platform', 'prefix', 'ps1',
2459-
'ps2', 'setcheckinterval', 'setdlopenflags', 'setprofile',
2460-
'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout', 'version',
2461-
'version_info', 'warnoptions']
2454+
'__stdin__', '__stdout__', '_getframe', 'api_version', 'argv',
2455+
'builtin_module_names', 'byteorder', 'callstats', 'copyright',
2456+
'displayhook', 'exc_clear', 'exc_info', 'exc_type', 'excepthook',
2457+
'exec_prefix', 'executable', 'exit', 'getdefaultencoding', 'getdlopenflags',
2458+
'getrecursionlimit', 'getrefcount', 'hexversion', 'maxint', 'maxunicode',
2459+
'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache',
2460+
'platform', 'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setdlopenflags',
2461+
'setprofile', 'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout',
2462+
'version', 'version_info', 'warnoptions']
24622463
\end{verbatim}
24632464

24642465
Without arguments, \function{dir()} lists the names you have defined

Lib/test/test_sys.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,50 @@ def test_original_excepthook(self):
6363
# FIXME: testing the code for a lost or replaced excepthook in
6464
# Python/pythonrun.c::PyErr_PrintEx() is tricky.
6565

66+
def test_exc_clear(self):
67+
self.assertRaises(TypeError, sys.exc_clear, 42)
68+
69+
# Verify that exc_info is present and matches exc, then clear it, and
70+
# check that it worked.
71+
def clear_check(exc):
72+
typ, value, traceback = sys.exc_info()
73+
self.assert_(typ is not None)
74+
self.assert_(value is exc)
75+
self.assert_(traceback is not None)
76+
77+
sys.exc_clear()
78+
79+
typ, value, traceback = sys.exc_info()
80+
self.assert_(typ is None)
81+
self.assert_(value is None)
82+
self.assert_(traceback is None)
83+
84+
def clear():
85+
try:
86+
raise ValueError, 42
87+
except ValueError, exc:
88+
clear_check(exc)
89+
90+
# Raise an exception and check that it can be cleared
91+
clear()
92+
93+
# Verify that a frame currently handling an exception is
94+
# unaffected by calling exc_clear in a nested frame.
95+
try:
96+
raise ValueError, 13
97+
except ValueError, exc:
98+
typ1, value1, traceback1 = sys.exc_info()
99+
clear()
100+
typ2, value2, traceback2 = sys.exc_info()
101+
102+
self.assert_(typ1 is typ2)
103+
self.assert_(value1 is exc)
104+
self.assert_(value1 is value2)
105+
self.assert_(traceback1 is traceback2)
106+
107+
# Check that an exception can be cleared outside of an except block
108+
clear_check(exc)
109+
66110
def test_exit(self):
67111
self.assertRaises(TypeError, sys.exit, 42, 42)
68112

Misc/NEWS

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ What's New in Python 2.3 beta 1?
1212
Core and builtins
1313
-----------------
1414

15+
16+
- New function sys.exc_clear() clears the current exception. This is
17+
rarely needed, but can sometimes be useful to release objects
18+
referenced by the traceback held in sys.exc_info()[2]. (SF patch
19+
#693195.)
20+
1521
- On 64-bit systems, a dictionary could contain duplicate long/int keys
1622
if the key value was larger than 2**32. See SF bug #689659.
1723

Python/sysmodule.c

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ PyDoc_STRVAR(excepthook_doc,
132132
);
133133

134134
static PyObject *
135-
sys_exc_info(PyObject *self)
135+
sys_exc_info(PyObject *self, PyObject *noargs)
136136
{
137137
PyThreadState *tstate;
138138
tstate = PyThreadState_Get();
@@ -147,8 +147,39 @@ sys_exc_info(PyObject *self)
147147
PyDoc_STRVAR(exc_info_doc,
148148
"exc_info() -> (type, value, traceback)\n\
149149
\n\
150-
Return information about the exception that is currently being handled.\n\
151-
This should be called from inside an except clause only."
150+
Return information about the most recent exception caught by an except\n\
151+
clause in the current stack frame or in an older stack frame."
152+
);
153+
154+
static PyObject *
155+
sys_exc_clear(PyObject *self, PyObject *noargs)
156+
{
157+
PyThreadState *tstate = PyThreadState_Get();
158+
PyObject *tmp_type, *tmp_value, *tmp_tb;
159+
tmp_type = tstate->exc_type;
160+
tmp_value = tstate->exc_value;
161+
tmp_tb = tstate->exc_traceback;
162+
tstate->exc_type = NULL;
163+
tstate->exc_value = NULL;
164+
tstate->exc_traceback = NULL;
165+
Py_XDECREF(tmp_type);
166+
Py_XDECREF(tmp_value);
167+
Py_XDECREF(tmp_tb);
168+
/* For b/w compatibility */
169+
PySys_SetObject("exc_type", Py_None);
170+
PySys_SetObject("exc_value", Py_None);
171+
PySys_SetObject("exc_traceback", Py_None);
172+
Py_INCREF(Py_None);
173+
return Py_None;
174+
}
175+
176+
PyDoc_STRVAR(exc_clear_doc,
177+
"exc_clear() -> None\n\
178+
\n\
179+
Clear global information on the current exception. Subsequent calls to\n\
180+
exc_info() will return (None,None,None) until another exception is raised\n\
181+
in the current thread or the execution stack returns to a frame where\n\
182+
another exception is being handled."
152183
);
153184

154185
static PyObject *
@@ -600,7 +631,8 @@ static PyMethodDef sys_methods[] = {
600631
{"callstats", (PyCFunction)PyEval_GetCallStats, METH_NOARGS,
601632
callstats_doc},
602633
{"displayhook", sys_displayhook, METH_O, displayhook_doc},
603-
{"exc_info", (PyCFunction)sys_exc_info, METH_NOARGS, exc_info_doc},
634+
{"exc_info", sys_exc_info, METH_NOARGS, exc_info_doc},
635+
{"exc_clear", sys_exc_clear, METH_NOARGS, exc_clear_doc},
604636
{"excepthook", sys_excepthook, METH_VARARGS, excepthook_doc},
605637
{"exit", sys_exit, METH_VARARGS, exit_doc},
606638
#ifdef Py_USING_UNICODE
@@ -786,6 +818,7 @@ Functions:\n\
786818
displayhook() -- print an object to the screen, and save it in __builtin__._\n\
787819
excepthook() -- print an exception and its traceback to sys.stderr\n\
788820
exc_info() -- return thread-safe information about the current exception\n\
821+
exc_clear() -- clear the exception state for the current thread\n\
789822
exit() -- exit the interpreter by raising SystemExit\n\
790823
getdlopenflags() -- returns flags to be used for dlopen() calls\n\
791824
getrefcount() -- return the reference count for an object (plus one :-)\n\

0 commit comments

Comments
 (0)