[Python-checkins] r67690 - in python/branches/release30-maint: Lib/test/test_with.py Misc/NEWS Python/ceval.c

amaury.forgeotdarc python-checkins at python.org
Thu Dec 11 00:55:09 CET 2008


Author: amaury.forgeotdarc
Date: Thu Dec 11 00:55:09 2008
New Revision: 67690

Log:
Merged revisions 67689 via svnmerge from 
svn+ssh://pythondev@svn.python.org/python/branches/py3k

................
  r67689 | amaury.forgeotdarc | 2008-12-11 00:49:33 +0100 (jeu., 11 déc. 2008) | 13 lines
  
  Merged revisions 67688 via svnmerge from 
  svn+ssh://pythondev@svn.python.org/python/trunk
  
  ........
    r67688 | amaury.forgeotdarc | 2008-12-11 00:22:49 +0100 (jeu., 11 déc. 2008) | 6 lines
    
    #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
  ........
................


Modified:
   python/branches/release30-maint/   (props changed)
   python/branches/release30-maint/Lib/test/test_with.py
   python/branches/release30-maint/Misc/NEWS
   python/branches/release30-maint/Python/ceval.c

Modified: python/branches/release30-maint/Lib/test/test_with.py
==============================================================================
--- python/branches/release30-maint/Lib/test/test_with.py	(original)
+++ python/branches/release30-maint/Lib/test/test_with.py	Thu Dec 11 00:55:09 2008
@@ -505,6 +505,36 @@
 
         self.assertRaises(GeneratorExit, shouldThrow)
 
+    def testErrorsInBool(self):
+        # issue4589: __exit__ return code may raise an exception
+        # when looking at its truth value.
+
+        class cm(object):
+            def __init__(self, bool_conversion):
+                class Bool:
+                    def __bool__(self):
+                        return bool_conversion()
+                self.exit_result = Bool()
+            def __enter__(self):
+                return 3
+            def __exit__(self, a, b, c):
+                return self.exit_result
+
+        def trueAsBool():
+            with cm(lambda: True):
+                self.fail("Should NOT see this")
+        trueAsBool()
+
+        def falseAsBool():
+            with cm(lambda: False):
+                self.fail("Should raise")
+        self.assertRaises(AssertionError, falseAsBool)
+
+        def failAsBool():
+            with cm(lambda: 1//0):
+                self.fail("Should NOT see this")
+        self.assertRaises(ZeroDivisionError, failAsBool)
+
 
 class NonLocalFlowControlTestCase(unittest.TestCase):
 

Modified: python/branches/release30-maint/Misc/NEWS
==============================================================================
--- python/branches/release30-maint/Misc/NEWS	(original)
+++ python/branches/release30-maint/Misc/NEWS	Thu Dec 11 00:55:09 2008
@@ -12,6 +12,9 @@
 Core and Builtins
 -----------------
 
+- Issue #4597: Fixed exception handling when the __exit__ function of a
+  context manager returns a value that cannot be converted to a bool.
+
 - Issue #4533: File read operation was dreadfully slow due to a slowly
   growing read buffer. Fixed by using the same growth rate algorithm as
   Python 2.x.

Modified: python/branches/release30-maint/Python/ceval.c
==============================================================================
--- python/branches/release30-maint/Python/ceval.c	(original)
+++ python/branches/release30-maint/Python/ceval.c	Thu Dec 11 00:55:09 2008
@@ -2181,7 +2181,17 @@
 			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);
 				SET_TOP(PyLong_FromLong((long) WHY_SILENCED));
@@ -2189,7 +2199,6 @@
 				Py_DECREF(v);
 				Py_DECREF(w);
 			}
-			Py_DECREF(x);
 			PREDICT(END_FINALLY);
 			break;
 		}


More information about the Python-checkins mailing list