Hello community,

here is the log from the commit of package python-more-itertools for 
openSUSE:Factory checked in at 2018-06-04 13:21:20
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-more-itertools (Old)
 and      /work/SRC/openSUSE:Factory/.python-more-itertools.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-more-itertools"

Mon Jun  4 13:21:20 2018 rev:4 rq:613148 version:4.2.0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-more-itertools/python-more-itertools.changes  
    2018-03-30 12:08:46.466801674 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-more-itertools.new/python-more-itertools.changes
 2018-06-04 13:21:21.359199917 +0200
@@ -1,0 +2,15 @@
+Thu May 31 04:34:12 UTC 2018 - [email protected]
+
+- Update to version 4.2.0
+  + New itertools:
+    * map_reduce (thanks to pylang)
+    * prepend (from the `Python 3.7 docs 
<https://docs.python.org/3.7/library/itertools.html#itertools-recipes>`_)
+  + Improvements to existing itertools:
+    * :func:`bucket` now complies with PEP 479 (thanks to irmen)
+  + Other changes:
+    * Python 3.7 is now supported (thanks to irmen)
+    * Python 3.3 is no longer supported
+    * The test suite no longer requires third-party modules to run
+    * The API docs now include links to source code
+
+-------------------------------------------------------------------

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

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

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

Other differences:
------------------
++++++ python-more-itertools.spec ++++++
--- /var/tmp/diff_new_pack.qK73pe/_old  2018-06-04 13:21:22.043174874 +0200
+++ /var/tmp/diff_new_pack.qK73pe/_new  2018-06-04 13:21:22.047174726 +0200
@@ -18,7 +18,7 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-more-itertools
-Version:        4.1.0
+Version:        4.2.0
 Release:        0
 Summary:        More routines for operating on iterables, beyond itertools
 License:        MIT

++++++ more-itertools-4.1.0.tar.gz -> more-itertools-4.2.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/more-itertools-4.1.0/PKG-INFO 
new/more-itertools-4.2.0/PKG-INFO
--- old/more-itertools-4.1.0/PKG-INFO   2018-01-21 16:32:20.000000000 +0100
+++ new/more-itertools-4.2.0/PKG-INFO   2018-05-24 03:40:36.000000000 +0200
@@ -1,12 +1,11 @@
 Metadata-Version: 1.1
 Name: more-itertools
-Version: 4.1.0
+Version: 4.2.0
 Summary: More routines for operating on iterables, beyond itertools
 Home-page: https://github.com/erikrose/more-itertools
 Author: Erik Rose
 Author-email: [email protected]
 License: MIT
-Description-Content-Type: UNKNOWN
 Description: ==============
         More Itertools
         ==============
@@ -73,6 +72,22 @@
         
         
         
+        4.2.0
+        -----
+        
+        * New itertools:
+            * map_reduce (thanks to pylang)
+            * prepend (from the `Python 3.7 docs 
<https://docs.python.org/3.7/library/itertools.html#itertools-recipes>`_)
+        
+        * Improvements to existing itertools:
+            * bucket now complies with PEP 479 (thanks to irmen)
+        
+        * Other changes:
+           * Python 3.7 is now supported (thanks to irmen)
+           * Python 3.3 is no longer supported
+           * The test suite no longer requires third-party modules to run
+           * The API docs now include links to source code
+        
         4.1.0
         -----
         
@@ -301,4 +316,6 @@
 Classifier: Programming Language :: Python :: 3.3
 Classifier: Programming Language :: Python :: 3.4
 Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
 Classifier: Topic :: Software Development :: Libraries
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/more-itertools-4.1.0/docs/api.rst 
new/more-itertools-4.2.0/docs/api.rst
--- old/more-itertools-4.1.0/docs/api.rst       2018-01-20 03:58:09.000000000 
+0100
+++ new/more-itertools-4.2.0/docs/api.rst       2018-05-24 03:40:14.000000000 
+0200
@@ -110,6 +110,7 @@
 .. autofunction:: dotproduct
 .. autofunction:: flatten
 .. autofunction:: roundrobin
+.. autofunction:: prepend
 
 
 Summarizing
@@ -129,6 +130,7 @@
 .. autofunction:: consecutive_groups(iterable, ordering=lambda x: x)
 .. autofunction:: exactly_n(iterable, n, predicate=bool)
 .. autoclass:: run_length
+.. autofunction:: map_reduce
 
 ----
 
@@ -143,7 +145,7 @@
 Selecting
 =========
 
-These yools yield certain items from an iterable.
+These tools yield certain items from an iterable.
 
 ----
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/more-itertools-4.1.0/docs/conf.py 
new/more-itertools-4.2.0/docs/conf.py
--- old/more-itertools-4.1.0/docs/conf.py       2018-01-19 03:35:47.000000000 
+0100
+++ new/more-itertools-4.2.0/docs/conf.py       2018-05-24 03:40:14.000000000 
+0200
@@ -18,7 +18,7 @@
 # If extensions (or modules to document with autodoc) are in another directory,
 # add these directories to sys.path here. If the directory is relative to the
 # documentation root, use os.path.abspath to make it absolute, like shown here.
-#sys.path.insert(0, os.path.abspath('.'))
+sys.path.insert(0, os.path.abspath('..'))
 
 # -- General configuration 
-----------------------------------------------------
 
@@ -50,7 +50,7 @@
 # built documents.
 #
 # The short X.Y version.
-version = '4.1.0'
+version = '4.2.0'
 # The full version, including alpha/beta/rc tags.
 release = version
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/more-itertools-4.1.0/docs/versions.rst 
new/more-itertools-4.2.0/docs/versions.rst
--- old/more-itertools-4.1.0/docs/versions.rst  2018-01-21 16:26:26.000000000 
+0100
+++ new/more-itertools-4.2.0/docs/versions.rst  2018-05-24 03:40:14.000000000 
+0200
@@ -4,6 +4,22 @@
 
 .. automodule:: more_itertools
 
+4.2.0
+-----
+
+* New itertools:
+    * :func:`map_reduce` (thanks to pylang)
+    * :func:`prepend` (from the `Python 3.7 docs 
<https://docs.python.org/3.7/library/itertools.html#itertools-recipes>`_)
+
+* Improvements to existing itertools:
+    * :func:`bucket` now complies with PEP 479 (thanks to irmen)
+
+* Other changes:
+   * Python 3.7 is now supported (thanks to irmen)
+   * Python 3.3 is no longer supported
+   * The test suite no longer requires third-party modules to run
+   * The API docs now include links to source code
+
 4.1.0
 -----
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/more-itertools-4.1.0/more_itertools/more.py 
new/more-itertools-4.2.0/more_itertools/more.py
--- old/more-itertools-4.1.0/more_itertools/more.py     2018-01-20 
03:57:27.000000000 +0100
+++ new/more-itertools-4.2.0/more_itertools/more.py     2018-05-15 
04:10:53.000000000 +0200
@@ -1,6 +1,6 @@
 from __future__ import print_function
 
-from collections import Counter, defaultdict, deque, Sequence
+from collections import Counter, defaultdict, deque
 from functools import partial, wraps
 from heapq import merge
 from itertools import (
@@ -17,6 +17,10 @@
 )
 from operator import itemgetter, lt, gt, sub
 from sys import maxsize, version_info
+try:
+    from collections.abc import Sequence
+except ImportError:
+    from collections import Sequence
 
 from six import binary_type, string_types, text_type
 from six.moves import filter, map, range, zip, zip_longest
@@ -51,6 +55,7 @@
     'locate',
     'lstrip',
     'make_decorator',
+    'map_reduce',
     'numeric_range',
     'one',
     'padded',
@@ -404,7 +409,11 @@
     This consumes the iterable, so handle with care.
 
     """
+    # maxlen=1 only stores the last item in the deque
     d = deque(enumerate(iterable, 1), maxlen=1)
+    # since we started enumerate at 1,
+    # the first item of the last pair will be the length of the iterable
+    # (assuming there were items)
     return d[0][0] if d else 0
 
 
@@ -539,9 +548,9 @@
                 item_counts[item] += 1
 
     item_counts = Counter(iterable)
+    length = sum(item_counts.values())
 
-    return perm_unique_helper(item_counts, [None] * len(iterable),
-                              len(iterable) - 1)
+    return perm_unique_helper(item_counts, [None] * length, length - 1)
 
 
 def intersperse(e, iterable, n=1):
@@ -722,7 +731,10 @@
             # a matching item, caching the rest.
             else:
                 while True:
-                    item = next(self._it)
+                    try:
+                        item = next(self._it)
+                    except StopIteration:
+                        return
                     item_value = self._key(item)
                     if item_value == value:
                         yield item
@@ -1337,6 +1349,10 @@
         >>> [(k, ''.join(g)) for k, g in grouper]
         [(0, 'ab'), (1, 'cde'), (2, 'fgh'), (3, 'i')]
 
+    Note that the order of items in the iterable is significant.
+    Only adjacent items are grouped together, so if you don't want any
+    duplicate groups, you should sort the iterable by the key function.
+
     """
     valuefunc = (lambda x: x) if valuefunc is None else valuefunc
     return ((k, map(valuefunc, g)) for k, g in groupby(iterable, keyfunc))
@@ -1983,3 +1999,70 @@
         return outer_wrapper
 
     return decorator
+
+
+def map_reduce(iterable, keyfunc, valuefunc=None, reducefunc=None):
+    """Return a dictionary that maps the items in *iterable* to categories
+    defined by *keyfunc*, transforms them with *valuefunc*, and
+    then summarizes them by category with *reducefunc*.
+
+    *valuefunc* defaults to the identity function if it is unspecified.
+    If *reducefunc* is unspecified, no summarization takes place:
+
+        >>> keyfunc = lambda x: x.upper()
+        >>> result = map_reduce('abbccc', keyfunc)
+        >>> sorted(result.items())
+        [('A', ['a']), ('B', ['b', 'b']), ('C', ['c', 'c', 'c'])]
+
+    Specifying *valuefunc* transforms the categorized items:
+
+        >>> keyfunc = lambda x: x.upper()
+        >>> valuefunc = lambda x: 1
+        >>> result = map_reduce('abbccc', keyfunc, valuefunc)
+        >>> sorted(result.items())
+        [('A', [1]), ('B', [1, 1]), ('C', [1, 1, 1])]
+
+    Specifying *reducefunc* summarizes the categorized items:
+
+        >>> keyfunc = lambda x: x.upper()
+        >>> valuefunc = lambda x: 1
+        >>> reducefunc = sum
+        >>> result = map_reduce('abbccc', keyfunc, valuefunc, reducefunc)
+        >>> sorted(result.items())
+        [('A', 1), ('B', 2), ('C', 3)]
+
+    You may want to filter the input iterable before applying the map/reduce
+    proecdure:
+
+        >>> all_items = range(30)
+        >>> items = [x for x in all_items if 10 <= x <= 20]  # Filter
+        >>> keyfunc = lambda x: x % 2  # Evens map to 0; odds to 1
+        >>> categories = map_reduce(items, keyfunc=keyfunc)
+        >>> sorted(categories.items())
+        [(0, [10, 12, 14, 16, 18, 20]), (1, [11, 13, 15, 17, 19])]
+        >>> summaries = map_reduce(items, keyfunc=keyfunc, reducefunc=sum)
+        >>> sorted(summaries.items())
+        [(0, 90), (1, 75)]
+
+    Note that all items in the iterable are gathered into a list before the
+    summarization step, which may require significant storage.
+
+    The returned object is a :obj:`collections.defaultdict` with the
+    ``default_factory`` set to ``None``, such that it behaves like a normal
+    dictionary.
+
+    """
+    valuefunc = (lambda x: x) if (valuefunc is None) else valuefunc
+
+    ret = defaultdict(list)
+    for item in iterable:
+        key = keyfunc(item)
+        value = valuefunc(item)
+        ret[key].append(value)
+
+    if reducefunc is not None:
+        for key, value_list in ret.items():
+            ret[key] = reducefunc(value_list)
+
+    ret.default_factory = None
+    return ret
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/more-itertools-4.1.0/more_itertools/recipes.py 
new/more-itertools-4.2.0/more_itertools/recipes.py
--- old/more-itertools-4.1.0/more_itertools/recipes.py  2018-01-19 
03:24:31.000000000 +0100
+++ new/more-itertools-4.2.0/more_itertools/recipes.py  2018-05-24 
03:40:14.000000000 +0200
@@ -33,6 +33,7 @@
     'pairwise',
     'partition',
     'powerset',
+    'prepend',
     'quantify',
     'random_combination_with_replacement',
     'random_combination',
