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
b4fb6e4d
Commit
b4fb6e4d
authored
Jun 14, 2008
by
Guido van Rossum
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implicit exception chaining via __context__ (PEP 3134).
Patch 3108 by Antooine Pitrou.
parent
973124fd
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
139 additions
and
33 deletions
+139
-33
Lib/test/test_exceptions.py
Lib/test/test_exceptions.py
+6
-1
Lib/test/test_raise.py
Lib/test/test_raise.py
+96
-26
Python/ceval.c
Python/ceval.c
+6
-4
Python/errors.c
Python/errors.c
+31
-2
No files found.
Lib/test/test_exceptions.py
View file @
b4fb6e4d
...
...
@@ -480,7 +480,12 @@ class ExceptionTests(unittest.TestCase):
inner_raising_func
()
except
:
raise
KeyError
except
KeyError
:
except
KeyError
as
e
:
# We want to test that the except block above got rid of
# the exception raised in inner_raising_func(), but it
# also ends up in the __context__ of the KeyError, so we
# must clear the latter manually for our test to succeed.
e
.
__context__
=
None
obj
=
None
obj
=
wr
()
self
.
failUnless
(
obj
is
None
,
"%s"
%
obj
)
...
...
Lib/test/test_raise.py
View file @
b4fb6e4d
...
...
@@ -181,32 +181,102 @@ class TestTraceback(unittest.TestCase):
self
.
fail
(
"No exception raised"
)
# Disabled until context is implemented
# class TestContext(object):
# def test_instance_context_bare_raise(self):
# context = IndexError()
# try:
# try:
# raise context
# except:
# raise OSError()
# except OSError as e:
# self.assertEqual(e.__context__, context)
# else:
# self.fail("No exception raised")
#
# def test_class_context_bare_raise(self):
# context = IndexError
# try:
# try:
# raise context
# except:
# raise OSError()
# except OSError as e:
# self.assertNotEqual(e.__context__, context)
# self.failUnless(isinstance(e.__context__, context))
# else:
# self.fail("No exception raised")
class
TestContext
(
unittest
.
TestCase
):
def
test_instance_context_instance_raise
(
self
):
context
=
IndexError
()
try
:
try
:
raise
context
except
:
raise
OSError
()
except
OSError
as
e
:
self
.
assertEqual
(
e
.
__context__
,
context
)
else
:
self
.
fail
(
"No exception raised"
)
def
test_class_context_instance_raise
(
self
):
context
=
IndexError
try
:
try
:
raise
context
except
:
raise
OSError
()
except
OSError
as
e
:
self
.
assertNotEqual
(
e
.
__context__
,
context
)
self
.
failUnless
(
isinstance
(
e
.
__context__
,
context
))
else
:
self
.
fail
(
"No exception raised"
)
def
test_class_context_class_raise
(
self
):
context
=
IndexError
try
:
try
:
raise
context
except
:
raise
OSError
except
OSError
as
e
:
self
.
assertNotEqual
(
e
.
__context__
,
context
)
self
.
failUnless
(
isinstance
(
e
.
__context__
,
context
))
else
:
self
.
fail
(
"No exception raised"
)
def
test_c_exception_context
(
self
):
try
:
try
:
1
/
0
except
:
raise
OSError
except
OSError
as
e
:
self
.
failUnless
(
isinstance
(
e
.
__context__
,
ZeroDivisionError
))
else
:
self
.
fail
(
"No exception raised"
)
def
test_c_exception_raise
(
self
):
try
:
try
:
1
/
0
except
:
xyzzy
except
NameError
as
e
:
self
.
failUnless
(
isinstance
(
e
.
__context__
,
ZeroDivisionError
))
else
:
self
.
fail
(
"No exception raised"
)
def
test_noraise_finally
(
self
):
try
:
try
:
pass
finally
:
raise
OSError
except
OSError
as
e
:
self
.
failUnless
(
e
.
__context__
is
None
)
else
:
self
.
fail
(
"No exception raised"
)
def
test_raise_finally
(
self
):
try
:
try
:
1
/
0
finally
:
raise
OSError
except
OSError
as
e
:
self
.
failUnless
(
isinstance
(
e
.
__context__
,
ZeroDivisionError
))
else
:
self
.
fail
(
"No exception raised"
)
def
test_context_manager
(
self
):
class
ContextManager
:
def
__enter__
(
self
):
pass
def
__exit__
(
self
,
t
,
v
,
tb
):
xyzzy
try
:
with
ContextManager
():
1
/
0
except
NameError
as
e
:
self
.
failUnless
(
isinstance
(
e
.
__context__
,
ZeroDivisionError
))
else
:
self
.
fail
(
"No exception raised"
)
class
TestRemovedFunctionality
(
unittest
.
TestCase
):
...
...
Python/ceval.c
View file @
b4fb6e4d
...
...
@@ -2817,11 +2817,12 @@ fail: /* Jump here from prelude on failure */
static
enum
why_code
do_raise
(
PyObject
*
exc
,
PyObject
*
cause
)
{
PyObject
*
type
=
NULL
,
*
value
=
NULL
,
*
tb
=
NULL
;
PyObject
*
type
=
NULL
,
*
value
=
NULL
;
if
(
exc
==
NULL
)
{
/* Reraise */
PyThreadState
*
tstate
=
PyThreadState_GET
();
PyObject
*
tb
;
type
=
tstate
->
exc_type
;
value
=
tstate
->
exc_value
;
tb
=
tstate
->
exc_traceback
;
...
...
@@ -2862,7 +2863,6 @@ do_raise(PyObject *exc, PyObject *cause)
goto
raise_error
;
}
tb
=
PyException_GetTraceback
(
value
);
if
(
cause
)
{
PyObject
*
fixed_cause
;
if
(
PyExceptionClass_Check
(
cause
))
{
...
...
@@ -2883,13 +2883,15 @@ do_raise(PyObject *exc, PyObject *cause)
PyException_SetCause
(
value
,
fixed_cause
);
}
PyErr_Restore
(
type
,
value
,
tb
);
PyErr_SetObject
(
type
,
value
);
/* PyErr_SetObject incref's its arguments */
Py_XDECREF
(
value
);
Py_XDECREF
(
type
);
return
WHY_EXCEPTION
;
raise_error:
Py_XDECREF
(
value
);
Py_XDECREF
(
type
);
Py_XDECREF
(
tb
);
Py_XDECREF
(
cause
);
return
WHY_EXCEPTION
;
}
...
...
Python/errors.c
View file @
b4fb6e4d
...
...
@@ -52,6 +52,9 @@ PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback)
void
PyErr_SetObject
(
PyObject
*
exception
,
PyObject
*
value
)
{
PyThreadState
*
tstate
=
PyThreadState_GET
();
PyObject
*
tb
=
NULL
;
if
(
exception
!=
NULL
&&
!
PyExceptionClass_Check
(
exception
))
{
PyErr_Format
(
PyExc_SystemError
,
...
...
@@ -59,9 +62,35 @@ PyErr_SetObject(PyObject *exception, PyObject *value)
exception
);
return
;
}
Py_XINCREF
(
exception
);
Py_XINCREF
(
value
);
PyErr_Restore
(
exception
,
value
,
(
PyObject
*
)
NULL
);
if
(
tstate
->
exc_value
!=
NULL
&&
tstate
->
exc_value
!=
Py_None
)
{
/* Implicit exception chaining */
if
(
value
==
NULL
||
!
PyExceptionInstance_Check
(
value
))
{
/* We must normalize the value right now */
PyObject
*
args
,
*
fixed_value
;
if
(
value
==
NULL
||
value
==
Py_None
)
args
=
PyTuple_New
(
0
);
else
if
(
PyTuple_Check
(
value
))
{
Py_INCREF
(
value
);
args
=
value
;
}
else
args
=
PyTuple_Pack
(
1
,
value
);
fixed_value
=
args
?
PyEval_CallObject
(
exception
,
args
)
:
NULL
;
Py_XDECREF
(
args
);
Py_XDECREF
(
value
);
if
(
fixed_value
==
NULL
)
return
;
value
=
fixed_value
;
}
Py_INCREF
(
tstate
->
exc_value
);
PyException_SetContext
(
value
,
tstate
->
exc_value
);
}
if
(
value
!=
NULL
&&
PyExceptionInstance_Check
(
value
))
tb
=
PyException_GetTraceback
(
value
);
Py_XINCREF
(
exception
);
PyErr_Restore
(
exception
,
value
,
tb
);
}
void
...
...
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