Hello community,

here is the log from the commit of package python-more-itertools for 
openSUSE:Factory checked in at 2020-06-05 19:59:36
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-more-itertools (Old)
 and      /work/SRC/openSUSE:Factory/.python-more-itertools.new.3606 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-more-itertools"

Fri Jun  5 19:59:36 2020 rev:10 rq:810900 version:8.3.0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-more-itertools/python-more-itertools.changes  
    2020-03-08 22:21:40.179986101 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-more-itertools.new.3606/python-more-itertools.changes
    2020-06-05 19:59:38.319819232 +0200
@@ -1,0 +2,14 @@
+Tue Jun  2 16:30:25 UTC 2020 - Dirk Mueller <[email protected]>
+
+- update to 8.3.0:
+  * New itertools
+    * :func:`zip_equal` (thanks to frankier and alexmojaki)
+    * :func:`split_at`, :func:`split_before`, :func:`split_after`, and 
:func:`split_when` all got a ``maxsplit`` paramter (thanks to jferard and 
ilai-deutel)
+    * :func:`split_at` now accepts a ``keep_separator`` parameter (thanks to 
jferard)
+    * :func:`distinct_permutations` can now generate ``r``-length permutations 
(thanks to SergBobrovsky and ilai-deutel)
+    * The :func:`windowed` implementation was improved  (thanks to 
SergBobrovsky)
+    * The :func:`spy` implementation was improved (thanks to has2k1)
+    * Type stubs are now tested with ``stubtest`` (thankjs to ilai-deutel)
+    * Tests now run with ``python -m unittest`` instead of ``python setup.py 
test`` (thanks to jdufresne)
+
+-------------------------------------------------------------------

Old:
----
  more-itertools-8.2.0.tar.gz

New:
----
  more-itertools-8.3.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-more-itertools.spec ++++++
--- /var/tmp/diff_new_pack.6XiiOg/_old  2020-06-05 19:59:38.891821211 +0200
+++ /var/tmp/diff_new_pack.6XiiOg/_new  2020-06-05 19:59:38.891821211 +0200
@@ -19,7 +19,7 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %define skip_python2 1
 Name:           python-more-itertools
-Version:        8.2.0
+Version:        8.3.0
 Release:        0
 Summary:        More routines for operating on iterables, beyond itertools
 License:        MIT

++++++ more-itertools-8.2.0.tar.gz -> more-itertools-8.3.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/more-itertools-8.2.0/PKG-INFO 
new/more-itertools-8.3.0/PKG-INFO
--- old/more-itertools-8.2.0/PKG-INFO   2020-01-29 13:52:26.000000000 +0100
+++ new/more-itertools-8.3.0/PKG-INFO   2020-05-16 03:25:21.078277000 +0200
@@ -1,8 +1,8 @@
 Metadata-Version: 1.2
 Name: more-itertools
-Version: 8.2.0
+Version: 8.3.0
 Summary: More routines for operating on iterables, beyond itertools
-Home-page: https://github.com/erikrose/more-itertools
+Home-page: https://github.com/more-itertools/more-itertools
 Author: Erik Rose
 Author-email: [email protected]
 License: MIT
@@ -10,16 +10,17 @@
         More Itertools
         ==============
         
-        .. image:: 
https://coveralls.io/repos/github/erikrose/more-itertools/badge.svg?branch=master
-          :target: 
https://coveralls.io/github/erikrose/more-itertools?branch=master
+        .. image:: 
https://readthedocs.org/projects/more-itertools/badge/?version=latest
+          :target: https://more-itertools.readthedocs.io/en/stable/
+        
+        .. image:: 
https://coveralls.io/repos/github/more-itertools/more-itertools/badge.svg?branch=master
+          :target: 
https://coveralls.io/github/more-itertools/more-itertools?branch=master
         
         Python's ``itertools`` library is a gem - you can compose elegant 
solutions
         for a variety of problems with the functions it provides. In 
``more-itertools``
         we collect additional building blocks, recipes, and routines for 
working with
         Python iterables.
         
-        ----
-        
         
+------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
         | Grouping               | `chunked 
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.chunked>`_,
                                                                                
                                        |
         |                        | `ichunked 
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.ichunked>`_,
                                                                                
                                      |
@@ -60,6 +61,7 @@
         |                        | `interleave 
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.interleave>`_,
                                                                                
                                  |
         |                        | `interleave_longest 
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.interleave_longest>`_,
                                                                                
                  |
         |                        | `zip_offset 
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.zip_offset>`_,
                                                                                
                                  |
+        |                        | `zip_equal 
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.zip_equal>`_,
                                                                                
                                    |
         |                        | `dotproduct 
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.dotproduct>`_,
                                                                                
                                  |
         |                        | `flatten 
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.flatten>`_,
                                                                                
                                        |
         |                        | `roundrobin 
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.roundrobin>`_,
                                                                                
                                  |
@@ -165,13 +167,23 @@
         
         
         
-        For the full listing of functions, see the `API documentation 
<https://more-itertools.readthedocs.io/en/latest/api.html>`_.
+        For the full listing of functions, see the `API documentation 
<https://more-itertools.readthedocs.io/en/stable/api.html>`_.
+        
+        
+        Links elsewhere
+        ===============
+        
+        Blog posts about ``more-itertools``:
+        
+        * `Yo, I heard you like decorators 
<https://bbayles.com/index/decorator_factory>`_
+        * `Tour of Python Itertools <https://martinheinz.dev/blog/16>`_
+        
         
         Development
         ===========
         
         ``more-itertools`` is maintained by `@erikrose 
<https://github.com/erikrose>`_
-        and `@bbayles <https://github.com/bbayles>`_, with help from `many 
others <https://github.com/erikrose/more-itertools/graphs/contributors>`_.
+        and `@bbayles <https://github.com/bbayles>`_, with help from `many 
others <https://github.com/more-itertools/more-itertools/graphs/contributors>`_.
         If you have a problem or suggestion, please file a bug or pull request 