@@ -548,3 +549,17 @@
         result.append(pool[-1 - n])
 
     return tuple(result)
+
+
+def prepend(value, iterator):
+    """Yield *value*, followed by the elements in *iterator*.
+
+        >>> value = '0'
+        >>> iterator = ['1', '2', '3']
+        >>> list(prepend(value, iterator))
+        ['0', '1', '2', '3']
+
+    To prepend multiple values, see :func:`itertools.chain`.
+
+    """
+    return chain([value], iterator)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/more-itertools-4.1.0/more_itertools/tests/test_more.py 
new/more-itertools-4.2.0/more_itertools/tests/test_more.py
--- old/more-itertools-4.1.0/more_itertools/tests/test_more.py  2018-01-20 
03:56:41.000000000 +0100
+++ new/more-itertools-4.2.0/more_itertools/tests/test_more.py  2018-05-10 
04:03:56.000000000 +0200
@@ -15,7 +15,7 @@
     product,
     repeat,
 )
-from operator import add, itemgetter
+from operator import add, mul, itemgetter
 from unittest import TestCase
 
 from six.moves import filter, map, range, zip
@@ -400,6 +400,27 @@
         ref_output = sorted(set(permutations(iterable)))
         self.assertEqual(test_output, ref_output)
 
+    def test_other_iterables(self):
+        """Make sure ``distinct_permutations()`` accepts a different type of
+        iterables.
+
+        """
+        # a generator
+        iterable = (c for c in ['z', 'a', 'a', 'q', 'q', 'q', 'y'])
+        test_output = sorted(mi.distinct_permutations(iterable))
+        # "reload" it
+        iterable = (c for c in ['z', 'a', 'a', 'q', 'q', 'q', 'y'])
+        ref_output = sorted(set(permutations(iterable)))
+        self.assertEqual(test_output, ref_output)
+
+        # an iterator
+        iterable = iter(['z', 'a', 'a', 'q', 'q', 'q', 'y'])
+        test_output = sorted(mi.distinct_permutations(iterable))
+        # "reload" it
+        iterable = iter(['z', 'a', 'a', 'q', 'q', 'q', 'y'])
+        ref_output = sorted(set(permutations(iterable)))
+        self.assertEqual(test_output, ref_output)
+
 
 class IlenTests(TestCase):
     def test_ilen(self):
@@ -1792,3 +1813,36 @@
 
         it.seek(0)
         self.assertEqual(list(it), ['0', '1', '2', '3', '4'])
+
+
+class MapReduceTests(TestCase):
+    def test_default(self):
+        iterable = (str(x) for x in range(5))
+        keyfunc = lambda x: int(x) // 2
+        actual = sorted(mi.map_reduce(iterable, keyfunc).items())
+        expected = [(0, ['0', '1']), (1, ['2', '3']), (2, ['4'])]
+        self.assertEqual(actual, expected)
+
+    def test_valuefunc(self):
+        iterable = (str(x) for x in range(5))
+        keyfunc = lambda x: int(x) // 2
+        valuefunc = int
+        actual = sorted(mi.map_reduce(iterable, keyfunc, valuefunc).items())
+        expected = [(0, [0, 1]), (1, [2, 3]), (2, [4])]
+        self.assertEqual(actual, expected)
+
+    def test_reducefunc(self):
+        iterable = (str(x) for x in range(5))
+        keyfunc = lambda x: int(x) // 2
+        valuefunc = int
+        reducefunc = lambda value_list: reduce(mul, value_list, 1)
+        actual = sorted(
+            mi.map_reduce(iterable, keyfunc, valuefunc, reducefunc).items()
+        )
+        expected = [(0, 0), (1, 6), (2, 4)]
+        self.assertEqual(actual, expected)
+
+    def test_ret(self):
+        d = mi.map_reduce([1, 0, 2, 0, 1, 0], bool)
+        self.assertEqual(d, {False: [0, 0, 0], True: [1, 2, 1]})
+        self.assertRaises(KeyError, lambda: d[None].append(1))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/more-itertools-4.1.0/more_itertools/tests/test_recipes.py 
new/more-itertools-4.2.0/more_itertools/tests/test_recipes.py
--- old/more-itertools-4.1.0/more_itertools/tests/test_recipes.py       
2018-01-19 03:24:31.000000000 +0100
+++ new/more-itertools-4.2.0/more_itertools/tests/test_recipes.py       
2018-05-24 03:40:14.000000000 +0200
@@ -589,3 +589,19 @@
         actual = mi.nth_combination(range(180), 4, 2000000)
         expected = (2, 12, 35, 126)
         self.assertEqual(actual, expected)
