[Python-checkins] r43607 - in python/trunk/Lib: contextlib.py test/test_with.py

Jim Jewett jimjjewett at gmail.com
Mon Apr 3 22:48:10 CEST 2006


Shouldn't the StopIteration be raised instead of returned?

As in, shouldn't


            except StopIteration:
                # 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
                # an exception unless __exit__() itself failed.  But throw()
                # has to raise the exception to signal propagation, so this
                # fixes the impedance mismatch between the throw() protocol
                # and the __exit__() protocol.
                #
                if sys.exc_info()[1] is not value:
                    raise


turn into

            except StopIteration:
                # Supress the exception unless it's the same exception the
                # was passed to throw().
                if sys.exc_info()[1] is value:
                    return False
                raise
            except:
                # only re-raise if it's *not* the exception that was
                # passed to throw(), because __exit__() must not raise
                # an exception unless __exit__() itself failed.  But throw()
                # has to raise the exception to signal propagation, so this
                # fixes the impedance mismatch between the throw() protocol
                # and the __exit__() protocol.
                #
                if sys.exc_info()[1] is not value:
                    raise
                return True

On 4/3/06, phillip.eby <python-checkins at python.org> wrote:
> Author: phillip.eby
> Date: Mon Apr  3 22:05:05 2006
> New Revision: 43607
>
> Modified:
>    python/trunk/Lib/contextlib.py
>    python/trunk/Lib/test/test_with.py
> Log:
> Fix SF#1462485: StopIteration raised in body of 'with' statement suppressed
>
>
> Modified: python/trunk/Lib/contextlib.py
> ==============================================================================
> --- python/trunk/Lib/contextlib.py      (original)
> +++ python/trunk/Lib/contextlib.py      Mon Apr  3 22:05:05 2006
> @@ -32,7 +32,9 @@
>                  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
>
> Modified: python/trunk/Lib/test/test_with.py
> ==============================================================================
> --- python/trunk/Lib/test/test_with.py  (original)
> +++ python/trunk/Lib/test/test_with.py  Mon Apr  3 22:05:05 2006
> @@ -494,6 +494,62 @@
>          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):
>
> _______________________________________________
> Python-checkins mailing list
> Python-checkins at python.org
> http://mail.python.org/mailman/listinfo/python-checkins
>


More information about the Python-checkins mailing list