in this
         repository. Thanks for contributing!
         
@@ -182,6 +194,23 @@
         
            :noindex:
         
+        8.3.0
+        -----
+        
+        * New itertools
+            * zip_equal (thanks to frankier and alexmojaki)
+        
+        * Changes to existing itertools:
+            * split_at, split_before, split_after, and split_when all got a 
``maxsplit`` paramter (thanks to jferard and ilai-deutel)
+            * split_at now accepts a ``keep_separator`` parameter (thanks to 
jferard)
+            * distinct_permutations can now generate ``r``-length permutations 
(thanks to SergBobrovsky and ilai-deutel)
+            * The windowed implementation was improved  (thanks to 
SergBobrovsky)
+            * The spy implementation was improved (thanks to has2k1)
+        
+        * Other changes
+            * Type stubs are now tested with ``stubtest`` (thankjs to 
ilai-deutel)
+            * Tests now run with ``python -m unittest`` instead of ``python 
setup.py test`` (thanks to jdufresne)
+        
         8.2.0
         -----
         
@@ -235,7 +264,6 @@
             * unique_everseen and groupby_transform were re-factored. (thanks 
to SergBobrovsky)
             * The implementation for difference was improved. (thanks to 
Jabbey92)
         
-        
         * Other changes
             * Python 3.4 has reached its end of life and is no longer 
supported.
             * Python 3.8 is officially supported. (thanks to jdufresne)
@@ -382,7 +410,7 @@
         * New itertools:
             * split_at (thanks to michael-celani)
             * circular_shifts (thanks to hiqua)
-            * make_decorator - see the blog post `Yo, I heard you like 
decorators <https://sites.google.com/site/bbayles/index/decorator_factory>`_
+            * make_decorator - see the blog post `Yo, I heard you like 
decorators <https://sites.google.com/site/bbayles/index/decorator_factory>`__
               for a tour (thanks to pylang)
             * always_reversible (thanks to michael-celani)
             * nth_combination (from the `Python 3.7 docs 
<https://docs.python.org/3.7/library/itertools.html#itertools-recipes>`_)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/more-itertools-8.2.0/README.rst 
new/more-itertools-8.3.0/README.rst
--- old/more-itertools-8.2.0/README.rst 2020-01-11 19:59:09.000000000 +0100
+++ new/more-itertools-8.3.0/README.rst 2020-05-08 04:42:06.000000000 +0200
@@ -2,16 +2,17 @@
 More Itertools
 ==============
 
-.. image:: 
https://coveralls.io/repos/github/erikrose/more-itertools/badge.svg?branch=master
-  :target: https://coveralls.io/github/erikrose/more-itertools?branch=master
+.. image:: 
https://readthedocs.org/projects/more-itertools/badge/?version=latest
+  :target: https://more-itertools.readthedocs.io/en/stable/
+
+.. image:: 
https://coveralls.io/repos/github/more-itertools/more-itertools/badge.svg?branch=master
+  :target: 
https://coveralls.io/github/more-itertools/more-itertools?branch=master
 
 Python's ``itertools`` library is a gem - you can compose elegant solutions
 for a variety of problems with the functions it provides. In ``more-itertools``
 we collect additional building blocks, recipes, and routines for working with
 Python iterables.
 
-----
-
 
+------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
 | Grouping               | `chunked 
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.chunked>`_,
                                                                                
                                        |
 |                        | `ichunked 
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.ichunked>`_,
                                                                                
                                      |
@@ -52,6 +53,7 @@
 |                        | `interleave 
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.interleave>`_,
                                                                                
                                  |
 |                        | `interleave_longest 
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.interleave_longest>`_,
                                                                                
                  |
 |                        | `zip_offset 
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.zip_offset>`_,
                                                                                
                                  |
+|                        | `zip_equal 
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.zip_equal>`_,
                                                                                
                                    |
 |                        | `dotproduct 
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.dotproduct>`_,
                                                                                
                                  |
 |                        | `flatten 
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.flatten>`_,
                                                                                
                                        |
 |                        | `roundrobin 
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.roundrobin>`_,
                                                                                
                                  |
@@ -157,12 +159,22 @@
 
 
 
-For the full listing of functions, see the `API documentation 
<https://more-itertools.readthedocs.io/en/latest/api.html>`_.
+For the full listing of functions, see the `API documentation 
<https://more-itertools.readthedocs.io/en/stable/api.html>`_.
+
+
+Links elsewhere
+===============
+
+Blog posts about ``more-itertools``:
+
+* `Yo, I heard you like decorators 
<https://bbayles.com/index/decorator_factory>`_
+* `Tour of Python Itertools <https://martinheinz.dev/blog/16>`_
+
 
 Development
 ===========
 
 ``more-itertools`` is maintained by `@erikrose <https://github.com/erikrose>`_
-and `@bbayles <https://github.com/bbayles>`_, with help from `many others 
<https://github.com/erikrose/more-itertools/graphs/contributors>`_.
+and `@bbayles <https://github.com/bbayles>`_, with help from `many others 
<https://github.com/more-itertools/more-itertools/graphs/contributors>`_.
 If you have a problem or suggestion, please file a bug or pull request in this
 repository. Thanks for contributing!
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/more-itertools-8.2.0/docs/api.rst 
new/more-itertools-8.3.0/docs/api.rst
--- old/more-itertools-8.2.0/docs/api.rst       2020-01-11 19:59:09.000000000 
+0100
+++ new/more-itertools-8.3.0/docs/api.rst       2020-05-08 04:41:55.000000000 
+0200
@@ -108,6 +108,7 @@
 .. autofunction:: interleave
 .. autofunction:: interleave_longest
 .. autofunction:: zip_offset(*iterables, offsets, longest=False, 
fillvalue=None)
+.. autofunction:: zip_equal
 
 ----
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/more-itertools-8.2.0/docs/testing.rst 
new/more-itertools-8.3.0/docs/testing.rst
--- old/more-itertools-8.2.0/docs/testing.rst   2018-11-12 02:37:51.000000000 
+0100
+++ new/more-itertools-8.3.0/docs/testing.rst   2020-03-01 16:31:34.000000000 
+0100
@@ -4,7 +4,7 @@
 
 To run install dependencies and run tests, use this command::
 
