Hello community, here is the log from the commit of package python-ordered-set for openSUSE:Factory checked in at 2019-06-06 18:15:18 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-ordered-set (Old) and /work/SRC/openSUSE:Factory/.python-ordered-set.new.4811 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-ordered-set" Thu Jun 6 18:15:18 2019 rev:2 rq:704779 version:3.1.1 Changes: -------- --- /work/SRC/openSUSE:Factory/python-ordered-set/python-ordered-set.changes 2019-05-06 13:23:09.180770758 +0200 +++ /work/SRC/openSUSE:Factory/.python-ordered-set.new.4811/python-ordered-set.changes 2019-06-06 18:15:19.744721050 +0200 @@ -1,0 +2,18 @@ +Wed May 22 14:21:24 UTC 2019 - Marketa Calabkova <[email protected]> + +- update to version 3.1.1 + * Implement set api. SLICE_ALL getitem returns copy + * Add tests for new API. Replace nose with pytest. + * OrderedSet now inherits from collections.Sequence, __eq__ now + checks order of sequences + * Drop Python 2.6 support; Python and pytest already don't + support it + * Fixed bitwise and + * Added comprehensive binary operation consistency checks + * Fix DeprecationWarning due to collections.abc in Python 3.7 + * Use set literal instead of function + * Fix error when fancy indexing by a NumPy array + * Update in-place operations to be O(N) + * Add testing and document support for Python 3.7 + +------------------------------------------------------------------- Old: ---- ordered-set-2.0.2.tar.gz New: ---- ordered-set-3.1.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-ordered-set.spec ++++++ --- /var/tmp/diff_new_pack.AR0zeb/_old 2019-06-06 18:15:20.540720816 +0200 +++ /var/tmp/diff_new_pack.AR0zeb/_new 2019-06-06 18:15:20.560720811 +0200 @@ -21,14 +21,14 @@ %global dir_name ordered_set %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-%{short_name} -Version: 2.0.2 +Version: 3.1.1 Release: 0 Summary: Custom MutableSet that remembers its order License: MIT Group: Development/Libraries/Python URL: https://github.com/LuminosoInsight/ordered-set Source0: https://pypi.python.org/packages/source/o/%{short_name}/%{short_name}-%{version}.tar.gz -BuildRequires: %{python_module nose} +BuildRequires: %{python_module pytest} BuildRequires: %{python_module setuptools} BuildRequires: fdupes BuildRequires: python-rpm-macros @@ -50,11 +50,11 @@ %python_expand %fdupes %{buildroot}%{$python_sitelib} %check -%python_exec setup.py nosetests +%pytest test.py %files %{python_files} %license MIT-LICENSE -%doc README +%doc README.md %{python_sitelib}/%{dir_name}-* %{python_sitelib}/%{dir_name}.py* %pycache_only %{python3_sitelib}/__pycache__/%{dir_name}.* ++++++ ordered-set-2.0.2.tar.gz -> ordered-set-3.1.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ordered-set-2.0.2/MIT-LICENSE new/ordered-set-3.1.1/MIT-LICENSE --- old/ordered-set-2.0.2/MIT-LICENSE 2017-04-19 17:44:56.000000000 +0200 +++ new/ordered-set-3.1.1/MIT-LICENSE 2018-06-16 22:59:22.000000000 +0200 @@ -1,4 +1,4 @@ -Copyright (c) 2013 Luminoso Technologies, Inc. +Copyright (c) 2018 Luminoso Technologies, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ordered-set-2.0.2/PKG-INFO new/ordered-set-3.1.1/PKG-INFO --- old/ordered-set-2.0.2/PKG-INFO 2017-04-19 20:21:54.000000000 +0200 +++ new/ordered-set-3.1.1/PKG-INFO 2019-04-25 21:07:28.000000000 +0200 @@ -1,17 +1,154 @@ -Metadata-Version: 1.1 +Metadata-Version: 2.1 Name: ordered-set -Version: 2.0.2 +Version: 3.1.1 Summary: A MutableSet that remembers its order, so that every entry has an index. -Home-page: http://github.com/LuminosoInsight/ordered-set -Author: Luminoso Technologies, Inc. -Author-email: [email protected] +Home-page: https://github.com/LuminosoInsight/ordered-set +Maintainer: Robyn Speer +Maintainer-email: [email protected] License: MIT-LICENSE -Description: UNKNOWN +Description: [](https://travis-ci.org/LuminosoInsight/ordered-set) + [](https://codecov.io/github/LuminosoInsight/ordered-set?branch=master) + [](https://pypi.python.org/pypi/ordered-set) + + An OrderedSet is a mutable data structure that is a hybrid of a list and a set. + It remembers the order of its entries, and every entry has an index number that + can be looked up. + + + ## Usage examples + + An OrderedSet is created and used like a set: + + >>> from ordered_set import OrderedSet + + >>> letters = OrderedSet('abracadabra') + + >>> letters + OrderedSet(['a', 'b', 'r', 'c', 'd']) + + >>> 'r' in letters + True + + It is efficient to find the index of an entry in an OrderedSet, or find an + entry by its index. To help with this use case, the `.add()` method returns + the index of the added item, whether it was already in the set or not. + + >>> letters.index('r') + 2 + + >>> letters[2] + 'r' + + >>> letters.add('r') + 2 + + >>> letters.add('x') + 5 + + OrderedSets implement the union (`|`), intersection (`&`), and difference (`-`) + operators like sets do. + + >>> letters |= OrderedSet('shazam') + + >>> letters + OrderedSet(['a', 'b', 'r', 'c', 'd', 'x', 's', 'h', 'z', 'm']) + + >>> letters & set('aeiou') + OrderedSet(['a']) + + >>> letters -= 'abcd' + + >>> letters + OrderedSet(['r', 'x', 's', 'h', 'z', 'm']) + + The `__getitem__()` and `index()` methods have been extended to accept any + iterable except a string, returning a list, to perform NumPy-like "fancy + indexing". + + >>> letters = OrderedSet('abracadabra') + + >>> letters[[0, 2, 3]] + ['a', 'r', 'c'] + + >>> letters.index(['a', 'r', 'c']) + [0, 2, 3] + + OrderedSet implements `__getstate__` and `__setstate__` so it can be pickled, + and implements the abstract base classes `collections.MutableSet` and + `collections.Sequence`. + + + ## Interoperability with NumPy and Pandas + + An OrderedSet can be used as a bi-directional mapping between a sparse + vocabulary and dense index numbers. As of version 3.1, it accepts NumPy arrays + of index numbers as well as lists. + + This combination of features makes OrderedSet a simple implementation of many + of the things that `pandas.Index` is used for, and many of its operations are + faster than the equivalent pandas operations. + + For further compatibility with pandas.Index, `get_loc` (the pandas method for + looking up a single index) and `get_indexer` (the pandas method for fancy + indexing in reverse) are both aliases for `index` (which handles both cases + in OrderedSet). + + + ## Type hinting + To use type hinting features install `ordered-set-stubs` package from + [PyPI](https://pypi.org/project/ordered-set-stubs/): + + $ pip install ordered-set-stubs + + + ## Authors + + OrderedSet was implemented by Robyn Speer. Jon Crall contributed changes and + tests to make it fit the Python set API. + + + ## Comparisons + + The original implementation of OrderedSet was a [recipe posted to ActiveState + Recipes][recipe] by Raymond Hettiger, released under the MIT license. + + [recipe]: https://code.activestate.com/recipes/576694-orderedset/ + + Hettiger's implementation kept its content in a doubly-linked list referenced by a + dict. As a result, looking up an item by its index was an O(N) operation, while + deletion was O(1). + + This version makes different trade-offs for the sake of efficient lookups. Its + content is a standard Python list instead of a doubly-linked list. This + provides O(1) lookups by index at the expense of O(N) deletion, as well as + slightly faster iteration. + + In Python 3.6 and later, the built-in `dict` type is inherently ordered. If you + ignore the dictionary values, that also gives you a simple ordered set, with + fast O(1) insertion, deletion, iteration and membership testing. However, `dict` + does not provide the list-like random access features of OrderedSet. You + would have to convert it to a list in O(N) to look up the index of an entry or + look up an entry by its index. + + + ## Compatibility + + OrderedSet is automatically tested on Python 2.7, 3.4, 3.5, 3.6, and 3.7. + We've checked more informally that it works on PyPy and PyPy3. + Platform: any Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License +Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 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: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy +Requires-Python: >=2.7 +Description-Content-Type: text/markdown diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ordered-set-2.0.2/README new/ordered-set-3.1.1/README --- old/ordered-set-2.0.2/README 2017-04-19 17:44:56.000000000 +0200 +++ new/ordered-set-3.1.1/README 1970-01-01 01:00:00.000000000 +0100 @@ -1,20 +0,0 @@ -An OrderedSet is a custom MutableSet that remembers its order, so that every -entry has an index that can be looked up. - -Based on a recipe originally posted to ActiveState Recipes by Raymond Hettiger, -and released under the MIT license: - - http://code.activestate.com/recipes/576694-orderedset/ - -Rob Speer's changes are as follows: - - - changed the content from a doubly-linked list to a regular Python list. - Seriously, who wants O(1) deletes but O(N) lookups by index? - - add() returns the index of the added item - - index() just returns the index of an item - - added a __getstate__ and __setstate__ so it can be pickled - - added __getitem__ - - __getitem__ and index() can be passed lists or arrays, looking up all - the elements in them to perform NumPy-like "fancy indexing" - -Tested on Python 2.6, 2.7, 3.3, 3.4, 3.5, PyPy, and PyPy3. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ordered-set-2.0.2/README.md new/ordered-set-3.1.1/README.md --- old/ordered-set-2.0.2/README.md 1970-01-01 01:00:00.000000000 +0100 +++ new/ordered-set-3.1.1/README.md 2018-12-20 20:44:37.000000000 +0100 @@ -0,0 +1,129 @@ +[](https://travis-ci.org/LuminosoInsight/ordered-set) +[](https://codecov.io/github/LuminosoInsight/ordered-set?branch=master) +[](https://pypi.python.org/pypi/ordered-set) + +An OrderedSet is a mutable data structure that is a hybrid of a list and a set. +It remembers the order of its entries, and every entry has an index number that +can be looked up. + + +## Usage examples + +An OrderedSet is created and used like a set: + + >>> from ordered_set import OrderedSet + + >>> letters = OrderedSet('abracadabra') + + >>> letters + OrderedSet(['a', 'b', 'r', 'c', 'd']) + + >>> 'r' in letters + True + +It is efficient to find the index of an entry in an OrderedSet, or find an +entry by its index. To help with this use case, the `.add()` method returns +the index of the added item, whether it was already in the set or not. + + >>> letters.index('r') + 2 + + >>> letters[2] + 'r' + + >>> letters.add('r') + 2 + + >>> letters.add('x') + 5 + +OrderedSets implement the union (`|`), intersection (`&`), and difference (`-`) +operators like sets do. + + >>> letters |= OrderedSet('shazam') + + >>> letters + OrderedSet(['a', 'b', 'r', 'c', 'd', 'x', 's', 'h', 'z', 'm']) + + >>> letters & set('aeiou') + OrderedSet(['a']) + + >>> letters -= 'abcd' + + >>> letters + OrderedSet(['r', 'x', 's', 'h', 'z', 'm']) + +The `__getitem__()` and `index()` methods have been extended to accept any +iterable except a string, returning a list, to perform NumPy-like "fancy +indexing". + + >>> letters = OrderedSet('abracadabra') + + >>> letters[[0, 2, 3]] + ['a', 'r', 'c'] + + >>> letters.index(['a', 'r', 'c']) + [0, 2, 3] + +OrderedSet implements `__getstate__` and `__setstate__` so it can be pickled, +and implements the abstract base classes `collections.MutableSet` and +`collections.Sequence`. + + +## Interoperability with NumPy and Pandas + +An OrderedSet can be used as a bi-directional mapping between a sparse +vocabulary and dense index numbers. As of version 3.1, it accepts NumPy arrays +of index numbers as well as lists. + +This combination of features makes OrderedSet a simple implementation of many +of the things that `pandas.Index` is used for, and many of its operations are +faster than the equivalent pandas operations. + +For further compatibility with pandas.Index, `get_loc` (the pandas method for +looking up a single index) and `get_indexer` (the pandas method for fancy +indexing in reverse) are both aliases for `index` (which handles both cases +in OrderedSet). + + +## Type hinting +To use type hinting features install `ordered-set-stubs` package from +[PyPI](https://pypi.org/project/ordered-set-stubs/): + + $ pip install ordered-set-stubs + + +## Authors + +OrderedSet was implemented by Robyn Speer. Jon Crall contributed changes and +tests to make it fit the Python set API. + + +## Comparisons + +The original implementation of OrderedSet was a [recipe posted to ActiveState +Recipes][recipe] by Raymond Hettiger, released under the MIT license. + +[recipe]: https://code.activestate.com/recipes/576694-orderedset/ + +Hettiger's implementation kept its content in a doubly-linked list referenced by a +dict. As a result, looking up an item by its index was an O(N) operation, while +deletion was O(1). + +This version makes different trade-offs for the sake of efficient lookups. Its +content is a standard Python list instead of a doubly-linked list. This +provides O(1) lookups by index at the expense of O(N) deletion, as well as +slightly faster iteration. + +In Python 3.6 and later, the built-in `dict` type is inherently ordered. If you +ignore the dictionary values, that also gives you a simple ordered set, with +fast O(1) insertion, deletion, iteration and membership testing. However, `dict` +does not provide the list-like random access features of OrderedSet. You +would have to convert it to a list in O(N) to look up the index of an entry or +look up an entry by its index. + + +## Compatibility + +OrderedSet is automatically tested on Python 2.7, 3.4, 3.5, 3.6, and 3.7. +We've checked more informally that it works on PyPy and PyPy3. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ordered-set-2.0.2/ordered_set.egg-info/PKG-INFO new/ordered-set-3.1.1/ordered_set.egg-info/PKG-INFO --- old/ordered-set-2.0.2/ordered_set.egg-info/PKG-INFO 2017-04-19 20:21:54.000000000 +0200 +++ new/ordered-set-3.1.1/ordered_set.egg-info/PKG-INFO 2019-04-25 21:07:27.000000000 +0200 @@ -1,17 +1,154 @@ -Metadata-Version: 1.1 +Metadata-Version: 2.1 Name: ordered-set -Version: 2.0.2 +Version: 3.1.1 Summary: A MutableSet that remembers its order, so that every entry has an index. -Home-page: http://github.com/LuminosoInsight/ordered-set -Author: Luminoso Technologies, Inc. -Author-email: [email protected] +Home-page: https://github.com/LuminosoInsight/ordered-set +Maintainer: Robyn Speer +Maintainer-email: [email protected] License: MIT-LICENSE -Description: UNKNOWN +Description: [](https://travis-ci.org/LuminosoInsight/ordered-set) + [](https://codecov.io/github/LuminosoInsight/ordered-set?branch=master) + [](https://pypi.python.org/pypi/ordered-set) + + An OrderedSet is a mutable data structure that is a hybrid of a list and a set. + It remembers the order of its entries, and every entry has an index number that + can be looked up. + + + ## Usage examples + + An OrderedSet is created and used like a set: + + >>> from ordered_set import OrderedSet + + >>> letters = OrderedSet('abracadabra') + + >>> letters + OrderedSet(['a', 'b', 'r', 'c', 'd']) + + >>> 'r' in letters + True + + It is efficient to find the index of an entry in an OrderedSet, or find an + entry by its index. To help with this use case, the `.add()` method returns + the index of the added item, whether it was already in the set or not. + + >>> letters.index('r') + 2 + + >>> letters[2] + 'r' + + >>> letters.add('r') + 2 + + >>> letters.add('x') + 5 + + OrderedSets implement the union (`|`), intersection (`&`), and difference (`-`) + operators like sets do. + + >>> letters |= OrderedSet('shazam') + + >>> letters + OrderedSet(['a', 'b', 'r', 'c', 'd', 'x', 's', 'h', 'z', 'm']) + + >>> letters & set('aeiou') + OrderedSet(['a']) + + >>> letters -= 'abcd' + + >>> letters + OrderedSet(['r', 'x', 's', 'h', 'z', 'm']) + + The `__getitem__()` and `index()` methods have been extended to accept any + iterable except a string, returning a list, to perform NumPy-like "fancy + indexing". + + >>> letters = OrderedSet('abracadabra') + + >>> letters[[0, 2, 3]] + ['a', 'r', 'c'] + + >>> letters.index(['a', 'r', 'c']) + [0, 2, 3] + + OrderedSet implements `__getstate__` and `__setstate__` so it can be pickled, + and implements the abstract base classes `collections.MutableSet` and + `collections.Sequence`. + + + ## Interoperability with NumPy and Pandas + + An OrderedSet can be used as a bi-directional mapping between a sparse + vocabulary and dense index numbers. As of version 3.1, it accepts NumPy arrays + of index numbers as well as lists. + + This combination of features makes OrderedSet a simple implementation of many + of the things that `pandas.Index` is used for, and many of its operations are + faster than the equivalent pandas operations. + + For further compatibility with pandas.Index, `get_loc` (the pandas method for + looking up a single index) and `get_indexer` (the pandas method for fancy + indexing in reverse) are both aliases for `index` (which handles both cases + in OrderedSet). + + + ## Type hinting + To use type hinting features install `ordered-set-stubs` package from + [PyPI](https://pypi.org/project/ordered-set-stubs/): + + $ pip install ordered-set-stubs + + + ## Authors + + OrderedSet was implemented by Robyn Speer. Jon Crall contributed changes and + tests to make it fit the Python set API. + + + ## Comparisons + + The original implementation of OrderedSet was a [recipe posted to ActiveState + Recipes][recipe] by Raymond Hettiger, released under the MIT license. + + [recipe]: https://code.activestate.com/recipes/576694-orderedset/ + + Hettiger's implementation kept its content in a doubly-linked list referenced by a + dict. As a result, looking up an item by its index was an O(N) operation, while + deletion was O(1). + + This version makes different trade-offs for the sake of efficient lookups. Its + content is a standard Python list instead of a doubly-linked list. This + provides O(1) lookups by index at the expense of O(N) deletion, as well as + slightly faster iteration. + + In Python 3.6 and later, the built-in `dict` type is inherently ordered. If you + ignore the dictionary values, that also gives you a simple ordered set, with + fast O(1) insertion, deletion, iteration and membership testing. However, `dict` + does not provide the list-like random access features of OrderedSet. You + would have to convert it to a list in O(N) to look up the index of an entry or + look up an entry by its index. + + + ## Compatibility + + OrderedSet is automatically tested on Python 2.7, 3.4, 3.5, 3.6, and 3.7. + We've checked more informally that it works on PyPy and PyPy3. + Platform: any Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License +Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 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: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy +Requires-Python: >=2.7 +Description-Content-Type: text/markdown diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ordered-set-2.0.2/ordered_set.egg-info/SOURCES.txt new/ordered-set-3.1.1/ordered_set.egg-info/SOURCES.txt --- old/ordered-set-2.0.2/ordered_set.egg-info/SOURCES.txt 2017-04-19 20:21:54.000000000 +0200 +++ new/ordered-set-3.1.1/ordered_set.egg-info/SOURCES.txt 2019-04-25 21:07:28.000000000 +0200 @@ -1,7 +1,9 @@ MANIFEST.in MIT-LICENSE -README +README.md ordered_set.py +ordered_set.pyi +setup.cfg setup.py test.py ordered_set.egg-info/PKG-INFO diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ordered-set-2.0.2/ordered_set.py new/ordered-set-3.1.1/ordered_set.py --- old/ordered-set-2.0.2/ordered_set.py 2017-04-19 17:44:56.000000000 +0200 +++ new/ordered-set-3.1.1/ordered_set.py 2019-04-25 21:07:12.000000000 +0200 @@ -4,20 +4,19 @@ Based on a recipe originally posted to ActiveState Recipes by Raymond Hettiger, and released under the MIT license. - -Rob Speer's changes are as follows: - - - changed the content from a doubly-linked list to a regular Python list. - Seriously, who wants O(1) deletes but O(N) lookups by index? - - add() returns the index of the added item - - index() just returns the index of an item - - added a __getstate__ and __setstate__ so it can be pickled - - added __getitem__ """ -import collections +import itertools as it +from collections import deque + +try: + # Python 3 + from collections.abc import MutableSet, Sequence +except ImportError: + # Python 2.7 + from collections import MutableSet, Sequence SLICE_ALL = slice(None) -__version__ = '2.0.1' +__version__ = "3.1" def is_iterable(obj): @@ -33,14 +32,23 @@ We don't need to check for the Python 2 `unicode` type, because it doesn't have an `__iter__` attribute anyway. """ - return hasattr(obj, '__iter__') and not isinstance(obj, str) and not isinstance(obj, tuple) + return ( + hasattr(obj, "__iter__") + and not isinstance(obj, str) + and not isinstance(obj, tuple) + ) -class OrderedSet(collections.MutableSet): +class OrderedSet(MutableSet, Sequence): """ An OrderedSet is a custom MutableSet that remembers its order, so that every entry has an index that can be looked up. + + Example: + >>> OrderedSet([1, 1, 2, 3, 2]) + OrderedSet([1, 2, 3]) """ + def __init__(self, iterable=None): self.items = [] self.map = {} @@ -48,36 +56,61 @@ self |= iterable def __len__(self): + """ + Returns the number of unique elements in the ordered set + + Example: + >>> len(OrderedSet([])) + 0 + >>> len(OrderedSet([1, 2])) + 2 + """ return len(self.items) def __getitem__(self, index): """ Get the item at a given index. - If `index` is a slice, you will get back that slice of items. If it's - the slice [:], exactly the same object is returned. (If you want an - independent copy of an OrderedSet, use `OrderedSet.copy()`.) - - If `index` is an iterable, you'll get the OrderedSet of items - corresponding to those indices. This is similar to NumPy's - "fancy indexing". - """ - if index == SLICE_ALL: - return self - elif hasattr(index, '__index__') or isinstance(index, slice): + If `index` is a slice, you will get back that slice of items, as a + new OrderedSet. + + If `index` is a list or a similar iterable, you'll get a list of + items corresponding to those indices. This is similar to NumPy's + "fancy indexing". The result is not an OrderedSet because you may ask + for duplicate indices, and the number of elements returned should be + the number of elements asked for. + + Example: + >>> oset = OrderedSet([1, 2, 3]) + >>> oset[1] + 2 + """ + if isinstance(index, slice) and index == SLICE_ALL: + return self.copy() + elif is_iterable(index): + return [self.items[i] for i in index] + elif hasattr(index, "__index__") or isinstance(index, slice): result = self.items[index] if isinstance(result, list): - return OrderedSet(result) + return self.__class__(result) else: return result - elif is_iterable(index): - return OrderedSet([self.items[i] for i in index]) else: - raise TypeError("Don't know how to index an OrderedSet by %r" % - index) + raise TypeError("Don't know how to index an OrderedSet by %r" % index) def copy(self): - return OrderedSet(self) + """ + Return a shallow copy of this object. + + Example: + >>> this = OrderedSet([1, 2, 3]) + >>> other = this.copy() + >>> this == other + True + >>> this is other + False + """ + return self.__class__(self) def __getstate__(self): if len(self) == 0: @@ -98,6 +131,15 @@ self.__init__(state) def __contains__(self, key): + """ + Test if the item is in this ordered set + + Example: + >>> 1 in OrderedSet([1, 3, 2]) + True + >>> 5 in OrderedSet([1, 3, 2]) + False + """ return key in self.map def add(self, key): @@ -106,24 +148,41 @@ If `key` is already in the OrderedSet, return the index it already had. + + Example: + >>> oset = OrderedSet() + >>> oset.append(3) + 0 + >>> print(oset) + OrderedSet([3]) """ if key not in self.map: self.map[key] = len(self.items) self.items.append(key) return self.map[key] + append = add def update(self, sequence): """ Update the set with the given iterable sequence, then return the index of the last element inserted. + + Example: + >>> oset = OrderedSet([1, 2, 3]) + >>> oset.update([3, 1, 5, 1, 4]) + 4 + >>> print(oset) + OrderedSet([1, 2, 3, 5, 4]) """ item_index = None try: for item in sequence: item_index = self.add(item) except TypeError: - raise ValueError('Argument needs to be an iterable, got %s' % type(sequence)) + raise ValueError( + "Argument needs to be an iterable, got %s" % type(sequence) + ) return item_index def index(self, key): @@ -133,19 +192,33 @@ `key` can be an iterable of entries that is not a string, in which case this returns a list of indices. + + Example: + >>> oset = OrderedSet([1, 2, 3]) + >>> oset.index(2) + 1 """ if is_iterable(key): return [self.index(subkey) for subkey in key] return self.map[key] + # Provide some compatibility with pd.Index + get_loc = index + get_indexer = index + def pop(self): """ Remove and return the last element from the set. Raises KeyError if the set is empty. + + Example: + >>> oset = OrderedSet([1, 2, 3]) + >>> oset.pop() + 3 """ if not self.items: - raise KeyError('Set is empty') + raise KeyError("Set is empty") elem = self.items[-1] del self.items[-1] @@ -158,6 +231,15 @@ The MutableSet mixin uses this to implement the .remove() method, which *does* raise an error when asked to remove a non-existent item. + + Example: + >>> oset = OrderedSet([1, 2, 3]) + >>> oset.discard(2) + >>> print(oset) + OrderedSet([1, 3]) + >>> oset.discard(2) + >>> print(oset) + OrderedSet([1, 3]) """ if key in self: i = self.map[key] @@ -175,19 +257,48 @@ self.map.clear() def __iter__(self): + """ + Example: + >>> list(iter(OrderedSet([1, 2, 3]))) + [1, 2, 3] + """ return iter(self.items) def __reversed__(self): + """ + Example: + >>> list(reversed(OrderedSet([1, 2, 3]))) + [3, 2, 1] + """ return reversed(self.items) def __repr__(self): if not self: - return '%s()' % (self.__class__.__name__,) - return '%s(%r)' % (self.__class__.__name__, list(self)) + return "%s()" % (self.__class__.__name__,) + return "%s(%r)" % (self.__class__.__name__, list(self)) def __eq__(self, other): - if isinstance(other, OrderedSet): - return len(self) == len(other) and self.items == other.items + """ + Returns true if the containers have the same items. If `other` is a + Sequence, then order is checked, otherwise it is ignored. + + Example: + >>> oset = OrderedSet([1, 3, 2]) + >>> oset == [1, 3, 2] + True + >>> oset == [1, 2, 3] + False + >>> oset == [2, 3] + False + >>> oset == OrderedSet([3, 2, 1]) + False + """ + # In Python 2 deque is not a Sequence, so treat it as one for + # consistent behavior with Python 3. + if isinstance(other, (Sequence, deque)): + # Check that this OrderedSet contains the same elements, in the + # same order, as the other object. + return list(self) == list(other) try: other_as_set = set(other) except TypeError: @@ -196,3 +307,182 @@ else: return set(self) == other_as_set + def union(self, *sets): + """ + Combines all unique items. + Each items order is defined by its first appearance. + + Example: + >>> oset = OrderedSet.union(OrderedSet([3, 1, 4, 1, 5]), [1, 3], [2, 0]) + >>> print(oset) + OrderedSet([3, 1, 4, 5, 2, 0]) + >>> oset.union([8, 9]) + OrderedSet([3, 1, 4, 5, 2, 0, 8, 9]) + >>> oset | {10} + OrderedSet([3, 1, 4, 5, 2, 0, 10]) + """ + cls = self.__class__ if isinstance(self, OrderedSet) else OrderedSet + containers = map(list, it.chain([self], sets)) + items = it.chain.from_iterable(containers) + return cls(items) + + def __and__(self, other): + # the parent implementation of this is backwards + return self.intersection(other) + + def intersection(self, *sets): + """ + Returns elements in common between all sets. Order is defined only + by the first set. + + Example: + >>> oset = OrderedSet.intersection(OrderedSet([0, 1, 2, 3]), [1, 2, 3]) + >>> print(oset) + OrderedSet([1, 2, 3]) + >>> oset.intersection([2, 4, 5], [1, 2, 3, 4]) + OrderedSet([2]) + >>> oset.intersection() + OrderedSet([1, 2, 3]) + """ + cls = self.__class__ if isinstance(self, OrderedSet) else OrderedSet + if sets: + common = set.intersection(*map(set, sets)) + items = (item for item in self if item in common) + else: + items = self + return cls(items) + + def difference(self, *sets): + """ + Returns all elements that are in this set but not the others. + + Example: + >>> OrderedSet([1, 2, 3]).difference(OrderedSet([2])) + OrderedSet([1, 3]) + >>> OrderedSet([1, 2, 3]).difference(OrderedSet([2]), OrderedSet([3])) + OrderedSet([1]) + >>> OrderedSet([1, 2, 3]) - OrderedSet([2]) + OrderedSet([1, 3]) + >>> OrderedSet([1, 2, 3]).difference() + OrderedSet([1, 2, 3]) + """ + cls = self.__class__ + if sets: + other = set.union(*map(set, sets)) + items = (item for item in self if item not in other) + else: + items = self + return cls(items) + + def issubset(self, other): + """ + Report whether another set contains this set. + + Example: + >>> OrderedSet([1, 2, 3]).issubset({1, 2}) + False + >>> OrderedSet([1, 2, 3]).issubset({1, 2, 3, 4}) + True + >>> OrderedSet([1, 2, 3]).issubset({1, 4, 3, 5}) + False + """ + if len(self) > len(other): # Fast check for obvious cases + return False + return all(item in other for item in self) + + def issuperset(self, other): + """ + Report whether this set contains another set. + + Example: + >>> OrderedSet([1, 2]).issuperset([1, 2, 3]) + False + >>> OrderedSet([1, 2, 3, 4]).issuperset({1, 2, 3}) + True + >>> OrderedSet([1, 4, 3, 5]).issuperset({1, 2, 3}) + False + """ + if len(self) < len(other): # Fast check for obvious cases + return False + return all(item in self for item in other) + + def symmetric_difference(self, other): + """ + Return the symmetric difference of two OrderedSets as a new set. + That is, the new set will contain all elements that are in exactly + one of the sets. + + Their order will be preserved, with elements from `self` preceding + elements from `other`. + + Example: + >>> this = OrderedSet([1, 4, 3, 5, 7]) + >>> other = OrderedSet([9, 7, 1, 3, 2]) + >>> this.symmetric_difference(other) + OrderedSet([4, 5, 9, 2]) + """ + cls = self.__class__ if isinstance(self, OrderedSet) else OrderedSet + diff1 = cls(self).difference(other) + diff2 = cls(other).difference(self) + return diff1.union(diff2) + + def _update_items(self, items): + """ + Replace the 'items' list of this OrderedSet with a new one, updating + self.map accordingly. + """ + self.items = items + self.map = {item: idx for (idx, item) in enumerate(items)} + + def difference_update(self, *sets): + """ + Update this OrderedSet to remove items from one or more other sets. + + Example: + >>> this = OrderedSet([1, 2, 3]) + >>> this.difference_update(OrderedSet([2, 4])) + >>> print(this) + OrderedSet([1, 3]) + + >>> this = OrderedSet([1, 2, 3, 4, 5]) + >>> this.difference_update(OrderedSet([2, 4]), OrderedSet([1, 4, 6])) + >>> print(this) + OrderedSet([3, 5]) + """ + items_to_remove = set() + for other in sets: + items_to_remove |= set(other) + self._update_items([item for item in self.items if item not in items_to_remove]) + + def intersection_update(self, other): + """ + Update this OrderedSet to keep only items in another set, preserving + their order in this set. + + Example: + >>> this = OrderedSet([1, 4, 3, 5, 7]) + >>> other = OrderedSet([9, 7, 1, 3, 2]) + >>> this.intersection_update(other) + >>> print(this) + OrderedSet([1, 3, 7]) + """ + other = set(other) + self._update_items([item for item in self.items if item in other]) + + def symmetric_difference_update(self, other): + """ + Update this OrderedSet to remove items from another set, then + add items from the other set that were not present in this set. + + Example: + >>> this = OrderedSet([1, 4, 3, 5, 7]) + >>> other = OrderedSet([9, 7, 1, 3, 2]) + >>> this.symmetric_difference_update(other) + >>> print(this) + OrderedSet([4, 5, 9, 2]) + """ + items_to_add = [item for item in other if item not in self] + items_to_remove = set(other) + self._update_items( + [item for item in self.items if item not in items_to_remove] + items_to_add + ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ordered-set-2.0.2/ordered_set.pyi new/ordered-set-3.1.1/ordered_set.pyi --- old/ordered-set-2.0.2/ordered_set.pyi 1970-01-01 01:00:00.000000000 +0100 +++ new/ordered-set-3.1.1/ordered_set.pyi 2018-09-14 22:41:05.000000000 +0200 @@ -0,0 +1,41 @@ +from typing import Any, MutableSet, TypeVar, Sequence, Union, Tuple, List, Iterator, Dict, Set, Iterable + + +def is_iterable(obj: Any) -> bool: ... + + +T = TypeVar('T') + + +class OrderedSet(MutableSet[T], Sequence[T]): + def __init__(self, iterable: Iterable[T] = None) -> None: + self.map: Dict[T, int] = {} + self.items: List[T] = [] + + def __len__(self) -> int: ... + def __getitem__(self, index: Union[int, slice, Sequence[int]]) -> OrderedSet[T]: ... + def copy(self) -> OrderedSet[T]: ... + def __getstate__(self) -> Union[Tuple[None], List[T]]: ... + def __setstate__(self, state: Union[Tuple[None], List[T]]) -> None: ... + def __contains__(self, key: T) -> bool: ... + def add(self, key: T) -> int: ... + append = add + def update(self, sequence: Sequence[T]) -> int: ... + def index(self, key: Union[T, Sequence[T]]) -> int: ... + def pop(self) -> T: ... + def discard(self, key: T) -> None: ... + def clear(self) -> None: ... + def __iter__(self) -> Iterator[T]: ... + def __reversed__(self) -> List[T]: ... + def __repr__(self) -> str: ... + def __eq__(self, other: Sequence[T]) -> bool: ... + def union(self, *sets: Sequence[T]) -> OrderedSet[T]: ... + def __and__(self, other: Sequence[T]) -> OrderedSet[T]: ... + def intersection(self, *sets: Sequence[T]) -> OrderedSet[T]: ... + def difference(self, *sets: Sequence[T]) -> OrderedSet[T]: ... + def issubset(self, other: Union[Set[T], Sequence[T]]) -> bool: ... + def issuperset(self, other: Union[Set[T], Sequence[T]]) -> bool: ... + def symmetric_difference(self, other: Sequence[T]) -> OrderedSet[T]: ... + def difference_update(self, *sets: Sequence[T]) -> None: ... + def intersection_update(self, other: Sequence[T]) -> None: ... + def symmetric_difference_update(self, other: Sequence[T]) -> None: ... diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ordered-set-2.0.2/setup.cfg new/ordered-set-3.1.1/setup.cfg --- old/ordered-set-2.0.2/setup.cfg 2017-04-19 20:21:54.000000000 +0200 +++ new/ordered-set-3.1.1/setup.cfg 2019-04-25 21:07:28.000000000 +0200 @@ -1,5 +1,10 @@ +[bdist_wheel] +universal = 1 + +[metadata] +license_file = MIT-LICENSE + [egg_info] tag_build = tag_date = 0 -tag_svn_revision = 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ordered-set-2.0.2/setup.py new/ordered-set-3.1.1/setup.py --- old/ordered-set-2.0.2/setup.py 2017-04-19 18:18:01.000000000 +0200 +++ new/ordered-set-3.1.1/setup.py 2019-04-25 21:07:12.000000000 +0200 @@ -1,25 +1,35 @@ from setuptools import setup +DESCRIPTION = open('README.md').read() + setup( name="ordered-set", - version = '2.0.2', - maintainer='Luminoso Technologies, Inc.', - maintainer_email='[email protected]', - license = "MIT-LICENSE", - url = 'http://github.com/LuminosoInsight/ordered-set', - platforms = ["any"], - description = "A MutableSet that remembers its order, so that every entry has an index.", + version='3.1.1', + maintainer='Robyn Speer', + maintainer_email='[email protected]', + license="MIT-LICENSE", + url='https://github.com/LuminosoInsight/ordered-set', + platforms=["any"], + description="A MutableSet that remembers its order, so that every entry has an index.", + long_description=DESCRIPTION, + long_description_content_type='text/markdown', py_modules=['ordered_set'], package_data={'': ['MIT-LICENSE']}, include_package_data=True, - test_suite='nose.collector', - tests_require=['nose'], + tests_require=['pytest'], + python_requires='>=2.7', classifiers=[ 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', + 'Programming Language :: Python', 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: Implementation :: CPython', 'Programming Language :: Python :: Implementation :: PyPy', ] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ordered-set-2.0.2/test.py new/ordered-set-3.1.1/test.py --- old/ordered-set-2.0.2/test.py 2017-04-19 17:44:56.000000000 +0200 +++ new/ordered-set-3.1.1/test.py 2019-04-25 21:07:12.000000000 +0200 @@ -1,6 +1,11 @@ -from nose.tools import eq_, raises, assert_raises -from ordered_set import OrderedSet import pickle +import pytest +import collections +import sys +import operator +import itertools as it +import random +from ordered_set import OrderedSet def test_pickle(): @@ -17,9 +22,9 @@ def test_order(): set1 = OrderedSet('abracadabra') - eq_(len(set1), 5) - eq_(set1, OrderedSet(['a', 'b', 'r', 'c', 'd'])) - eq_(list(reversed(set1)), ['d', 'c', 'r', 'b', 'a']) + assert len(set1) == 5 + assert set1 == OrderedSet(['a', 'b', 'r', 'c', 'd']) + assert list(reversed(set1)) == ['d', 'c', 'r', 'b', 'a'] def test_binary_operations(): @@ -27,35 +32,64 @@ set2 = OrderedSet('simsalabim') assert set1 != set2 - eq_(set1 & set2, OrderedSet(['a', 'b'])) - eq_(set1 | set2, OrderedSet(['a', 'b', 'r', 'c', 'd', 's', 'i', 'm', 'l'])) - eq_(set1 - set2, OrderedSet(['r', 'c', 'd'])) + assert set1 & set2 == OrderedSet(['a', 'b']) + assert set1 | set2 == OrderedSet(['a', 'b', 'r', 'c', 'd', 's', 'i', 'm', 'l']) + assert set1 - set2 == OrderedSet(['r', 'c', 'd']) def test_indexing(): set1 = OrderedSet('abracadabra') - eq_(set1[:], set1) - eq_(set1.copy(), set1) - assert set1[:] is set1 + assert set1[:] == set1 + assert set1.copy() == set1 + assert set1 is set1 + assert set1[:] is not set1 assert set1.copy() is not set1 - eq_(set1[[1, 2]], OrderedSet(['b', 'r'])) - eq_(set1[1:3], OrderedSet(['b', 'r'])) - eq_(set1.index('b'), 1) - eq_(set1.index(['b', 'r']), [1, 2]) - try: + assert set1[[1, 2]] == OrderedSet(['b', 'r']) + assert set1[1:3] == OrderedSet(['b', 'r']) + assert set1.index('b') == 1 + assert set1.index(['b', 'r']) == [1, 2] + with pytest.raises(KeyError): set1.index('br') - assert False, "Looking up a nonexistent key should be a KeyError" - except KeyError: - pass + + +class FancyIndexTester: + """ + Make sure we can index by a NumPy ndarray, without having to import + NumPy. + """ + def __init__(self, indices): + self.indices = indices + + def __iter__(self): + return iter(self.indices) + + def __index__(self): + raise TypeError("NumPy arrays have weird __index__ methods") + + def __eq__(self, other): + # Emulate NumPy being fussy about the == operator + raise TypeError + + +def test_fancy_index_class(): + set1 = OrderedSet('abracadabra') + indexer = FancyIndexTester([1, 0, 4, 3, 0, 2]) + assert ''.join(set1[indexer]) == 'badcar' + + +def test_pandas_compat(): + set1 = OrderedSet('abracadabra') + assert set1.get_loc('b') == 1 + assert set1.get_indexer(['b', 'r']) == [1, 2] def test_tuples(): set1 = OrderedSet() tup = ('tuple', 1) set1.add(tup) - eq_(set1.index(tup), 0) - eq_(set1[0], tup) + assert set1.index(tup) == 0 + assert set1[0] == tup def test_remove(): @@ -83,11 +117,11 @@ set1.discard('a') -@raises(KeyError) def test_remove_error(): # If we .remove() an element that's not there, we get a KeyError set1 = OrderedSet('abracadabra') - set1.remove('z') + with pytest.raises(KeyError): + set1.remove('z') def test_clear(): @@ -122,5 +156,229 @@ assert elem == 'a' - assert_raises(KeyError, set1.pop) + pytest.raises(KeyError, set1.pop) + + +def test_getitem_type_error(): + set1 = OrderedSet('ab') + with pytest.raises(TypeError): + set1['a'] + + +def test_update_value_error(): + set1 = OrderedSet('ab') + with pytest.raises(ValueError): + # noinspection PyTypeChecker + set1.update(3) + + +def test_empty_repr(): + set1 = OrderedSet() + assert repr(set1) == 'OrderedSet()' + + +def test_eq_wrong_type(): + set1 = OrderedSet() + assert set1 != 2 + + +def test_ordered_equality(): + # Ordered set checks order against sequences. + assert OrderedSet([1, 2]) == OrderedSet([1, 2]) + assert OrderedSet([1, 2]) == [1, 2] + assert OrderedSet([1, 2]) == (1, 2) + assert OrderedSet([1, 2]) == collections.deque([1, 2]) + + +def test_ordered_inequality(): + # Ordered set checks order against sequences. + assert OrderedSet([1, 2]) != OrderedSet([2, 1]) + + assert OrderedSet([1, 2]) != [2, 1] + assert OrderedSet([1, 2]) != [2, 1, 1] + + assert OrderedSet([1, 2]) != (2, 1) + assert OrderedSet([1, 2]) != (2, 1, 1) + + # Note: in Python 2.7 deque does not inherit from Sequence, but __eq__ + # contains an explicit check for this case for python 2/3 compatibility. + assert OrderedSet([1, 2]) != collections.deque([2, 1]) + assert OrderedSet([1, 2]) != collections.deque([2, 2, 1]) + + +def test_comparisons(): + # Comparison operators on sets actually test for subset and superset. + assert OrderedSet([1, 2]) < OrderedSet([1, 2, 3]) + assert OrderedSet([1, 2]) > OrderedSet([1]) + + # MutableSet subclasses aren't comparable to set on 3.3. + if tuple(sys.version_info) >= (3, 4): + assert OrderedSet([1, 2]) > {1} + +def test_unordered_equality(): + # Unordered set checks order against non-sequences. + assert OrderedSet([1, 2]) == {1, 2} + assert OrderedSet([1, 2]) == frozenset([2, 1]) + + assert OrderedSet([1, 2]) == {1: 'a', 2: 'b'} + assert OrderedSet([1, 2]) == {1: 1, 2: 2}.keys() + assert OrderedSet([1, 2]) == {1: 1, 2: 2}.values() + + # Corner case: OrderedDict is not a Sequence, so we don't check for order, + # even though it does have the concept of order. + assert OrderedSet([1, 2]) == collections.OrderedDict([(2, 2), (1, 1)]) + + # Corner case: We have to treat iterators as unordered because there + # is nothing to distinguish an ordered and unordered iterator + assert OrderedSet([1, 2]) == iter([1, 2]) + assert OrderedSet([1, 2]) == iter([2, 1]) + assert OrderedSet([1, 2]) == iter([2, 1, 1]) + + +def test_unordered_inequality(): + assert OrderedSet([1, 2]) != set([]) + assert OrderedSet([1, 2]) != frozenset([2, 1, 3]) + + assert OrderedSet([1, 2]) != {2: 'b'} + assert OrderedSet([1, 2]) != {1: 1, 4: 2}.keys() + assert OrderedSet([1, 2]) != {1: 1, 2: 3}.values() + + # Corner case: OrderedDict is not a Sequence, so we don't check for order, + # even though it does have the concept of order. + assert OrderedSet([1, 2]) != collections.OrderedDict([(2, 2), (3, 1)]) + + +def allsame_(iterable, eq=operator.eq): + """ returns True of all items in iterable equal each other """ + iter_ = iter(iterable) + try: + first = next(iter_) + except StopIteration: + return True + return all(eq(first, item) for item in iter_) + + +def check_results_(results, datas, name): + """ + helper for binary operator tests. + + check that all results have the same value, but are different items. + data and name are used to indicate what sort of tests is run. + """ + if not allsame_(results): + raise AssertionError( + 'Not all same {} for {} with datas={}'.format(results, name, datas) + ) + for a, b in it.combinations(results, 2): + if not isinstance(a, (bool, int)): + assert a is not b, name + ' should all be different items' + + +def _operator_consistency_testdata(): + """ + Predefined and random data used to test operator consistency. + """ + # test case 1 + data1 = OrderedSet([5, 3, 1, 4]) + data2 = OrderedSet([1, 4]) + yield data1, data2 + + # first set is empty + data1 = OrderedSet([]) + data2 = OrderedSet([3, 1, 2]) + yield data1, data2 + + # second set is empty + data1 = OrderedSet([3, 1, 2]) + data2 = OrderedSet([]) + yield data1, data2 + + # both sets are empty + data1 = OrderedSet([]) + data2 = OrderedSet([]) + yield data1, data2 + + # random test cases + rng = random.Random(0) + a, b = 20, 20 + for _ in range(10): + data1 = OrderedSet(rng.randint(0, a) for _ in range(b)) + data2 = OrderedSet(rng.randint(0, a) for _ in range(b)) + yield data1, data2 + yield data2, data1 + + +def test_operator_consistency_isect(): + for data1, data2 in _operator_consistency_testdata(): + result1 = data1.copy() + result1.intersection_update(data2) + result2 = data1 & data2 + result3 = data1.intersection(data2) + check_results_([result1, result2, result3], datas=(data1, data2), name='isect') + + +def test_operator_consistency_difference(): + for data1, data2 in _operator_consistency_testdata(): + result1 = data1.copy() + result1.difference_update(data2) + result2 = data1 - data2 + result3 = data1.difference(data2) + check_results_( + [result1, result2, result3], datas=(data1, data2), name='difference' + ) + + +def test_operator_consistency_xor(): + for data1, data2 in _operator_consistency_testdata(): + result1 = data1.copy() + result1.symmetric_difference_update(data2) + result2 = data1 ^ data2 + result3 = data1.symmetric_difference(data2) + check_results_([result1, result2, result3], datas=(data1, data2), name='xor') + + +def test_operator_consistency_union(): + for data1, data2 in _operator_consistency_testdata(): + result1 = data1.copy() + result1.update(data2) + result2 = data1 | data2 + result3 = data1.union(data2) + check_results_([result1, result2, result3], datas=(data1, data2), name='union') + + +def test_operator_consistency_subset(): + for data1, data2 in _operator_consistency_testdata(): + result1 = data1 <= data2 + result2 = data1.issubset(data2) + result3 = set(data1).issubset(set(data2)) + check_results_([result1, result2, result3], datas=(data1, data2), name='subset') + + +def test_operator_consistency_superset(): + for data1, data2 in _operator_consistency_testdata(): + result1 = data1 >= data2 + result2 = data1.issuperset(data2) + result3 = set(data1).issuperset(set(data2)) + check_results_( + [result1, result2, result3], datas=(data1, data2), name='superset' + ) + + +def test_operator_consistency_disjoint(): + for data1, data2 in _operator_consistency_testdata(): + result1 = data1.isdisjoint(data2) + result2 = len(data1.intersection(data2)) == 0 + check_results_([result1, result2], datas=(data1, data2), name='disjoint') + + +def test_bitwise_and_consistency(): + # Specific case that was failing without explicit __and__ definition + data1 = OrderedSet([12, 13, 1, 8, 16, 15, 9, 11, 18, 6, 4, 3, 19, 17]) + data2 = OrderedSet([19, 4, 9, 3, 2, 10, 15, 17, 11, 13, 20, 6, 14, 16, 8]) + result1 = data1.copy() + result1.intersection_update(data2) + # This requires a custom & operation apparently + result2 = data1 & data2 + result3 = data1.intersection(data2) + check_results_([result1, result2, result3], datas=(data1, data2), name='isect')
