diff options
author | Yury Selivanov <yselivanov@sprymix.com> | 2015-05-22 15:16:47 (GMT) |
---|---|---|
committer | Yury Selivanov <yselivanov@sprymix.com> | 2015-05-22 15:16:47 (GMT) |
commit | 683333955a05a31da5f0b2ca1b3bffb9962fb4b2 (patch) | |
tree | 236016d773133c19e57c14fc69144e46a586549d /Lib | |
parent | e79ec70801e410de9c3110ffe78f98e08114ae16 (diff) | |
download | cpython-683333955a05a31da5f0b2ca1b3bffb9962fb4b2.zip cpython-683333955a05a31da5f0b2ca1b3bffb9962fb4b2.tar.gz cpython-683333955a05a31da5f0b2ca1b3bffb9962fb4b2.tar.bz2 |
Issue 24237: Raise PendingDeprecationWarning per PEP 479
Raise PendingDeprecationWarning when generator raises StopIteration
and no __future__ import is used. Fix offenders in the stdlib
and tests.
See also issue 22906.
Thanks to Nick Coghlan and Berker Peksag for reviews.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/difflib.py | 10 | ||||
-rw-r--r-- | Lib/test/test_contextlib.py | 6 | ||||
-rw-r--r-- | Lib/test/test_generators.py | 62 | ||||
-rw-r--r-- | Lib/test/test_with.py | 6 |
4 files changed, 58 insertions, 26 deletions
diff --git a/Lib/difflib.py b/Lib/difflib.py index aa98436..22d9145 100644 --- a/Lib/difflib.py +++ b/Lib/difflib.py @@ -1582,7 +1582,10 @@ def _mdiff(fromlines, tolines, context=None, linejunk=None, while True: # Collecting lines of text until we have a from/to pair while (len(fromlines)==0 or len(tolines)==0): - from_line, to_line, found_diff = next(line_iterator) + try: + from_line, to_line, found_diff = next(line_iterator) + except StopIteration: + return if from_line is not None: fromlines.append((from_line,found_diff)) if to_line is not None: @@ -1609,7 +1612,10 @@ def _mdiff(fromlines, tolines, context=None, linejunk=None, index, contextLines = 0, [None]*(context) found_diff = False while(found_diff is False): - from_line, to_line, found_diff = next(line_pair_iterator) + try: + from_line, to_line, found_diff = next(line_pair_iterator) + except StopIteration: + return i = index % context contextLines[i] = (from_line, to_line, found_diff) index += 1 diff --git a/Lib/test/test_contextlib.py b/Lib/test/test_contextlib.py index a5d68a9..adafc9f 100644 --- a/Lib/test/test_contextlib.py +++ b/Lib/test/test_contextlib.py @@ -89,8 +89,10 @@ class ContextManagerTestCase(unittest.TestCase): def woohoo(): yield try: - with woohoo(): - raise stop_exc + with self.assertWarnsRegex(PendingDeprecationWarning, + "StopIteration"): + with woohoo(): + raise stop_exc except Exception as ex: self.assertIs(ex, stop_exc) else: diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py index 85e09a1..fe4b138 100644 --- a/Lib/test/test_generators.py +++ b/Lib/test/test_generators.py @@ -1,6 +1,7 @@ import gc import sys import unittest +import warnings import weakref from test import support @@ -217,6 +218,46 @@ class ExceptionTest(unittest.TestCase): self.assertEqual(next(g), "done") self.assertEqual(sys.exc_info(), (None, None, None)) + def test_stopiteration_warning(self): + # See also PEP 479. + + def gen(): + raise StopIteration + yield + + with self.assertRaises(StopIteration), \ + self.assertWarnsRegex(PendingDeprecationWarning, "StopIteration"): + + next(gen()) + + with self.assertRaisesRegex(PendingDeprecationWarning, + "generator .* raised StopIteration"), \ + warnings.catch_warnings(): + + warnings.simplefilter('error') + next(gen()) + + + def test_tutorial_stopiteration(self): + # Raise StopIteration" stops the generator too: + + def f(): + yield 1 + raise StopIteration + yield 2 # never reached + + g = f() + self.assertEqual(next(g), 1) + + with self.assertWarnsRegex(PendingDeprecationWarning, "StopIteration"): + with self.assertRaises(StopIteration): + next(g) + + with self.assertRaises(StopIteration): + # This time StopIteration isn't raised from the generator's body, + # hence no warning. + next(g) + tutorial_tests = """ Let's try a simple generator: @@ -263,26 +304,7 @@ Let's try a simple generator: File "<stdin>", line 1, in ? StopIteration -"raise StopIteration" stops the generator too: - - >>> def f(): - ... yield 1 - ... raise StopIteration - ... yield 2 # never reached - ... - >>> g = f() - >>> next(g) - 1 - >>> next(g) - Traceback (most recent call last): - File "<stdin>", line 1, in ? - StopIteration - >>> next(g) - Traceback (most recent call last): - File "<stdin>", line 1, in ? - StopIteration - -However, they are not exactly equivalent: +However, "return" and StopIteration are not exactly equivalent: >>> def g1(): ... try: diff --git a/Lib/test/test_with.py b/Lib/test/test_with.py index fcd28f6..5dbd1e6 100644 --- a/Lib/test/test_with.py +++ b/Lib/test/test_with.py @@ -454,7 +454,8 @@ class ExceptionalTestCase(ContextmanagerAssertionMixin, unittest.TestCase): with cm(): raise StopIteration("from with") - self.assertRaises(StopIteration, shouldThrow) + with self.assertWarnsRegex(PendingDeprecationWarning, "StopIteration"): + self.assertRaises(StopIteration, shouldThrow) def testRaisedStopIteration2(self): # From bug 1462485 @@ -481,7 +482,8 @@ class ExceptionalTestCase(ContextmanagerAssertionMixin, unittest.TestCase): with cm(): raise next(iter([])) - self.assertRaises(StopIteration, shouldThrow) + with self.assertWarnsRegex(PendingDeprecationWarning, "StopIteration"): + self.assertRaises(StopIteration, shouldThrow) def testRaisedGeneratorExit1(self): # From bug 1462485 |