-    python setup.py test
+    python -m unittest
 
 Multiple Python Versions
 ========================
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/more-itertools-8.2.0/docs/versions.rst 
new/more-itertools-8.3.0/docs/versions.rst
--- old/more-itertools-8.2.0/docs/versions.rst  2020-01-29 13:49:15.000000000 
+0100
+++ new/more-itertools-8.3.0/docs/versions.rst  2020-05-16 03:24:56.000000000 
+0200
@@ -5,6 +5,23 @@
 .. automodule:: more_itertools
    :noindex:
 
+8.3.0
+-----
+
+* New itertools
+    * :func:`zip_equal` (thanks to frankier and alexmojaki)
+
+* Changes to existing itertools:
+    * :func:`split_at`, :func:`split_before`, :func:`split_after`, and 
:func:`split_when` all got a ``maxsplit`` paramter (thanks to jferard and 
ilai-deutel)
+    * :func:`split_at` now accepts a ``keep_separator`` parameter (thanks to 
jferard)
+    * :func:`distinct_permutations` can now generate ``r``-length permutations 
(thanks to SergBobrovsky and ilai-deutel)
+    * The :func:`windowed` implementation was improved  (thanks to 
SergBobrovsky)
+    * The :func:`spy` implementation was improved (thanks to has2k1)
+
+* Other changes
+    * Type stubs are now tested with ``stubtest`` (thankjs to ilai-deutel)
+    * Tests now run with ``python -m unittest`` instead of ``python setup.py 
test`` (thanks to jdufresne)
+
 8.2.0
 -----
 
@@ -58,7 +75,6 @@
     * :func:`unique_everseen` and :func:`groupby_transform` were re-factored. 
(thanks to SergBobrovsky)
     * The implementation for :func:`difference` was improved. (thanks to 
Jabbey92)
 
-
 * Other changes
     * Python 3.4 has reached its end of life and is no longer supported.
     * Python 3.8 is officially supported. (thanks to jdufresne)
@@ -205,7 +221,7 @@
 * New itertools:
     * :func:`split_at` (thanks to michael-celani)
     * :func:`circular_shifts` (thanks to hiqua)
-    * :func:`make_decorator` - see the blog post `Yo, I heard you like 
decorators <https://sites.google.com/site/bbayles/index/decorator_factory>`_
+    * :func:`make_decorator` - see the blog post `Yo, I heard you like 
decorators <https://sites.google.com/site/bbayles/index/decorator_factory>`__
       for a tour (thanks to pylang)
     * :func:`always_reversible` (thanks to michael-celani)
     * :func:`nth_combination` (from the `Python 3.7 docs 
<https://docs.python.org/3.7/library/itertools.html#itertools-recipes>`_)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/more-itertools-8.2.0/more_itertools/__init__.py 
new/more-itertools-8.3.0/more_itertools/__init__.py
--- old/more-itertools-8.2.0/more_itertools/__init__.py 2020-01-29 
13:51:50.000000000 +0100
+++ new/more-itertools-8.3.0/more_itertools/__init__.py 2020-05-16 
03:19:57.000000000 +0200
@@ -1,4 +1,4 @@
 from .more import *  # noqa
 from .recipes import *  # noqa
 
-__version__ = '8.2.0'
+__version__ = '8.3.0'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/more-itertools-8.2.0/more_itertools/more.py 
new/more-itertools-8.3.0/more_itertools/more.py
--- old/more-itertools-8.2.0/more_itertools/more.py     2020-01-29 
13:49:15.000000000 +0100
+++ new/more-itertools-8.3.0/more_itertools/more.py     2020-05-16 
03:19:57.000000000 +0200
@@ -93,6 +93,8 @@
     'unzip',
     'windowed',
     'with_iter',
+    'UnequalIterablesError',
+    'zip_equal',
     'zip_offset',
 ]
 
@@ -545,7 +547,7 @@
     return first_value
 
 
-def distinct_permutations(iterable):
+def distinct_permutations(iterable, r=None):
     """Yield successive distinct permutations of the elements in *iterable*.
 
         >>> sorted(distinct_permutations([1, 0, 1]))
@@ -561,30 +563,86 @@
     items input, and each `x_i` is the count of a distinct item in the input
     sequence.
 
+    If *r* is given, only the *r*-length permutations are yielded.
+
+        >>> sorted(distinct_permutations([1, 0, 1], r=3))
+        [(0, 1, 1), (1, 0, 1), (1, 1, 0)]
+
     """
+    # Algorithm: https://w.wiki/Qai
+    def _full(A):
+        while True:
+            # Yield the permutation we have
+            yield tuple(A)
 
