diff options
author | Guido van Rossum <guido@python.org> | 2006-02-28 21:57:43 +0000 |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2006-02-28 21:57:43 +0000 |
commit | 1a5e21e0334a6d4e1c756575023c7157fc9ee306 (patch) | |
tree | d2c1c9383b3c6d8194449ae756e663b0b0ac9e4e /Python | |
parent | 87a8b4fee56b8204ee9f7b0ce2e5db0564e8f86e (diff) | |
download | cpython-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.c | 26 | ||||
-rw-r--r-- | Python/errors.c | 1 |
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; } |