summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorYury Selivanov <yselivanov@sprymix.com>2015-05-22 15:16:47 (GMT)
committerYury Selivanov <yselivanov@sprymix.com>2015-05-22 15:16:47 (GMT)
commit683333955a05a31da5f0b2ca1b3bffb9962fb4b2 (patch)
tree236016d773133c19e57c14fc69144e46a586549d /Lib
parente79ec70801e410de9c3110ffe78f98e08114ae16 (diff)
downloadcpython-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.py10
-rw-r--r--Lib/test/test_contextlib.py6
-rw-r--r--Lib/test/test_generators.py62
-rw-r--r--Lib/test/test_with.py6
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