mirror of
https://github.com/python/cpython.git
synced 2025-07-29 06:05:00 +00:00
Fix SF#1462485: StopIteration raised in body of 'with' statement suppressed
This commit is contained in:
parent
9161a0d8da
commit
9444bd51c4
2 changed files with 59 additions and 1 deletions
|
@ -32,7 +32,9 @@ class GeneratorContextManager(object):
|
||||||
self.gen.throw(type, value, traceback)
|
self.gen.throw(type, value, traceback)
|
||||||
raise RuntimeError("generator didn't stop after throw()")
|
raise RuntimeError("generator didn't stop after throw()")
|
||||||
except StopIteration:
|
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:
|
except:
|
||||||
# only re-raise if it's *not* the exception that was
|
# only re-raise if it's *not* the exception that was
|
||||||
# passed to throw(), because __exit__() must not raise
|
# passed to throw(), because __exit__() must not raise
|
||||||
|
|
|
@ -494,6 +494,62 @@ class ExceptionalTestCase(unittest.TestCase, ContextmanagerAssertionMixin):
|
||||||
self.assertAfterWithGeneratorInvariantsWithError(self.foo)
|
self.assertAfterWithGeneratorInvariantsWithError(self.foo)
|
||||||
self.assertAfterWithGeneratorInvariantsNoError(self.bar)
|
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):
|
class NonLocalFlowControlTestCase(unittest.TestCase):
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue