summaryrefslogtreecommitdiff
path: root/Python
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2006-02-28 21:57:43 +0000
committerGuido van Rossum <guido@python.org>2006-02-28 21:57:43 +0000
commit1a5e21e0334a6d4e1c756575023c7157fc9ee306 (patch)
treed2c1c9383b3c6d8194449ae756e663b0b0ac9e4e /Python
parent87a8b4fee56b8204ee9f7b0ce2e5db0564e8f86e (diff)
downloadcpython-git-1a5e21e0334a6d4e1c756575023c7157fc9ee306.tar.gz
Updates to the with-statement:
- New semantics for __exit__() -- it must re-raise the exception if type is not None; the with-statement itself doesn't do this. (See the updated PEP for motivation.) - Added context managers to: - file - thread.LockType - threading.{Lock,RLock,Condition,Semaphore,BoundedSemaphore} - decimal.Context - Added contextlib.py, which defines @contextmanager, nested(), closing(). - Unit tests all around; bot no docs yet.
Diffstat (limited to 'Python')
-rw-r--r--Python/ceval.c26
-rw-r--r--Python/errors.c1
2 files changed, 21 insertions, 6 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index 3732f6db75..3ef853ea1b 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -2200,23 +2200,37 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throw)
The code here just sets the stack up for the call;
separate CALL_FUNCTION(3) and POP_TOP opcodes are
emitted by the compiler.
+
+ In addition, if the stack represents an exception,
+ we "zap" this information; __exit__() should
+ re-raise the exception if it wants to, and if
+ __exit__() returns normally, END_FINALLY should
+ *not* re-raise the exception. (But non-local
+ gotos should still be resumed.)
*/
x = TOP();
u = SECOND();
if (PyInt_Check(u) || u == Py_None) {
u = v = w = Py_None;
+ Py_INCREF(u);
+ Py_INCREF(v);
+ Py_INCREF(w);
}
else {
v = THIRD();
w = FOURTH();
+ /* Zap the exception from the stack,
+ to fool END_FINALLY. */
+ STACKADJ(-2);
+ SET_TOP(x);
+ Py_INCREF(Py_None);
+ SET_SECOND(Py_None);
}
- Py_INCREF(u);
- Py_INCREF(v);
- Py_INCREF(w);
- PUSH(u);
- PUSH(v);
- PUSH(w);
+ STACKADJ(3);
+ SET_THIRD(u);
+ SET_SECOND(v);
+ SET_TOP(w);
break;
}
diff --git a/Python/errors.c b/Python/errors.c
index cbcc6facaf..c33bd13bde 100644
--- a/Python/errors.c
+++ b/Python/errors.c
@@ -24,6 +24,7 @@ PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback)
if (traceback != NULL && !PyTraceBack_Check(traceback)) {
/* XXX Should never happen -- fatal error instead? */
+ /* Well, it could be None. */
Py_DECREF(traceback);
traceback = NULL;
}