]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Small improvements to the itertools docs (GH-123885)
authorRaymond Hettinger <rhettinger@users.noreply.github.com>
Tue, 10 Sep 2024 01:57:49 +0000 (20:57 -0500)
committerGitHub <noreply@github.com>
Tue, 10 Sep 2024 01:57:49 +0000 (20:57 -0500)
Doc/library/itertools.rst
Lib/test/test_itertools.py

index 553abf788b223ae4b05970007e57a3e5f8b9ded9..508c20f4df6f5e3fbe28416d76685628aced44dd 100644 (file)
@@ -474,7 +474,7 @@ loops that truncate the stream.
    If *start* is zero or ``None``, iteration starts at zero.  Otherwise,
    elements from the iterable are skipped until *start* is reached.
 
-   If *stop* is ``None``, iteration continues until the iterator is
+   If *stop* is ``None``, iteration continues until the iterable is
    exhausted, if at all.  Otherwise, it stops at the specified position.
 
    If *step* is ``None``, the step defaults to one.  Elements are returned
@@ -503,6 +503,10 @@ loops that truncate the stream.
                   yield element
                   next_i += step
 
+   If the input is an iterator, then fully consuming the *islice*
+   advances the input iterator by ``max(start, stop)`` steps regardless
+   of the *step* value.
+
 
 .. function:: pairwise(iterable)
 
@@ -601,6 +605,8 @@ loops that truncate the stream.
            # product('ABCD', 'xy') → Ax Ay Bx By Cx Cy Dx Dy
            # product(range(2), repeat=3) → 000 001 010 011 100 101 110 111
 
+           if repeat < 0:
+               raise ValueError('repeat argument cannot be negative')
            pools = [tuple(pool) for pool in iterables] * repeat
 
            result = [[]]
@@ -684,6 +690,8 @@ loops that truncate the stream.
    Roughly equivalent to::
 
         def tee(iterable, n=2):
+            if n < 0:
+                raise ValueError('n must be >= 0')
             iterator = iter(iterable)
             shared_link = [None, None]
             return tuple(_tee(iterator, shared_link) for _ in range(n))
@@ -703,6 +711,12 @@ loops that truncate the stream.
    used anywhere else; otherwise, the *iterable* could get advanced without
    the tee objects being informed.
 
+   When the input *iterable* is already a tee iterator object, all
+   members of the return tuple are constructed as if they had been
+   produced by the upstream :func:`tee` call.  This "flattening step"
+   allows nested :func:`tee` calls to share the same underlying data
+   chain and to have a single update step rather than a chain of calls.
+
    ``tee`` iterators are not threadsafe. A :exc:`RuntimeError` may be
    raised when simultaneously using iterators returned by the same :func:`tee`
    call, even if the original *iterable* is threadsafe.
index 9c0c4b4de18cf10454fb60b0415bb977c3cf4489..6820dce3f1262007effc6d272640f0dcd003b733 100644 (file)
@@ -992,12 +992,16 @@ class TestBasicOps(unittest.TestCase):
                 else:
                     return
 
-        def product2(*args, **kwds):
+        def product2(*iterables, repeat=1):
             'Pure python version used in docs'
-            pools = list(map(tuple, args)) * kwds.get('repeat', 1)
+            if repeat < 0:
+                raise ValueError('repeat argument cannot be negative')
+            pools = [tuple(pool) for pool in iterables] * repeat
+
             result = [[]]
             for pool in pools:
                 result = [x+[y] for x in result for y in pool]
+
             for prod in result:
                 yield tuple(prod)
 
@@ -1754,6 +1758,8 @@ class TestPurePythonRoughEquivalents(unittest.TestCase):
         # Begin tee() recipe ###########################################
 
         def tee(iterable, n=2):
+            if n < 0:
+                raise ValueError('n must be >= 0')
             iterator = iter(iterable)
             shared_link = [None, None]
             return tuple(_tee(iterator, shared_link) for _ in range(n))
@@ -1829,11 +1835,9 @@ class TestPurePythonRoughEquivalents(unittest.TestCase):
         self.assertEqual(list(a), list(range(100,2000)))
         self.assertEqual(list(c), list(range(2,2000)))
 
-        # Tests not applicable to the tee() recipe
-        if False:
-            # test invalid values of n
-            self.assertRaises(TypeError, tee, 'abc', 'invalid')
-            self.assertRaises(ValueError, tee, [], -1)
+        # test invalid values of n
+        self.assertRaises(TypeError, tee, 'abc', 'invalid')
+        self.assertRaises(ValueError, tee, [], -1)
 
         for n in range(5):
             result = tee('abc', n)