Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
aa2efcb0
Commit
aa2efcb0
authored
Apr 19, 2012
by
Martin v. Löwis
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue #14098: New functions PyErr_GetExcInfo and PyErr_SetExcInfo.
Patch by Stefan Behnel.
parent
e27b3608
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
120 additions
and
0 deletions
+120
-0
Doc/c-api/exceptions.rst
Doc/c-api/exceptions.rst
+35
-0
Include/pyerrors.h
Include/pyerrors.h
+2
-0
Lib/test/test_capi.py
Lib/test/test_capi.py
+23
-0
Misc/NEWS
Misc/NEWS
+3
-0
Modules/_testcapimodule.c
Modules/_testcapimodule.c
+24
-0
Python/errors.c
Python/errors.c
+33
-0
No files found.
Doc/c-api/exceptions.rst
View file @
aa2efcb0
...
@@ -129,6 +129,41 @@ in various ways. There is a separate error indicator for each thread.
...
@@ -129,6 +129,41 @@ in various ways. There is a separate error indicator for each thread.
exception state.
exception state.
.. c:function:: void PyErr_GetExcInfo(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback)
Retrieve the exception info, as known from ``sys.exc_info()``. This refers
to an exception that was already caught, not to an exception that was
freshly raised. Returns new references for the three objects, any of which
may be *NULL*. Does not modify the exception info state.
.. note::
This function is not normally used by code that wants to handle exceptions.
Rather, it can be used when code needs to save and restore the exception
state temporarily. Use :c:func:`PyErr_SetExcInfo` to restore or clear the
exception state.
.. versionadded:: 3.3
.. c:function:: void PyErr_SetExcInfo(PyObject *type, PyObject *value, PyObject *traceback)
Set the exception info, as known from ``sys.exc_info()``. This refers
to an exception that was already caught, not to an exception that was
freshly raised. This function steals the references of the arguments.
To clear the exception state, pass *NULL* for all three arguments.
For general rules about the three arguments, see :c:func:`PyErr_Restore`.
.. note::
This function is not normally used by code that wants to handle exceptions.
Rather, it can be used when code needs to save and restore the exception
state temporarily. Use :c:func:`PyErr_GetExcInfo` to read the exception
state.
.. versionadded:: 3.3
.. c:function:: void PyErr_SetString(PyObject *type, const char *message)
.. c:function:: void PyErr_SetString(PyObject *type, const char *message)
This is the most common way to set the error indicator. The first argument
This is the most common way to set the error indicator. The first argument
...
...
Include/pyerrors.h
View file @
aa2efcb0
...
@@ -82,6 +82,8 @@ PyAPI_FUNC(PyObject *) PyErr_Occurred(void);
...
@@ -82,6 +82,8 @@ PyAPI_FUNC(PyObject *) PyErr_Occurred(void);
PyAPI_FUNC
(
void
)
PyErr_Clear
(
void
);
PyAPI_FUNC
(
void
)
PyErr_Clear
(
void
);
PyAPI_FUNC
(
void
)
PyErr_Fetch
(
PyObject
**
,
PyObject
**
,
PyObject
**
);
PyAPI_FUNC
(
void
)
PyErr_Fetch
(
PyObject
**
,
PyObject
**
,
PyObject
**
);
PyAPI_FUNC
(
void
)
PyErr_Restore
(
PyObject
*
,
PyObject
*
,
PyObject
*
);
PyAPI_FUNC
(
void
)
PyErr_Restore
(
PyObject
*
,
PyObject
*
,
PyObject
*
);
PyAPI_FUNC
(
void
)
PyErr_GetExcInfo
(
PyObject
**
,
PyObject
**
,
PyObject
**
);
PyAPI_FUNC
(
void
)
PyErr_SetExcInfo
(
PyObject
*
,
PyObject
*
,
PyObject
*
);
#if defined(__clang__) || \
#if defined(__clang__) || \
(defined(__GNUC__) && \
(defined(__GNUC__) && \
...
...
Lib/test/test_capi.py
View file @
aa2efcb0
...
@@ -55,6 +55,29 @@ class CAPITest(unittest.TestCase):
...
@@ -55,6 +55,29 @@ class CAPITest(unittest.TestCase):
def
test_memoryview_from_NULL_pointer
(
self
):
def
test_memoryview_from_NULL_pointer
(
self
):
self
.
assertRaises
(
ValueError
,
_testcapi
.
make_memoryview_from_NULL_pointer
)
self
.
assertRaises
(
ValueError
,
_testcapi
.
make_memoryview_from_NULL_pointer
)
def
test_exc_info
(
self
):
raised_exception
=
ValueError
(
"5"
)
new_exc
=
TypeError
(
"TEST"
)
try
:
raise
raised_exception
except
ValueError
as
e
:
tb
=
e
.
__traceback__
orig_sys_exc_info
=
sys
.
exc_info
()
orig_exc_info
=
_testcapi
.
set_exc_info
(
new_exc
.
__class__
,
new_exc
,
None
)
new_sys_exc_info
=
sys
.
exc_info
()
new_exc_info
=
_testcapi
.
set_exc_info
(
*
orig_exc_info
)
reset_sys_exc_info
=
sys
.
exc_info
()
self
.
assertEqual
(
orig_exc_info
[
1
],
e
)
self
.
assertSequenceEqual
(
orig_exc_info
,
(
raised_exception
.
__class__
,
raised_exception
,
tb
))
self
.
assertSequenceEqual
(
orig_sys_exc_info
,
orig_exc_info
)
self
.
assertSequenceEqual
(
reset_sys_exc_info
,
orig_exc_info
)
self
.
assertSequenceEqual
(
new_exc_info
,
(
new_exc
.
__class__
,
new_exc
,
None
))
self
.
assertSequenceEqual
(
new_sys_exc_info
,
new_exc_info
)
else
:
self
.
assertTrue
(
False
)
@
unittest
.
skipUnless
(
threading
,
'Threading required for this test.'
)
@
unittest
.
skipUnless
(
threading
,
'Threading required for this test.'
)
class
TestPendingCalls
(
unittest
.
TestCase
):
class
TestPendingCalls
(
unittest
.
TestCase
):
...
...
Misc/NEWS
View file @
aa2efcb0
...
@@ -10,6 +10,9 @@ What's New in Python 3.3.0 Alpha 3?
...
@@ -10,6 +10,9 @@ What's New in Python 3.3.0 Alpha 3?
Core and Builtins
Core and Builtins
-----------------
-----------------
- Issue #14098: New functions PyErr_GetExcInfo and PyErr_SetExcInfo.
Patch by Stefan Behnel.
- Issue #14385: It is now possible to use a custom type for the __builtins__
- Issue #14385: It is now possible to use a custom type for the __builtins__
namespace, instead of a dict. It can be used for sandboxing for example.
namespace, instead of a dict. It can be used for sandboxing for example.
Raise also a NameError instead of ImportError if __build_class__ name if not
Raise also a NameError instead of ImportError if __build_class__ name if not
...
...
Modules/_testcapimodule.c
View file @
aa2efcb0
...
@@ -1639,6 +1639,29 @@ raise_exception(PyObject *self, PyObject *args)
...
@@ -1639,6 +1639,29 @@ raise_exception(PyObject *self, PyObject *args)
return
NULL
;
return
NULL
;
}
}
static
PyObject
*
test_set_exc_info
(
PyObject
*
self
,
PyObject
*
args
)
{
PyObject
*
orig_exc
;
PyObject
*
new_type
,
*
new_value
,
*
new_tb
;
PyObject
*
type
,
*
value
,
*
tb
;
if
(
!
PyArg_ParseTuple
(
args
,
"OOO:test_set_exc_info"
,
&
new_type
,
&
new_value
,
&
new_tb
))
return
NULL
;
PyErr_GetExcInfo
(
&
type
,
&
value
,
&
tb
);
Py_INCREF
(
new_type
);
Py_INCREF
(
new_value
);
Py_INCREF
(
new_tb
);
PyErr_SetExcInfo
(
new_type
,
new_value
,
new_tb
);
orig_exc
=
PyTuple_Pack
(
3
,
type
?
type
:
Py_None
,
value
?
value
:
Py_None
,
tb
?
tb
:
Py_None
);
Py_XDECREF
(
type
);
Py_XDECREF
(
value
);
Py_XDECREF
(
tb
);
return
orig_exc
;
}
static
int
test_run_counter
=
0
;
static
int
test_run_counter
=
0
;
...
@@ -2471,6 +2494,7 @@ static PyMethodDef TestMethods[] = {
...
@@ -2471,6 +2494,7 @@ static PyMethodDef TestMethods[] = {
#endif
#endif
{
"traceback_print"
,
traceback_print
,
METH_VARARGS
},
{
"traceback_print"
,
traceback_print
,
METH_VARARGS
},
{
"exception_print"
,
exception_print
,
METH_VARARGS
},
{
"exception_print"
,
exception_print
,
METH_VARARGS
},
{
"set_exc_info"
,
test_set_exc_info
,
METH_VARARGS
},
{
"argparsing"
,
argparsing
,
METH_VARARGS
},
{
"argparsing"
,
argparsing
,
METH_VARARGS
},
{
"code_newempty"
,
code_newempty
,
METH_VARARGS
},
{
"code_newempty"
,
code_newempty
,
METH_VARARGS
},
{
"make_exception_with_doc"
,
(
PyCFunction
)
make_exception_with_doc
,
{
"make_exception_with_doc"
,
(
PyCFunction
)
make_exception_with_doc
,
...
...
Python/errors.c
View file @
aa2efcb0
...
@@ -320,6 +320,39 @@ PyErr_Clear(void)
...
@@ -320,6 +320,39 @@ PyErr_Clear(void)
PyErr_Restore
(
NULL
,
NULL
,
NULL
);
PyErr_Restore
(
NULL
,
NULL
,
NULL
);
}
}
void
PyErr_GetExcInfo
(
PyObject
**
p_type
,
PyObject
**
p_value
,
PyObject
**
p_traceback
)
{
PyThreadState
*
tstate
=
PyThreadState_GET
();
*
p_type
=
tstate
->
exc_type
;
*
p_value
=
tstate
->
exc_value
;
*
p_traceback
=
tstate
->
exc_traceback
;
Py_XINCREF
(
*
p_type
);
Py_XINCREF
(
*
p_value
);
Py_XINCREF
(
*
p_traceback
);
}
void
PyErr_SetExcInfo
(
PyObject
*
p_type
,
PyObject
*
p_value
,
PyObject
*
p_traceback
)
{
PyObject
*
oldtype
,
*
oldvalue
,
*
oldtraceback
;
PyThreadState
*
tstate
=
PyThreadState_GET
();
oldtype
=
tstate
->
exc_type
;
oldvalue
=
tstate
->
exc_value
;
oldtraceback
=
tstate
->
exc_traceback
;
tstate
->
exc_type
=
p_type
;
tstate
->
exc_value
=
p_value
;
tstate
->
exc_traceback
=
p_traceback
;
Py_XDECREF
(
oldtype
);
Py_XDECREF
(
oldvalue
);
Py_XDECREF
(
oldtraceback
);
}
/* Convenience functions to set a type error exception and return 0 */
/* Convenience functions to set a type error exception and return 0 */
int
int
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment