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