-    def make_new_permutations(pool, e):
-        """Internal helper function.
-        The output permutations are built up by adding element *e* to the
-        current *permutations* at every possible position.
-        The key idea is to keep repeated elements (reverse) ordered:
-        if e1 == e2 and e1 is before e2 in the iterable, then all permutations
-        with e1 before e2 are ignored.
+            # Find the largest index i such that A[i] < A[i + 1]
+            for i in range(size - 2, -1, -1):
+                if A[i] < A[i + 1]:
+                    break
+            #  If no such index exists, this permutation is the last one
+            else:
+                return
 
-        """
-        for perm in pool:
-            for j in range(len(perm)):
-                yield perm[:j] + (e,) + perm[j:]
-                if perm[j] == e:
+            # Find the largest index j greater than j such that A[i] < A[j]
+            for j in range(size - 1, i, -1):
+                if A[i] < A[j]:
+                    break
+
+            # Swap the value of A[i] with that of A[j], then reverse the
+            # sequence from A[i + 1] to form the new permutation
+            A[i], A[j] = A[j], A[i]
+            A[i + 1:] = A[:i - size:-1]  # A[i + 1:][::-1]
+
+    # Algorithm: modified from the above
+    def _partial(A, r):
+        # Split A into the first r items and the last r items
+        head, tail = A[:r], A[r:]
+        right_head_indexes = range(r - 1, -1, -1)
+        left_tail_indexes = range(len(tail))
+
+        while True:
+            # Yield the permutation we have
+            yield tuple(head)
+
+            # Starting from the right, find the first index of the head with
+            # value smaller than the maximum value of the tail - call it i.
+            pivot = tail[-1]
+            for i in right_head_indexes:
+                if head[i] < pivot:
+                    break
+                pivot = head[i]
+            else:
+                return
+
+            # Starting from the left, find the first value of the tail
+            # with a value greater than head[i] and swap.
+            for j in left_tail_indexes:
+                if tail[j] > head[i]:
+                    head[i], tail[j] = tail[j], head[i]
                     break
+            # If we didn't find one, start from the right and find the first
+            # index of the head with a value greater than head[i] and swap.
             else:
-                yield perm + (e,)
+                for j in right_head_indexes:
+                    if head[j] > head[i]:
+                        head[i], head[j] = head[j], head[i]
+                        break
+
+            # Reverse head[i + 1:] and swap it with tail[:r - (i + 1)]
+            tail += head[:i - r:-1]  # head[i + 1:][::-1]
+            i += 1
+            head[i:], tail[:] = tail[:r - i], tail[r - i:]
+
+    items = sorted(iterable)
+
+    size = len(items)
+    if r is None:
+        r = size
 
-    permutations = [()]
-    for e in iterable:
-        permutations = make_new_permutations(permutations, e)
+    if 0 < r <= size:
+        return _full(items) if (r == size) else _partial(items, r)
 
-    return (tuple(t) for t in permutations)
+    return iter(() if r else ((),))
 
 
 def intersperse(e, iterable, n=1):
@@ -654,7 +712,7 @@
         [(1, 2, 3), (2, 3, 4), (3, 4, 5)]
 
     When the window is larger than the iterable, *fillvalue* is used in place
-    of missing values::
+    of missing values:
 
         >>> list(windowed([1, 2, 3], 4))
         [(1, 2, 3, None)]
@@ -672,7 +730,6 @@
         >>> padding = [None] * (n - 1)
         >>> list(windowed(chain(padding, iterable), 3))
         [(None, None, 1), (None, 1, 2), (1, 2, 3), (2, 3, 4)]
-
     """
     if n < 0:
         raise ValueError('n must be >= 0')
@@ -682,28 +739,19 @@
     if step < 1:
         raise ValueError('step must be >= 1')
 
-    it = iter(seq)
-    window = deque([], n)
-    append = window.append
-
-    # Initial deque fill
-    for _ in range(n):
-        append(next(it, fillvalue))
-    yield tuple(window)
-
-    # Appending new items to the right causes old items to fall off the left
-    i = 0
-    for item in it:
-        append(item)
-        i = (i + 1) % step
-        if i % step == 0:
+    window = deque(maxlen=n)
+    i = n
+    for _ in map(window.append, seq):
+        i -= 1
+        if not i:
+            i = step
             yield tuple(window)
 
-    # If there are items from the iterable in the window, pad with the given
-    # value and emit them.
-    if (i % step) and (step - i < n):
-        for _ in range(step - i):
-            append(fillvalue)
+    size = len(window)
+    if size < n:
+        yield tuple(chain(window, repeat(fillvalue, n - size)))
+    elif 0 < i < min(step, n):
+        window += (fillvalue,) * i
         yield tuple(window)
 
 
@@ -903,7 +951,7 @@
     it = iter(iterable)
     head = take(n, it)
 
-    return head, chain(head, it)
+    return head.copy(), chain(head, it)
 
 
 def interleave(*iterables):
@@ -1064,28 +1112,51 @@
     return takewhile(len, (seq[i : i + n] for i in count(0, n)))
 
 
-def split_at(iterable, pred):
+def split_at(iterable, pred, maxsplit=-1, keep_separator=False):
     """Yield lists of items from *iterable*, where each list is delimited by
-    an item where callable *pred* returns ``True``. The lists do not include
-    the delimiting items.
+    an item where callable *pred* returns ``True``.
 
         >>> list(split_at('abcdcba', lambda x: x == 'b'))
         [['a'], ['c', 'd', 'c'], ['a']]
 
         >>> list(split_at(range(10), lambda n: n % 2 == 1))
         [[0], [2], [4], [6], [8], []]
+
+    At most *maxsplit* splits are done. If *maxsplit* is not specified or -1,
+    then there is no limit on the number of splits:
+
+        >>> list(split_at(range(10), lambda n: n % 2 == 1, maxsplit=2))
+        [[0], [2], [4, 5, 6, 7, 8, 9]]
+
+    By default, the delimiting items are not included in the output.
+    The include them, set *keep_separator* to ``True``.
+
+        >>> list(split_at('abcdcba', lambda x: x == 'b', keep_separator=True))
+        [['a'], ['b'], ['c', 'd', 'c'], ['b'], ['a']]
+
     """
+    if maxsplit == 0:
+        yield list(iterable)
+        return
+
     buf = []
-    for item in iterable:
+    it = iter(iterable)
+    for item in it:
         if pred(item):
             yield buf
+            if keep_separator:
+                yield [item]
+            if maxsplit == 1:
+                yield list(it)
+                return
             buf = []
+            maxsplit -= 1
         else:
             buf.append(item)
     yield buf
 
 
-def split_before(iterable, pred):
+def split_before(iterable, pred, maxsplit=-1):
     """Yield lists of items from *iterable*, where each list ends just before
     an item for which callable *pred* returns ``True``:
 
