Commit 10b24e87 authored by Amaury Forgeot d'Arc's avatar Amaury Forgeot d'Arc

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
........
parent ee763951
...@@ -505,6 +505,36 @@ class ExceptionalTestCase(ContextmanagerAssertionMixin, unittest.TestCase): ...@@ -505,6 +505,36 @@ class ExceptionalTestCase(ContextmanagerAssertionMixin, unittest.TestCase):
self.assertRaises(GeneratorExit, shouldThrow) 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): class NonLocalFlowControlTestCase(unittest.TestCase):
......
...@@ -12,6 +12,9 @@ What's New in Python 3.1 alpha 0 ...@@ -12,6 +12,9 @@ What's New in Python 3.1 alpha 0
Core and Builtins 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 #4445: Replace "sizeof(PyBytesObject)" with - Issue #4445: Replace "sizeof(PyBytesObject)" with
"offsetof(PyBytesObject, ob_sval) + 1" when allocating memory for "offsetof(PyBytesObject, ob_sval) + 1" when allocating memory for
bytes instances. On a typical machine this saves 3 bytes of memory bytes instances. On a typical machine this saves 3 bytes of memory
......
...@@ -2189,7 +2189,17 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) ...@@ -2189,7 +2189,17 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
Py_DECREF(exit_func); Py_DECREF(exit_func);
if (x == NULL) if (x == NULL)
break; /* Go to error exit */ 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 */ /* There was an exception and a True return */
STACKADJ(-2); STACKADJ(-2);
SET_TOP(PyLong_FromLong((long) WHY_SILENCED)); SET_TOP(PyLong_FromLong((long) WHY_SILENCED));
...@@ -2197,7 +2207,6 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) ...@@ -2197,7 +2207,6 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
Py_DECREF(v); Py_DECREF(v);
Py_DECREF(w); Py_DECREF(w);
} }
Py_DECREF(x);
PREDICT(END_FINALLY); PREDICT(END_FINALLY);
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment