Hello community, here is the log from the commit of package python-more-itertools for openSUSE:Factory checked in at 2020-01-24 13:06:35 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-more-itertools (Old) and /work/SRC/openSUSE:Factory/.python-more-itertools.new.26092 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-more-itertools" Fri Jan 24 13:06:35 2020 rev:8 rq:766375 version:8.1.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-more-itertools/python-more-itertools.changes 2020-01-01 14:58:26.205935440 +0100 +++ /work/SRC/openSUSE:Factory/.python-more-itertools.new.26092/python-more-itertools.changes 2020-01-24 13:09:52.989402235 +0100 @@ -1,0 +2,13 @@ +Wed Jan 22 15:56:53 UTC 2020 - Martin Sirringhaus <martin.sirringh...@suse.com> + +- update to 8.1.0: + * Bug fixes + :func:`partition` works with pred=None again. (thanks + to MSeifert04) + * New itertools + :func:`sample` (thanks to tommyod) + :func:`nth_or_last` (thanks to d-ryzhikov) + * Changes to existing itertools: + The implementation for :func:`divide` was improved. + +------------------------------------------------------------------- Old: ---- more-itertools-8.0.2.tar.gz New: ---- more-itertools-8.1.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-more-itertools.spec ++++++ --- /var/tmp/diff_new_pack.HZHEyl/_old 2020-01-24 13:09:53.905402602 +0100 +++ /var/tmp/diff_new_pack.HZHEyl/_new 2020-01-24 13:09:53.905402602 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-more-itertools # -# Copyright (c) 2019 SUSE LLC +# Copyright (c) 2020 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -19,7 +19,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} %define skip_python2 1 Name: python-more-itertools -Version: 8.0.2 +Version: 8.1.0 Release: 0 Summary: More routines for operating on iterables, beyond itertools License: MIT ++++++ more-itertools-8.0.2.tar.gz -> more-itertools-8.1.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/more-itertools-8.0.2/PKG-INFO new/more-itertools-8.1.0/PKG-INFO --- old/more-itertools-8.0.2/PKG-INFO 2019-12-06 13:17:53.696788300 +0100 +++ new/more-itertools-8.1.0/PKG-INFO 2020-01-11 19:59:22.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.2 Name: more-itertools -Version: 8.0.2 +Version: 8.1.0 Summary: More routines for operating on iterables, beyond itertools Home-page: https://github.com/erikrose/more-itertools Author: Erik Rose @@ -59,7 +59,6 @@ | | `sort_together <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.sort_together>`_, | | | `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>`_, | - | | `collate <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.collate>`_, | | | `zip_offset <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.zip_offset>`_, | | | `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>`_, | @@ -67,32 +66,32 @@ | | `prepend <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.prepend>`_ | +------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Summarizing | `ilen <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.ilen>`_, | - | | `first <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.first>`_, | - | | `last <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.last>`_, | - | | `one <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.one>`_, | - | | `only <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.only>`_, | | | `unique_to_each <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.unique_to_each>`_, | - | | `locate <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.locate>`_, | - | | `rlocate <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.rlocate>`_, | + | | `sample <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.sample>`_, | | | `consecutive_groups <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.consecutive_groups>`_, | - | | `exactly_n <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.exactly_n>`_, | | | `run_length <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.run_length>`_, | | | `map_reduce <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.map_reduce>`_, | + | | `exactly_n <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.exactly_n>`_, | | | `all_equal <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.all_equal>`_, | | | `first_true <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.first_true>`_, | - | | `nth <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.nth>`_, | | | `quantify <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.quantify>`_ | +------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Selecting | `islice_extended <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.islice_extended>`_, | + | | `first <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.first>`_, | + | | `last <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.last>`_, | + | | `one <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.one>`_, | + | | `only <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.only>`_, | | | `strip <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.strip>`_, | | | `lstrip <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.lstrip>`_, | | | `rstrip <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.rstrip>`_, | + | | `filter_except <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.filter_except>`_ | + | | `map_except <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.map_except>`_ | + | | `nth_or_last <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.nth_or_last>`_, | + | | `nth <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.nth>`_, | | | `take <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.take>`_, | | | `tail <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.tail>`_, | | | `unique_everseen <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertoo ls.unique_everseen>`_, | | | `unique_justseen <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.unique_justseen>`_ | - | | `filter_except <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.filter_except>`_ | - | | `map_except <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.map_except>`_ | +------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Combinatorics | `distinct_permutations <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.distinct_permutations>`_, | | | `distinct_combinations <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.distinct_combinations>`_, | @@ -107,13 +106,15 @@ | | `nth_combination <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.nth_combination>`_ | +------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Wrapping | `always_iterable <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.always_iterable>`_, | + | | `always_reversible <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.always_reversible>`_, | | | `consumer <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.consumer>`_, | | | `with_iter <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.with_iter>`_, | | | `iter_except <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.iter_except>`_ | +------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - | Others | `replace <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.replace>`_, | + | Others | `locate <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.locate>`_, | + | | `rlocate <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.rlocate>`_, | + | | `replace <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.replace>`_, | | | `numeric_range <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.numeric_range>`_, | - | | `always_reversible <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.always_reversible>`_, | | | `side_effect <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.side_effect>`_, | | | `iterate <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.iterate>`_, | | | `difference <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.difference>`_, | @@ -181,6 +182,19 @@ :noindex: + 8.1.0 + ----- + + * Bug fixes + * partition works with ``pred=None`` again. (thanks to MSeifert04) + + * New itertools + * sample (thanks to tommyod) + * nth_or_last (thanks to d-ryzhikov) + + * Changes to existing itertools: + * The implementation for divide was improved. (thanks to jferard) + 8.0.2 ----- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/more-itertools-8.0.2/README.rst new/more-itertools-8.1.0/README.rst --- old/more-itertools-8.0.2/README.rst 2019-11-29 20:07:06.000000000 +0100 +++ new/more-itertools-8.1.0/README.rst 2020-01-11 19:59:09.000000000 +0100 @@ -51,7 +51,6 @@ | | `sort_together <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.sort_together>`_, | | | `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>`_, | -| | `collate <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.collate>`_, | | | `zip_offset <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.zip_offset>`_, | | | `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>`_, | @@ -59,32 +58,32 @@ | | `prepend <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.prepend>`_ | +------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Summarizing | `ilen <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.ilen>`_, | -| | `first <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.first>`_, | -| | `last <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.last>`_, | -| | `one <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.one>`_, | -| | `only <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.only>`_, | | | `unique_to_each <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.unique_to_each>`_, | -| | `locate <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.locate>`_, | -| | `rlocate <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.rlocate>`_, | +| | `sample <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.sample>`_, | | | `consecutive_groups <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.consecutive_groups>`_, | -| | `exactly_n <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.exactly_n>`_, | | | `run_length <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.run_length>`_, | | | `map_reduce <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.map_reduce>`_, | +| | `exactly_n <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.exactly_n>`_, | | | `all_equal <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.all_equal>`_, | | | `first_true <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.first_true>`_, | -| | `nth <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.nth>`_, | | | `quantify <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.quantify>`_ | +------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Selecting | `islice_extended <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.islice_extended>`_, | +| | `first <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.first>`_, | +| | `last <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.last>`_, | +| | `one <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.one>`_, | +| | `only <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.only>`_, | | | `strip <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.strip>`_, | | | `lstrip <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.lstrip>`_, | | | `rstrip <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.rstrip>`_, | +| | `filter_except <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.filter_except>`_ | +| | `map_except <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.map_except>`_ | +| | `nth_or_last <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.nth_or_last>`_, | +| | `nth <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.nth>`_, | | | `take <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.take>`_, | | | `tail <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.tail>`_, | | | `unique_everseen <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertoo ls.unique_everseen>`_, | | | `unique_justseen <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.unique_justseen>`_ | -| | `filter_except <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.filter_except>`_ | -| | `map_except <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.map_except>`_ | +------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Combinatorics | `distinct_permutations <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.distinct_permutations>`_, | | | `distinct_combinations <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.distinct_combinations>`_, | @@ -99,13 +98,15 @@ | | `nth_combination <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.nth_combination>`_ | +------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Wrapping | `always_iterable <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.always_iterable>`_, | +| | `always_reversible <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.always_reversible>`_, | | | `consumer <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.consumer>`_, | | | `with_iter <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.with_iter>`_, | | | `iter_except <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.iter_except>`_ | +------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Others | `replace <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.replace>`_, | +| Others | `locate <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.locate>`_, | +| | `rlocate <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.rlocate>`_, | +| | `replace <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.replace>`_, | | | `numeric_range <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.numeric_range>`_, | -| | `always_reversible <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.always_reversible>`_, | | | `side_effect <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.side_effect>`_, | | | `iterate <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.iterate>`_, | | | `difference <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.difference>`_, | diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/more-itertools-8.0.2/docs/api.rst new/more-itertools-8.1.0/docs/api.rst --- old/more-itertools-8.0.2/docs/api.rst 2019-12-01 20:26:05.000000000 +0100 +++ new/more-itertools-8.1.0/docs/api.rst 2020-01-11 19:59:09.000000000 +0100 @@ -129,17 +129,12 @@ **New itertools** .. autofunction:: ilen -.. autofunction:: first(iterable[, default]) -.. autofunction:: last(iterable[, default]) -.. autofunction:: one(iterable, too_short=ValueError, too_long=ValueError) -.. autofunction:: only(iterable, default=None, too_long=ValueError) .. autofunction:: unique_to_each -.. autofunction:: locate(iterable, pred=bool, window_size=None) -.. autofunction:: rlocate(iterable, pred=bool, window_size=None) +.. autofunction:: sample(iterable, k=1, weights=None) .. autofunction:: consecutive_groups(iterable, ordering=lambda x: x) -.. autofunction:: exactly_n(iterable, n, predicate=bool) .. autoclass:: run_length .. autofunction:: map_reduce +.. autofunction:: exactly_n(iterable, n, predicate=bool) ---- @@ -147,7 +142,6 @@ .. autofunction:: all_equal .. autofunction:: first_true -.. autofunction:: nth .. autofunction:: quantify(iterable, pred=bool) @@ -161,16 +155,22 @@ **New itertools** .. autofunction:: islice_extended(start, stop, step) +.. autofunction:: first(iterable[, default]) +.. autofunction:: last(iterable[, default]) +.. autofunction:: one(iterable, too_short=ValueError, too_long=ValueError) +.. autofunction:: only(iterable, default=None, too_long=ValueError) .. autofunction:: strip .. autofunction:: lstrip .. autofunction:: rstrip .. autofunction:: filter_except .. autofunction:: map_except +.. autofunction:: nth_or_last(iterable, n[, default]) ---- **Itertools recipes** +.. autofunction:: nth .. autofunction:: take .. autofunction:: tail .. autofunction:: unique_everseen @@ -215,6 +215,7 @@ **New itertools** .. autofunction:: always_iterable +.. autofunction:: always_reversible .. autofunction:: consumer .. autofunction:: with_iter @@ -230,9 +231,10 @@ **New itertools** +.. autofunction:: locate(iterable, pred=bool, window_size=None) +.. autofunction:: rlocate(iterable, pred=bool, window_size=None) .. autofunction:: replace .. autofunction:: numeric_range(start, stop, step) -.. autofunction:: always_reversible .. autofunction:: side_effect .. autofunction:: iterate .. autofunction:: difference(iterable, func=operator.sub, *, initial=None) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/more-itertools-8.0.2/docs/conf.py new/more-itertools-8.1.0/docs/conf.py --- old/more-itertools-8.0.2/docs/conf.py 2019-12-06 13:17:40.000000000 +0100 +++ new/more-itertools-8.1.0/docs/conf.py 2020-01-11 19:59:09.000000000 +0100 @@ -14,6 +14,8 @@ import sphinx_rtd_theme +import more_itertools + # 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. @@ -49,7 +51,7 @@ # built documents. # # The short X.Y version. -version = '8.0.2' +version = more_itertools.__version__ # The full version, including alpha/beta/rc tags. release = version diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/more-itertools-8.0.2/docs/versions.rst new/more-itertools-8.1.0/docs/versions.rst --- old/more-itertools-8.0.2/docs/versions.rst 2019-12-06 13:17:17.000000000 +0100 +++ new/more-itertools-8.1.0/docs/versions.rst 2020-01-11 19:59:09.000000000 +0100 @@ -5,6 +5,19 @@ .. automodule:: more_itertools :noindex: +8.1.0 +----- + +* Bug fixes + * :func:`partition` works with ``pred=None`` again. (thanks to MSeifert04) + +* New itertools + * :func:`sample` (thanks to tommyod) + * :func:`nth_or_last` (thanks to d-ryzhikov) + +* Changes to existing itertools: + * The implementation for :func:`divide` was improved. (thanks to jferard) + 8.0.2 ----- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/more-itertools-8.0.2/more_itertools/__init__.py new/more-itertools-8.1.0/more_itertools/__init__.py --- old/more-itertools-8.0.2/more_itertools/__init__.py 2019-12-06 03:05:54.000000000 +0100 +++ new/more-itertools-8.1.0/more_itertools/__init__.py 2020-01-11 19:59:09.000000000 +0100 @@ -1,2 +1,4 @@ from .more import * # noqa from .recipes import * # noqa + +__version__ = '8.1.0' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/more-itertools-8.0.2/more_itertools/more.py new/more-itertools-8.1.0/more_itertools/more.py --- old/more-itertools-8.0.2/more_itertools/more.py 2019-12-06 03:05:47.000000000 +0100 +++ new/more-itertools-8.1.0/more_itertools/more.py 2020-01-11 19:59:09.000000000 +0100 @@ -1,9 +1,8 @@ import warnings - from collections import Counter, defaultdict, deque from collections.abc import Sequence from functools import partial, wraps -from heapq import merge +from heapq import merge, heapify, heapreplace, heappop from itertools import ( chain, compress, @@ -18,7 +17,9 @@ tee, zip_longest, ) -from operator import itemgetter, lt, gt, sub +from math import exp, floor, log +from operator import gt, itemgetter, lt, sub +from random import random, randrange, uniform from sys import maxsize from time import monotonic @@ -58,6 +59,7 @@ 'make_decorator', 'map_except', 'map_reduce', + 'nth_or_last', 'numeric_range', 'one', 'only', @@ -70,6 +72,7 @@ 'rlocate', 'rstrip', 'run_length', + 'sample', 'seekable', 'SequenceView', 'side_effect', @@ -180,6 +183,23 @@ return default +def nth_or_last(iterable, n, default=_marker): + """Return the nth or the last item of *iterable*, + or *default* if *iterable* is empty. + + >>> nth_or_last([0, 1, 2, 3], 2) + 2 + >>> nth_or_last([0, 1], 2) + 1 + >>> nth_or_last([], 0, 'some default') + 'some default' + + If *default* is not provided and there are no items in the iterable, + raise ``ValueError``. + """ + return last(islice(iterable, n + 1), default=default) + + class peekable: """Wrap an iterator to allow lookahead and prepending elements. @@ -1441,13 +1461,20 @@ if n < 1: raise ValueError('n must be at least 1') - seq = tuple(iterable) + try: + iterable[:0] + except TypeError: + seq = tuple(iterable) + else: + seq = iterable + q, r = divmod(len(seq), n) ret = [] - for i in range(n): - start = (i * q) + (i if i < r else r) - stop = ((i + 1) * q) + (i + 1 if i + 1 < r else r) + stop = 0 + for i in range(1, n + 1): + start = stop + stop += q + 1 if i <= r else q ret.append(iter(seq[start:stop])) return ret @@ -2689,3 +2716,100 @@ yield function(item) except exceptions: pass + + +def _sample_unweighted(iterable, k): + # Implementation of "Algorithm L" from the 1994 paper by Kim-Hung Li: + # "Reservoir-Sampling Algorithms of Time Complexity O(n(1+log(N/n)))". + + # Fill up the reservoir (collection of samples) with the first `k` samples + reservoir = take(k, iterable) + + # Generate random number that's the largest in a sample of k U(0,1) numbers + # Largest order statistic: https://en.wikipedia.org/wiki/Order_statistic + W = exp(log(random()) / k) + + # The number of elements to skip before changing the reservoir is a random + # number with a geometric distribution. Sample it using random() and logs. + next_index = k + floor(log(random()) / log(1 - W)) + + for index, element in enumerate(iterable, k): + + if index == next_index: + reservoir[randrange(k)] = element + # The new W is the largest in a sample of k U(0, `old_W`) numbers + W *= exp(log(random()) / k) + next_index += floor(log(random()) / log(1 - W)) + 1 + + return reservoir + + +def _sample_weighted(iterable, k, weights): + # Implementation of "A-ExpJ" from the 2006 paper by Efraimidis et al. : + # "Weighted random sampling with a reservoir". + + # Log-transform for numerical stability for weights that are small/large + weight_keys = (log(random()) / weight for weight in weights) + + # Fill up the reservoir (collection of samples) with the first `k` + # weight-keys and elements, then heapify the list. + reservoir = take(k, zip(weight_keys, iterable)) + heapify(reservoir) + + # The number of jumps before changing the reservoir is a random variable + # with an exponential distribution. Sample it using random() and logs. + smallest_weight_key, _ = reservoir[0] + weights_to_skip = log(random()) / smallest_weight_key + + for weight, element in zip(weights, iterable): + if weight >= weights_to_skip: + # The notation here is consistent with the paper, but we store + # the weight-keys in log-space for better numerical stability. + smallest_weight_key, _ = reservoir[0] + t_w = exp(weight * smallest_weight_key) + r_2 = uniform(t_w, 1) # generate U(t_w, 1) + weight_key = log(r_2) / weight + heapreplace(reservoir, (weight_key, element)) + smallest_weight_key, _ = reservoir[0] + weights_to_skip = log(random()) / smallest_weight_key + else: + weights_to_skip -= weight + + # Equivalent to [element for weight_key, element in sorted(reservoir)] + return [heappop(reservoir)[1] for _ in range(k)] + + +def sample(iterable, k, weights=None): + """Return a *k*-length list of elements chosen (without replacement) + from the *iterable*. Like :func:`random.sample`, but works on iterables + of unknown length. + + >>> iterable = range(100) + >>> sample(iterable, 5) # doctest: +SKIP + [81, 60, 96, 16, 4] + + An iterable with *weights* may also be given: + + >>> iterable = range(100) + >>> weights = (i * i + 1 for i in range(100)) + >>> sampled = sample(iterable, 5, weights=weights) # doctest: +SKIP + [79, 67, 74, 66, 78] + + The algorithm can also be used to generate weighted random permutations. + The relative weight of each item determines the probability that it + appears late in the permutation. + + >>> data = "abcdefgh" + >>> weights = range(1, len(data) + 1) + >>> sample(data, k=len(data), weights=weights) # doctest: +SKIP + ['c', 'a', 'b', 'e', 'g', 'd', 'h', 'f'] + """ + if k == 0: + return [] + + iterable = iter(iterable) + if weights is None: + return _sample_unweighted(iterable, k) + else: + weights = iter(weights) + return _sample_weighted(iterable, k, weights) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/more-itertools-8.0.2/more_itertools/recipes.py new/more-itertools-8.1.0/more_itertools/recipes.py --- old/more-itertools-8.0.2/more_itertools/recipes.py 2019-12-01 04:46:19.000000000 +0100 +++ new/more-itertools-8.1.0/more_itertools/recipes.py 2020-01-04 02:33:10.000000000 +0100 @@ -313,8 +313,17 @@ >>> list(even_items), list(odd_items) ([0, 2, 4, 6, 8], [1, 3, 5, 7, 9]) + If *pred* is None, :func:`bool` is used. + + >>> iterable = [0, 1, False, True, '', ' '] + >>> false_items, true_items = partition(None, iterable) + >>> list(false_items), list(true_items) + ([0, False, ''], [1, True, ' ']) + """ - # partition(is_odd, range(10)) --> 0 2 4 6 8 and 1 3 5 7 9 + if pred is None: + pred = bool + evaluations = ((pred(x), x) for x in iterable) t1, t2 = tee(evaluations) return ( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/more-itertools-8.0.2/more_itertools.egg-info/PKG-INFO new/more-itertools-8.1.0/more_itertools.egg-info/PKG-INFO --- old/more-itertools-8.0.2/more_itertools.egg-info/PKG-INFO 2019-12-06 13:17:53.000000000 +0100 +++ new/more-itertools-8.1.0/more_itertools.egg-info/PKG-INFO 2020-01-11 19:59:22.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.2 Name: more-itertools -Version: 8.0.2 +Version: 8.1.0 Summary: More routines for operating on iterables, beyond itertools Home-page: https://github.com/erikrose/more-itertools Author: Erik Rose @@ -59,7 +59,6 @@ | | `sort_together <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.sort_together>`_, | | | `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>`_, | - | | `collate <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.collate>`_, | | | `zip_offset <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.zip_offset>`_, | | | `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>`_, | @@ -67,32 +66,32 @@ | | `prepend <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.prepend>`_ | +------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Summarizing | `ilen <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.ilen>`_, | - | | `first <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.first>`_, | - | | `last <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.last>`_, | - | | `one <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.one>`_, | - | | `only <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.only>`_, | | | `unique_to_each <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.unique_to_each>`_, | - | | `locate <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.locate>`_, | - | | `rlocate <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.rlocate>`_, | + | | `sample <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.sample>`_, | | | `consecutive_groups <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.consecutive_groups>`_, | - | | `exactly_n <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.exactly_n>`_, | | | `run_length <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.run_length>`_, | | | `map_reduce <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.map_reduce>`_, | + | | `exactly_n <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.exactly_n>`_, | | | `all_equal <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.all_equal>`_, | | | `first_true <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.first_true>`_, | - | | `nth <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.nth>`_, | | | `quantify <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.quantify>`_ | +------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Selecting | `islice_extended <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.islice_extended>`_, | + | | `first <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.first>`_, | + | | `last <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.last>`_, | + | | `one <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.one>`_, | + | | `only <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.only>`_, | | | `strip <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.strip>`_, | | | `lstrip <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.lstrip>`_, | | | `rstrip <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.rstrip>`_, | + | | `filter_except <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.filter_except>`_ | + | | `map_except <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.map_except>`_ | + | | `nth_or_last <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.nth_or_last>`_, | + | | `nth <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.nth>`_, | | | `take <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.take>`_, | | | `tail <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.tail>`_, | | | `unique_everseen <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertoo ls.unique_everseen>`_, | | | `unique_justseen <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.unique_justseen>`_ | - | | `filter_except <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.filter_except>`_ | - | | `map_except <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.map_except>`_ | +------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Combinatorics | `distinct_permutations <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.distinct_permutations>`_, | | | `distinct_combinations <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.distinct_combinations>`_, | @@ -107,13 +106,15 @@ | | `nth_combination <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.nth_combination>`_ | +------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Wrapping | `always_iterable <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.always_iterable>`_, | + | | `always_reversible <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.always_reversible>`_, | | | `consumer <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.consumer>`_, | | | `with_iter <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.with_iter>`_, | | | `iter_except <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.iter_except>`_ | +------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - | Others | `replace <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.replace>`_, | + | Others | `locate <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.locate>`_, | + | | `rlocate <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.rlocate>`_, | + | | `replace <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.replace>`_, | | | `numeric_range <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.numeric_range>`_, | - | | `always_reversible <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.always_reversible>`_, | | | `side_effect <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.side_effect>`_, | | | `iterate <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.iterate>`_, | | | `difference <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.difference>`_, | @@ -181,6 +182,19 @@ :noindex: + 8.1.0 + ----- + + * Bug fixes + * partition works with ``pred=None`` again. (thanks to MSeifert04) + + * New itertools + * sample (thanks to tommyod) + * nth_or_last (thanks to d-ryzhikov) + + * Changes to existing itertools: + * The implementation for divide was improved. (thanks to jferard) + 8.0.2 ----- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/more-itertools-8.0.2/setup.cfg new/more-itertools-8.1.0/setup.cfg --- old/more-itertools-8.0.2/setup.cfg 2019-12-06 13:17:53.696788300 +0100 +++ new/more-itertools-8.1.0/setup.cfg 2020-01-11 19:59:22.000000000 +0100 @@ -1,3 +1,9 @@ +[bumpversion] +current_version = 8.1.0 +commit = True +tag = False +files = more_itertools/__init__.py + [flake8] exclude = ./docs/conf.py, .eggs/ ignore = E203, E731, E741, F999, W503 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/more-itertools-8.0.2/setup.py new/more-itertools-8.1.0/setup.py --- old/more-itertools-8.0.2/setup.py 2019-12-06 13:17:35.000000000 +0100 +++ new/more-itertools-8.1.0/setup.py 2020-01-11 19:59:09.000000000 +0100 @@ -2,6 +2,8 @@ from setuptools import setup +from more_itertools import __version__ + def get_long_description(): # Fix display issues on PyPI caused by RST markup @@ -22,7 +24,7 @@ setup( name='more-itertools', - version='8.0.2', + version=__version__, description='More routines for operating on iterables, beyond itertools', long_description=get_long_description(), author='Erik Rose', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/more-itertools-8.0.2/tests/test_more.py new/more-itertools-8.1.0/tests/test_more.py --- old/more-itertools-8.0.2/tests/test_more.py 2019-12-06 03:05:47.000000000 +0100 +++ new/more-itertools-8.1.0/tests/test_more.py 2020-01-11 19:59:09.000000000 +0100 @@ -19,6 +19,8 @@ repeat, ) from operator import add, mul, itemgetter +from random import seed +from statistics import mean from sys import version_info from time import sleep from unittest import skipIf, TestCase @@ -200,6 +202,21 @@ self.assertEqual(mi.last(IterOnlyRange(5)), 4) +class NthOrLastTests(TestCase): + """Tests for ``nth_or_last()``""" + + def test_basic(self): + self.assertEqual(mi.nth_or_last(range(3), 1), 1) + self.assertEqual(mi.nth_or_last(range(3), 3), 2) + + def test_default_value(self): + default = 42 + self.assertEqual(mi.nth_or_last(range(0), 3, default), default) + + def test_empty_iterable_no_default(self): + self.assertRaises(ValueError, lambda: mi.nth_or_last(range(0), 0)) + + class PeekableTests(TestCase): """Tests for ``peekable()`` behavor not incidentally covered by testing ``collate()`` @@ -1670,9 +1687,8 @@ ) def test_large_n(self): - iterable = [1, 2, 3, 4] self.assertEqual( - [list(x) for x in mi.divide(6, iterable)], + [list(x) for x in mi.divide(6, iter(range(1, 4 + 1)))], [[1], [2], [3], [4], [], []], ) @@ -2936,3 +2952,89 @@ actual = list(mi.map_except(int, iterable, ValueError, TypeError)) expected = [0, 1, 2, 4] self.assertEqual(actual, expected) + + +class SampleTests(TestCase): + + def test_unit_case(self): + """Test against a fixed case by seeding the random module.""" + # Beware that this test really just verifies random.random() behavior. + # If the algorithm is changed (e.g. to a more naive implementation) + # this test will fail, but the algorithm might be correct. + # Also, this test can pass and the algorithm can be completely wrong. + data = "abcdef" + weights = list(range(1, len(data) + 1)) + seed(123) + actual = mi.sample(data, k=2, weights=weights) + expected = ['f', 'e'] + self.assertEqual(actual, expected) + + def test_length(self): + """Check that *k* elements are sampled.""" + data = [1, 2, 3, 4, 5] + for k in [0, 3, 5, 7]: + sampled = mi.sample(data, k=k) + actual = len(sampled) + expected = min(k, len(data)) + self.assertEqual(actual, expected) + + def test_samling_entire_iterable(self): + """If k=len(iterable), the sample contains the original elements.""" + data = ["a", 2, "a", 4, (1, 2, 3)] + actual = set(mi.sample(data, k=len(data))) + expected = set(data) + self.assertEqual(actual, expected) + + def test_scale_invariance_of_weights(self): + """The probabilit of chosing element a_i is w_i / sum(weights). + Scaling weights should not change the probability or outcome.""" + data = "abcdef" + + weights = list(range(1, len(data) + 1)) + seed(123) + first_sample = mi.sample(data, k=2, weights=weights) + + # Scale the weights and sample again + weights_scaled = [w / 1e10 for w in weights] + seed(123) + second_sample = mi.sample(data, k=2, weights=weights_scaled) + + self.assertEqual(first_sample, second_sample) + + def test_invariance_under_permutations_unweighted(self): + """The order of the data should not matter. This is a stochastic test, + but it will fail in less than 1 / 10_000 cases.""" + + # Create a data set and a reversed data set + data = list(range(100)) + data_rev = list(reversed(data)) + + # Sample each data set 10 times + data_means = [mean(mi.sample(data, k=50)) for _ in range(10)] + data_rev_means = [mean(mi.sample(data_rev, k=50)) for _ in range(10)] + + # The difference in the means should be low, i.e. little bias + difference_in_means = abs(mean(data_means) - mean(data_rev_means)) + + # The observed largest difference in 10,000 simulations was 5.09599 + self.assertTrue(difference_in_means < 5.1) + + def test_invariance_under_permutations_weighted(self): + """The order of the data should not matter. This is a stochastic test, + but it will fail in less than 1 / 10_000 cases.""" + + # Create a data set and a reversed data set + data = list(range(1, 101)) + data_rev = list(reversed(data)) + + # Sample each data set 10 times + data_means = [mean(mi.sample(data, k=50, weights=data)) + for _ in range(10)] + data_rev_means = [mean(mi.sample(data_rev, k=50, weights=data_rev)) + for _ in range(10)] + + # The difference in the means should be low, i.e. little bias + difference_in_means = abs(mean(data_means) - mean(data_rev_means)) + + # The observed largest difference in 10,000 simulations was 4.337999 + self.assertTrue(difference_in_means < 4.4) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/more-itertools-8.0.2/tests/test_recipes.py new/more-itertools-8.1.0/tests/test_recipes.py --- old/more-itertools-8.0.2/tests/test_recipes.py 2019-12-01 04:46:19.000000000 +0100 +++ new/more-itertools-8.1.0/tests/test_recipes.py 2020-01-04 02:33:10.000000000 +0100 @@ -319,17 +319,20 @@ """Tests for ``partition()``""" def test_bool(self): - """Test when pred() returns a boolean""" lesser, greater = mi.partition(lambda x: x > 5, range(10)) self.assertEqual(list(lesser), [0, 1, 2, 3, 4, 5]) self.assertEqual(list(greater), [6, 7, 8, 9]) def test_arbitrary(self): - """Test when pred() returns an integer""" divisibles, remainders = mi.partition(lambda x: x % 3, range(10)) self.assertEqual(list(divisibles), [0, 3, 6, 9]) self.assertEqual(list(remainders), [1, 2, 4, 5, 7, 8]) + def test_pred_is_none(self): + falses, trues = mi.partition(None, range(3)) + self.assertEqual(list(falses), [0]) + self.assertEqual(list(trues), [1, 2]) + class PowersetTests(TestCase): """Tests for ``powerset()``"""