@@ -1095,17 +1166,31 @@
         >>> list(split_before(range(10), lambda n: n % 3 == 0))
         [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]
 
+    At most *maxsplit* splits are done. If *maxsplit* is not specified or -1,
+    then there is no limit on the number of splits:
+
+        >>> list(split_before(range(10), lambda n: n % 3 == 0, maxsplit=2))
+        [[0, 1, 2], [3, 4, 5], [6, 7, 8, 9]]
     """
+    if maxsplit == 0:
+        yield list(iterable)
+        return
+
     buf = []
-    for item in iterable:
+    it = iter(iterable)
+    for item in it:
         if pred(item) and buf:
             yield buf
+            if maxsplit == 1:
+                yield [item] + list(it)
+                return
             buf = []
+            maxsplit -= 1
         buf.append(item)
     yield buf
 
 
-def split_after(iterable, pred):
+def split_after(iterable, pred, maxsplit=-1):
     """Yield lists of items from *iterable*, where each list ends with an
     item where callable *pred* returns ``True``:
 
@@ -1115,18 +1200,33 @@
         >>> list(split_after(range(10), lambda n: n % 3 == 0))
         [[0], [1, 2, 3], [4, 5, 6], [7, 8, 9]]
 
+    At most *maxsplit* splits are done. If *maxsplit* is not specified or -1,
+    then there is no limit on the number of splits:
+
+        >>> list(split_after(range(10), lambda n: n % 3 == 0, maxsplit=2))
+        [[0], [1, 2, 3], [4, 5, 6, 7, 8, 9]]
+
     """
+    if maxsplit == 0:
+        yield list(iterable)
+        return
+
     buf = []
-    for item in iterable:
+    it = iter(iterable)
+    for item in it:
         buf.append(item)
         if pred(item) and buf:
             yield buf
+            if maxsplit == 1:
+                yield list(it)
+                return
             buf = []
+            maxsplit -= 1
     if buf:
         yield buf
 
 
-def split_when(iterable, pred):
+def split_when(iterable, pred, maxsplit=-1):
     """Split *iterable* into pieces based on the output of *pred*.
     *pred* should be a function that takes successive pairs of items and
     returns ``True`` if the iterable should be split in between them.
@@ -1136,7 +1236,19 @@
 
         >>> list(split_when([1, 2, 3, 3, 2, 5, 2, 4, 2], lambda x, y: x > y))
         [[1, 2, 3, 3], [2, 5], [2, 4], [2]]
+
+    At most *maxsplit* splits are done. If *maxsplit* is not specified or -1,
+    then there is no limit on the number of splits:
+
+        >>> list(split_when([1, 2, 3, 3, 2, 5, 2, 4, 2],
+        ...                 lambda x, y: x > y, maxsplit=2))
+        [[1, 2, 3, 3], [2, 5], [2, 4, 2]]
+
     """
+    if maxsplit == 0:
+        yield list(iterable)
+        return
+
     it = iter(iterable)
     try:
         cur_item = next(it)
@@ -1147,7 +1259,11 @@
     for next_item in it:
         if pred(cur_item, next_item):
             yield buf
+            if maxsplit == 1:
+                yield [next_item] + list(it)
+                return
             buf = []
+            maxsplit -= 1
 
         buf.append(next_item)
         cur_item = next_item
@@ -1314,6 +1430,62 @@
     )
 
 
+class UnequalIterablesError(ValueError):
+    def __init__(self, details=None):
+        msg = 'Iterables have different lengths'
+        if details is not None:
+            msg += (
+                ': index 0 has length {}; index {} has length {}'
+            ).format(*details)
+
+        super().__init__(msg)
+
+
+def zip_equal(*iterables):
+    """``zip`` the input *iterables* together, but raise
+    ``UnequalIterablesError`` if they aren't all the same length.
+
+        >>> it_1 = range(3)
+        >>> it_2 = iter('abc')
+        >>> list(zip_equal(it_1, it_2))
+        [(0, 'a'), (1, 'b'), (2, 'c')]
+
+        >>> it_1 = range(3)
+        >>> it_2 = iter('abcd')
+        >>> list(zip_equal(it_1, it_2)) # doctest: +IGNORE_EXCEPTION_DETAIL
+        Traceback (most recent call last):
+        ...
+        more_itertools.more.UnequalIterablesError: Iterables have different
+        lengths
+
+    """
+    # Check whether the iterables are all the same size.
+    try:
+        first_size = len(iterables[0])
+        for i, it in enumerate(iterables[1:], 1):
+            size = len(it)
+            if size != first_size:
+                break
+        else:
+            # If we didn't break out, we can use the built-in zip.
+            return zip(*iterables)
+
+        # If we did break out, there was a mismatch.
+        raise UnequalIterablesError(details=(first_size, i, size))
+    # If any one of the iterables didn't have a length, start reading
+    # them until one runs out.
+    except TypeError:
+        return _zip_equal_generator(iterables)
+
+
+def _zip_equal_generator(iterables):
+    for combo in zip_longest(*iterables, fillvalue=_marker):
+        for val in combo:
+            if val is _marker:
+                raise UnequalIterablesError()
+        yield combo
+
+
 def zip_offset(*iterables, offsets, longest=False, fillvalue=None):
     """``zip`` the input *iterables* together, but offset the `i`-th iterable
     by the `i`-th item in *offsets*.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/more-itertools-8.2.0/more_itertools.egg-info/PKG-INFO 