+
+
+class PrependTests(TestCase):
+    def test_basic(self):
+        value = 'a'
+        iterator = iter('bcdefg')
+        actual = list(mi.prepend(value, iterator))
+        expected = list('abcdefg')
+        self.assertEqual(actual, expected)
+
+    def test_multiple(self):
+        value = 'ab'
+        iterator = iter('cdefg')
+        actual = tuple(mi.prepend(value, iterator))
+        expected = ('ab',) + tuple('cdefg')
+        self.assertEqual(actual, expected)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/more-itertools-4.1.0/more_itertools.egg-info/PKG-INFO 
new/more-itertools-4.2.0/more_itertools.egg-info/PKG-INFO
--- old/more-itertools-4.1.0/more_itertools.egg-info/PKG-INFO   2018-01-21 
16:32:19.000000000 +0100
+++ new/more-itertools-4.2.0/more_itertools.egg-info/PKG-INFO   2018-05-24 
03:40:36.000000000 +0200
@@ -1,12 +1,11 @@
 Metadata-Version: 1.1
 Name: more-itertools
-Version: 4.1.0
+Version: 4.2.0
 Summary: More routines for operating on iterables, beyond itertools
 Home-page: https://github.com/erikrose/more-itertools
 Author: Erik Rose
 Author-email: [email protected]
 License: MIT
-Description-Content-Type: UNKNOWN
 Description: ==============
         More Itertools
         ==============
@@ -73,6 +72,22 @@
         
         
         
+        4.2.0
+        -----
+        
+        * New itertools:
+            * map_reduce (thanks to pylang)
+            * prepend (from the `Python 3.7 docs 
<https://docs.python.org/3.7/library/itertools.html#itertools-recipes>`_)
+        
+        * Improvements to existing itertools:
+            * bucket now complies with PEP 479 (thanks to irmen)
+        
+        * Other changes:
+           * Python 3.7 is now supported (thanks to irmen)
+           * Python 3.3 is no longer supported
+           * The test suite no longer requires third-party modules to run
+           * The API docs now include links to source code
+        
         4.1.0
         -----
         
@@ -301,4 +316,6 @@
 Classifier: Programming Language :: Python :: 3.3
 Classifier: Programming Language :: Python :: 3.4
 Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
 Classifier: Topic :: Software Development :: Libraries
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/more-itertools-4.1.0/setup.py 
new/more-itertools-4.2.0/setup.py
--- old/more-itertools-4.1.0/setup.py   2018-01-19 03:35:51.000000000 +0100
+++ new/more-itertools-4.2.0/setup.py   2018-05-24 03:40:14.000000000 +0200
@@ -28,7 +28,7 @@
 
 setup(
     name='more-itertools',
-    version='4.1.0',
+    version='4.2.0',
     description='More routines for operating on iterables, beyond itertools',
     long_description=get_long_description(),
     author='Erik Rose',
@@ -51,6 +51,8 @@
         'Programming Language :: Python :: 3.3',
         'Programming Language :: Python :: 3.4',
         'Programming Language :: Python :: 3.5',
+        'Programming Language :: Python :: 3.6',
+        'Programming Language :: Python :: 3.7',
         'Topic :: Software Development :: Libraries'],
     keywords=['itertools', 'iterator', 'iteration', 'filter', 'peek',
               'peekable', 'collate', 'chunk', 'chunked'],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/more-itertools-4.1.0/tox.ini 
new/more-itertools-4.2.0/tox.ini
--- old/more-itertools-4.1.0/tox.ini    2017-12-03 15:50:05.000000000 +0100
+++ new/more-itertools-4.2.0/tox.ini    2018-05-24 03:40:14.000000000 +0200
@@ -1,5 +1,5 @@
 [tox]
-envlist = py27, py32, py33, py34, py35
+envlist = py27, py34, py35, py36, py37
 
 [testenv]
 commands = {envbindir}/python -m unittest discover -v


Reply via email to