Fix SF#1462485: StopIteration raised in body of 'with' statement suppressed

This commit is contained in:
Phillip J. Eby 2006-04-03 20:05:05 +00:00
parent 9161a0d8da
commit 9444bd51c4
2 changed files with 59 additions and 1 deletions

View File

@ -32,7 +32,9 @@ class GeneratorContextManager(object):
self.gen.throw(type, value, traceback)
raise RuntimeError("generator didn't stop after throw()")
except StopIteration:
return True
# Supress the exception unless it's the same exception the
# was passed to throw().
return sys.exc_info()[1] is not value
except:
# only re-raise if it's *not* the exception that was
# passed to throw(), because __exit__() must not raise

View File

@ -494,6 +494,62 @@ class ExceptionalTestCase(unittest.TestCase, ContextmanagerAssertionMixin):
self.assertAfterWithGeneratorInvariantsWithError(self.foo)
self.assertAfterWithGeneratorInvariantsNoError(self.bar)
def testRaisedStopIteration1(self):
@contextmanager
def cm():
yield
def shouldThrow():
with cm():
raise StopIteration("from with")
self.assertRaises(StopIteration, shouldThrow)
def testRaisedStopIteration2(self):
class cm (object):
def __context__(self):
return self
def __enter__(self):
pass
def __exit__(self, type, value, traceback):
pass
def shouldThrow():
with cm():
raise StopIteration("from with")
self.assertRaises(StopIteration, shouldThrow)
def testRaisedGeneratorExit1(self):
@contextmanager
def cm():
yield
def shouldThrow():
with cm():
raise GeneratorExit("from with")
self.assertRaises(GeneratorExit, shouldThrow)
def testRaisedGeneratorExit2(self):
class cm (object):
def __context__(self):
return self
def __enter__(self):
pass
def __exit__(self, type, value, traceback):
pass
def shouldThrow():
with cm():
raise GeneratorExit("from with")
self.assertRaises(GeneratorExit, shouldThrow)
class NonLocalFlowControlTestCase(unittest.TestCase):