new/more-itertools-8.3.0/more_itertools.egg-info/PKG-INFO
--- old/more-itertools-8.2.0/more_itertools.egg-info/PKG-INFO   2020-01-29 
13:52:26.000000000 +0100
+++ new/more-itertools-8.3.0/more_itertools.egg-info/PKG-INFO   2020-05-16 
03:25:20.000000000 +0200
@@ -1,8 +1,8 @@
 Metadata-Version: 1.2
 Name: more-itertools
-Version: 8.2.0
+Version: 8.3.0
 Summary: More routines for operating on iterables, beyond itertools
-Home-page: https://github.com/erikrose/more-itertools
+Home-page: https://github.com/more-itertools/more-itertools
 Author: Erik Rose
 Author-email: [email protected]
 License: MIT
@@ -10,16 +10,17 @@
         More Itertools
         ==============
         
-        .. image:: 
https://coveralls.io/repos/github/erikrose/more-itertools/badge.svg?branch=master
-          :target: 
https://coveralls.io/github/erikrose/more-itertools?branch=master
+        .. image:: 
https://readthedocs.org/projects/more-itertools/badge/?version=latest
+          :target: https://more-itertools.readthedocs.io/en/stable/
+        
+        .. image:: 
https://coveralls.io/repos/github/more-itertools/more-itertools/badge.svg?branch=master
+          :target: 
https://coveralls.io/github/more-itertools/more-itertools?branch=master
         
         Python's ``itertools`` library is a gem - you can compose elegant 
solutions
         for a variety of problems with the functions it provides. In 
``more-itertools``
         we collect additional building blocks, recipes, and routines for 
working with
         Python iterables.
         
-        ----
-        
         
+------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
         | Grouping               | `chunked 
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.chunked>`_,
                                                                                
                                        |
         |                        | `ichunked 
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.ichunked>`_,
                                                                                
                                      |
@@ -60,6 +61,7 @@
         |                        | `interleave 
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.interleave>`_,
                                                                                
                                  |
         |                        | `interleave_longest 
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.interleave_longest>`_,
                                                                                
                  |
         |                        | `zip_offset 
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.zip_offset>`_,
                                                                                
                                  |
+        |                        | `zip_equal 
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.zip_equal>`_,
                                                                                
                                    |
         |                        | `dotproduct 
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.dotproduct>`_,
                                                                                
                                  |
         |                        | `flatten 
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.flatten>`_,
                                                                                
                                        |
         |                        | `roundrobin 
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.roundrobin>`_,
                                                                                
                                  |
@@ -165,13 +167,23 @@
         
         
         
-        For the full listing of functions, see the `API documentation 
<https://more-itertools.readthedocs.io/en/latest/api.html>`_.
+        For the full listing of functions, see the `API documentation 
<https://more-itertools.readthedocs.io/en/stable/api.html>`_.
+        
+        
+        Links elsewhere
+        ===============
+        
+        Blog posts about ``more-itertools``:
+        
+        * `Yo, I heard you like decorators 
<https://bbayles.com/index/decorator_factory>`_
+        * `Tour of Python Itertools <https://martinheinz.dev/blog/16>`_
+        
         
         Development
         ===========
         
         ``more-itertools`` is maintained by `@erikrose 
<https://github.com/erikrose>`_
-        and `@bbayles <https://github.com/bbayles>`_, with help from `many 
others <https://github.com/erikrose/more-itertools/graphs/contributors>`_.
+        and `@bbayles <https://github.com/bbayles>`_, with help from `many 
others <https://github.com/more-itertools/more-itertools/graphs/contributors>`_.
         If you have a problem or suggestion, please file a bug or pull request 
in this
         repository. Thanks for contributing!
         
@@ -182,6 +194,23 @@
         
            :noindex:
         
+        8.3.0
+        -----
+        
+        * New itertools
+            * zip_equal (thanks to frankier and alexmojaki)
+        
+        * Changes to existing itertools:
+            * split_at, split_before, split_after, and split_when all got a 
``maxsplit`` paramter (thanks to jferard and ilai-deutel)
+            * split_at now accepts a ``keep_separator`` parameter (thanks to 
jferard)
+            * distinct_permutations can now generate ``r``-length permutations 
(thanks to SergBobrovsky and ilai-deutel)
+            * The windowed implementation was improved  (thanks to 
SergBobrovsky)
+            * The spy implementation was improved (thanks to has2k1)
+        
+        * Other changes
+            * Type stubs are now tested with ``stubtest`` (thankjs to 
ilai-deutel)
+            * Tests now run with ``python -m unittest`` instead of ``python 
setup.py test`` (thanks to jdufresne)
+        
         8.2.0
         -----
         
@@ -235,7 +264,6 @@
             * unique_everseen and groupby_transform were re-factored. (thanks 
to SergBobrovsky)
             * The implementation for difference was improved. (thanks to 
Jabbey92)
         
-        
         * Other changes
             * Python 3.4 has reached its end of life and is no longer 
supported.
             * Python 3.8 is officially supported. (thanks to jdufresne)
@@ -382,7 +410,7 @@
         * New itertools:
             * split_at (thanks to michael-celani)
             * circular_shifts (thanks to hiqua)
-            * make_decorator - see the blog post `Yo, I heard you like 
decorators <https://sites.google.com/site/bbayles/index/decorator_factory>`_
+            * make_decorator - see the blog post `Yo, I heard you like 
decorators <https://sites.google.com/site/bbayles/index/decorator_factory>`__
               for a tour (thanks to pylang)
             * always_reversible (thanks to michael-celani)
             * nth_combination (from the `Python 3.7 docs 
<https://docs.python.org/3.7/library/itertools.html#itertools-recipes>`_)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/more-itertools-8.2.0/setup.cfg 
new/more-itertools-8.3.0/setup.cfg
--- old/more-itertools-8.2.0/setup.cfg  2020-01-29 13:52:26.000000000 +0100
+++ new/more-itertools-8.3.0/setup.cfg  2020-05-16 03:25:21.078277000 +0200
@@ -1,5 +1,5 @@
 [bumpversion]
