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 - toddrme2178@gmail.com + +- 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: erikrose@grinchcentral.com 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: erikrose@grinchcentral.com 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