diff Python/ceval.c @ 36737:fa92fe15251a legacy-trunk

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.
author Guido van Rossum <guido@python.org>
date Tue, 28 Feb 2006 21:57:43 +0000
parents 5c36c222e7ca
children 8e04de2480e4
line wrap: on
line diff
--- a/Python/ceval.c	Tue Feb 28 21:41:30 2006 +0000
+++ b/Python/ceval.c	Tue Feb 28 21:57:43 2006 +0000
@@ -2200,23 +2200,37 @@
 			   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;
 		}