-current_version = 8.2.0
+current_version = 8.3.0
 commit = True
 tag = False
 files = more_itertools/__init__.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/more-itertools-8.2.0/setup.py 
new/more-itertools-8.3.0/setup.py
--- old/more-itertools-8.2.0/setup.py   2020-01-11 19:59:09.000000000 +0100
+++ new/more-itertools-8.3.0/setup.py   2020-05-16 03:22:50.000000000 +0200
@@ -34,8 +34,7 @@
     package_data={'more_itertools': ['py.typed', '*.pyi']},
     include_package_data=True,
     python_requires='>=3.5',
-    test_suite='tests',
-    url='https://github.com/erikrose/more-itertools',
+    url='https://github.com/more-itertools/more-itertools',
     classifiers=[
         'Development Status :: 5 - Production/Stable',
         'Intended Audience :: Developers',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/more-itertools-8.2.0/tests/test_more.py 
new/more-itertools-8.3.0/tests/test_more.py
--- old/more-itertools-8.2.0/tests/test_more.py 2020-01-29 13:49:15.000000000 
+0100
+++ new/more-itertools-8.3.0/tests/test_more.py 2020-05-09 04:19:44.000000000 
+0200
@@ -526,6 +526,30 @@
         ref_output = sorted(set(permutations(iterable)))
         self.assertEqual(test_output, ref_output)
 
+    def test_r(self):
+        for iterable, r in (
+            ('mississippi', 0),
+            ('mississippi', 1),
+            ('mississippi', 6),
+            ('mississippi', 7),
+            ('mississippi', 12),
+            ([0, 1, 1, 0], 0),
+            ([0, 1, 1, 0], 1),
+            ([0, 1, 1, 0], 2),
+            ([0, 1, 1, 0], 3),
+            ([0, 1, 1, 0], 4),
+            (['a'], 0),
+            (['a'], 1),
+            (['a'], 5),
+            ([], 0),
+            ([], 1),
+            ([], 4),
+        ):
+            with self.subTest(iterable=iterable, r=r):
+                expected = sorted(set(permutations(iterable, r)))
+                actual = sorted(mi.distinct_permutations(iter(iterable), r))
+                self.assertEqual(actual, expected)
+
 
 class IlenTests(TestCase):
     def test_ilen(self):
@@ -909,6 +933,15 @@
         self.assertEqual(head, [])
         self.assertEqual(list(new_iterable), ['a', 'b', 'c'])
 
+    def test_immutable(self):
+        original_iterable = iter('abcdefg')
+        head, new_iterable = mi.spy(original_iterable, 3)
+        head[0] = 'A'
+        self.assertEqual(head, ['A', 'b', 'c'])
+        self.assertEqual(
+            list(new_iterable), ['a', 'b', 'c', 'd', 'e', 'f', 'g']
+        )
+
 
 class InterleaveTests(TestCase):
     def test_even(self):
@@ -1098,19 +1131,60 @@
 
 
 class SplitAtTests(TestCase):
-    """Tests for ``split()``"""
+    def test_basic(self):
+        for iterable, separator in [
+            ('a,bb,ccc,dddd', ','),
+            (',a,bb,ccc,dddd', ','),
+            ('a,bb,ccc,dddd,', ','),
+            ('a,bb,ccc,,dddd', ','),
+            ('', ','),
+            (',', ','),
+            ('a,bb,ccc,dddd', ';'),
+        ]:
+            with self.subTest(iterable=iterable, separator=separator):
+                it = iter(iterable)
+                pred = lambda x: x == separator
+                actual = [''.join(x) for x in mi.split_at(it, pred)]
+                expected = iterable.split(separator)
+                self.assertEqual(actual, expected)
+
+    def test_maxsplit(self):
+        iterable = 'a,bb,ccc,dddd'
+        separator = ','
+        pred = lambda x: x == separator
+
+        for maxsplit in range(-1, 4):
+            with self.subTest(maxsplit=maxsplit):
+                it = iter(iterable)
+                result = mi.split_at(it, pred, maxsplit=maxsplit)
+                actual = [''.join(x) for x in result]
+                expected = iterable.split(separator, maxsplit)
+                self.assertEqual(actual, expected)
+
+    def test_keep_separator(self):
+        separator = ','
+        pred = lambda x: x == separator
+
+        for iterable, expected in [
+            ('a,bb,ccc', ['a', ',', 'bb', ',', 'ccc']),
+            (',a,bb,ccc', ['', ',', 'a', ',', 'bb', ',', 'ccc']),
+            ('a,bb,ccc,', ['a', ',', 'bb', ',', 'ccc', ',', '']),
+        ]:
+            with self.subTest(iterable=iterable):
+                it = iter(iterable)
+                result = mi.split_at(it, pred, keep_separator=True)
+                actual = [''.join(x) for x in result]
+                self.assertEqual(actual, expected)
 
-    def comp_with_str_split(self, str_to_split, delim):
-        pred = lambda c: c == delim
-        actual = list(map(''.join, mi.split_at(str_to_split, pred)))
-        expected = str_to_split.split(delim)
+    def test_combination(self):
+        iterable = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+        pred = lambda x: x % 3 == 0
+        actual = list(
+            mi.split_at(iterable, pred, maxsplit=2, keep_separator=True)
+        )
+        expected = [[1, 2], [3], [4, 5], [6], [7, 8, 9, 10]]
         self.assertEqual(actual, expected)
 
-    def test_seperators(self):
-        test_strs = ['', 'abcba', 'aaabbbcccddd', 'e']
-        for s, delim in product(test_strs, 'abcd'):
-            self.comp_with_str_split(s, delim)
-
 
 class SplitBeforeTest(TestCase):
     """Tests for ``split_before()``"""
@@ -1130,6 +1204,26 @@
         expected = [['o', 'o', 'o']]
         self.assertEqual(actual, expected)
 
+    def test_max_split(self):
+        for args, expected in [
+            (('a,b,c,d', lambda c: c == ',', -1),
+             [['a'], [',', 'b'], [',', 'c'], [',', 'd']]),
+            (('a,b,c,d', lambda c: c == ',', 0),
+             [['a', ',', 'b', ',', 'c', ',', 'd']]),
+            (('a,b,c,d', lambda c: c == ',', 1),
+             [['a'], [',', 'b', ',', 'c', ',', 'd']]),
+            (('a,b,c,d', lambda c: c == ',', 2),
+             [['a'], [',', 'b'], [',', 'c', ',', 'd']]),
+            (('a,b,c,d', lambda c: c == ',', 10),
+             [['a'], [',', 'b'], [',', 'c'], [',', 'd']]),
+            (('a,b,c,d', lambda c: c == '@', 2),
+             [['a', ',', 'b', ',', 'c', ',', 'd']]),
+            (('a,b,c,d', lambda c: c != ',', 2),
+             [['a', ','], ['b', ','], ['c', ',', 'd']]),
+        ]:
+            actual = list(mi.split_before(*args))
+            self.assertEqual(actual, expected)
+
 
 class SplitAfterTest(TestCase):
     """Tests for ``split_after()``"""
@@ -1149,6 +1243,26 @@
         expected = [['o', 'o', 'o']]
         self.assertEqual(actual, expected)
 
+    def test_max_split(self):
+        for args, expected in [
+            (('a,b,c,d', lambda c: c == ',', -1),
+             [['a', ','], ['b', ','], ['c', ','], ['d']]),
+            (('a,b,c,d', lambda c: c == ',', 0),
+             [['a', ',', 'b', ',', 'c', ',', 'd']]),
+            (('a,b,c,d', lambda c: c == ',', 1),
+             [['a', ','], ['b', ',', 'c', ',', 'd']]),
+            (('a,b,c,d', lambda c: c == ',', 2),
+             [['a', ','], ['b', ','], ['c', ',', 'd']]),
+            (('a,b,c,d', lambda c: c == ',', 10),
+             [['a', ','], ['b', ','], ['c', ','], ['d']]),
+            (('a,b,c,d', lambda c: c == '@', 2),
+             [['a', ',', 'b', ',', 'c', ',', 'd']]),
+            (('a,b,c,d', lambda c: c != ',', 2),
+             [['a'], [',', 'b'], [',', 'c', ',', 'd']]),
+        ]:
+            actual = list(mi.split_after(*args))
+            self.assertEqual(actual, expected)
+
 
 class SplitWhenTests(TestCase):
     """Tests for ``split_when()``"""
@@ -1214,6 +1328,28 @@
         expected = [['x']]
         self.assertEqual(actual, expected)
 
+    def test_max_split(self):
+        for args, expected in [
+            (('a,b,c,d', lambda a, _: a == ',', -1),
+             [['a', ','], ['b', ','], ['c', ','], ['d']]),
+            (('a,b,c,d', lambda a, _: a == ',', 0),
+             [['a', ',', 'b', ',', 'c', ',', 'd']]),
+            (('a,b,c,d', lambda _, b: b == ',', 1),
+             [['a'], [',', 'b', ',', 'c', ',', 'd']]),
+            (('a,b,c,d', lambda a, _: a == ',', 2),
+             [['a', ','], ['b', ','], ['c', ',', 'd']]),
+            (('0124376', lambda a, b: a > b, -1),
+             [['0', '1', '2', '4'], ['3', '7'], ['6']]),
+            (('0124376', lambda a, b: a > b, 0),
+             [['0', '1', '2', '4', '3', '7', '6']]),
+            (('0124376', lambda a, b: a > b, 1),
+             [['0', '1', '2', '4'], ['3', '7', '6']]),
+            (('0124376', lambda a, b: a > b, 2),
+             [['0', '1', '2', '4'], ['3', '7'], ['6']]),
+        ]:
+            actual = list(mi.split_when(*args))
+            self.assertEqual(actual, expected, str(args))
+
 
 class SplitIntoTests(TestCase):
     """Tests for ``split_into()``"""
@@ -1528,6 +1664,55 @@
             self.assertEqual(list(all_groups), expected)
 
 
+class ZipEqualTest(TestCase):
+    """Tests for ``zip_equal()``"""
+
+    def test_equal(self):
+        lists = [0, 1, 2], [2, 3, 4]
+
+        for iterables in [lists, map(iter, lists)]:
+            actual = list(mi.zip_equal(*iterables))
+            expected = [(0, 2), (1, 3), (2, 4)]
+            self.assertEqual(actual, expected)
+
+    def test_unequal_lists(self):
+        two_items = [0, 1]
+        three_items = [2, 3, 4]
+        four_items = [5, 6, 7, 8]
+
+        # the mismatch is at index 1
+        try:
+            list(mi.zip_equal(two_items, three_items, four_items))
+        except mi.UnequalIterablesError as e:
+            self.assertEqual(
+                e.args[0],
+                (
+                    'Iterables have different lengths: '
+                    'index 0 has length 2; index 1 has length 3'
+                )
+            )
+
+        # the mismatch is at index 2
+        try:
+            list(mi.zip_equal(two_items, two_items, four_items, four_items))
+        except mi.UnequalIterablesError as e:
+            self.assertEqual(
+                e.args[0],
+                (
+                    'Iterables have different lengths: '
+                    'index 0 has length 2; index 2 has length 4'
+                )
+            )
+
+        # One without length: delegate to _zip_equal_generator
+        try:
+            list(mi.zip_equal(two_items, iter(two_items), three_items))
+        except mi.UnequalIterablesError as e:
+            self.assertEqual(
+                e.args[0], 'Iterables have different lengths'
+            )
+
+
 class ZipOffsetTest(TestCase):
     """Tests for ``zip_offset()``"""
 


Reply via email to