summaryrefslogtreecommitdiff
path: root/Python/ceval.c
diff options
context:
space:
mode:
authorAmaury Forgeot d'Arc <amauryfa@gmail.com>2008-12-10 23:22:49 +0000
committerAmaury Forgeot d'Arc <amauryfa@gmail.com>2008-12-10 23:22:49 +0000
commitad9b5992e3525c8a53ec6add3fee1f97142dc503 (patch)
tree889d5d5133ffeea501626369c635c67306fd927f /Python/ceval.c
parentffd42cf4442418ad8f22080377717d9d2b27f695 (diff)
downloadcpython-git-ad9b5992e3525c8a53ec6add3fee1f97142dc503.tar.gz
#4559: When a context manager's __exit__() method returns an object whose
conversion to bool raises an exception, 'with' loses that exception. Reviewed by Jeffrey Yasskin. Already ported to 2.5, will port to 2.6 and 3.0
Diffstat (limited to 'Python/ceval.c')
-rw-r--r--Python/ceval.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index 0a1d86a9d7..bd35185c84 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -2349,11 +2349,20 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
/* XXX Not the fastest way to call it... */
x = PyObject_CallFunctionObjArgs(exit_func, u, v, w,
NULL);
- if (x == NULL) {
- Py_DECREF(exit_func);
+ Py_DECREF(exit_func);
+ if (x == NULL)
break; /* Go to error exit */
- }
- if (u != Py_None && PyObject_IsTrue(x)) {
+
+ if (u != Py_None)
+ err = PyObject_IsTrue(x);
+ else
+ err = 0;
+ Py_DECREF(x);
+
+ if (err < 0)
+ break; /* Go to error exit */
+ else if (err > 0) {
+ err = 0;
/* There was an exception and a true return */
STACKADJ(-2);
Py_INCREF(Py_None);
@@ -2365,8 +2374,6 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
/* The stack was rearranged to remove EXIT
above. Let END_FINALLY do its thing */
}
- Py_DECREF(x);
- Py_DECREF(exit_func);
PREDICT(END_FINALLY);
break;
}