Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-pyrsistent for openSUSE:Factory checked in at 2023-01-07 17:15:57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-pyrsistent (Old) and /work/SRC/openSUSE:Factory/.python-pyrsistent.new.1563 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pyrsistent" Sat Jan 7 17:15:57 2023 rev:12 rq:1056270 version:0.19.3 Changes: -------- --- /work/SRC/openSUSE:Factory/python-pyrsistent/python-pyrsistent.changes 2022-04-02 18:19:49.374758432 +0200 +++ /work/SRC/openSUSE:Factory/.python-pyrsistent.new.1563/python-pyrsistent.changes 2023-01-07 17:16:13.368906154 +0100 @@ -1,0 +2,19 @@ +Thu Jan 5 20:30:51 UTC 2023 - Dirk Müller <dmuel...@suse.com> + +- update to 0.19.3: + * Fix #264, add wheels and official support for Python 3.11. + * Fix #263, pmap regression in 0.19.1. Element access sometimes unreliable + after insert. + * Fix #159 (through PR #243). Pmap keys/values/items now behave more like the + corresponding Python 3 methods on dicts. Previously they returned a + materialized PVector holding the items, now they return + views instead. + * Fix #244, type for argument to PVector.delete missing. + * Fix #249, rename perf test directory to avoid tripping up automatic + discovery in more recent setuptools versions + * Fix #247, performance bug when setting elements in maps and adding elements + to sets + * Fix #248, build pure Python wheels. This is used by some installers. + * Fix #254, #258, support manylinux_2014_aarch64 wheels. + +------------------------------------------------------------------- Old: ---- pyrsistent-0.18.1.tar.gz New: ---- pyrsistent-0.19.3.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-pyrsistent.spec ++++++ --- /var/tmp/diff_new_pack.suMEFl/_old 2023-01-07 17:16:13.788908660 +0100 +++ /var/tmp/diff_new_pack.suMEFl/_new 2023-01-07 17:16:13.792908684 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-pyrsistent # -# Copyright (c) 2022 SUSE LLC +# Copyright (c) 2023 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-%{**}} %global skip_python2 1 Name: python-pyrsistent -Version: 0.18.1 +Version: 0.19.3 Release: 0 Summary: Persistent, Functional, Immutable data structures License: MIT ++++++ pyrsistent-0.18.1.tar.gz -> pyrsistent-0.19.3.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.18.1/CHANGES.txt new/pyrsistent-0.19.3/CHANGES.txt --- old/pyrsistent-0.18.1/CHANGES.txt 2022-01-14 20:50:00.000000000 +0100 +++ new/pyrsistent-0.19.3/CHANGES.txt 2022-12-29 08:50:58.000000000 +0100 @@ -1,5 +1,25 @@ Revision history ---------------- +0.19.3, 2022-12-29 + * Fix #264, add wheels and official support for Python 3.11. Thanks @hugovk for this! + +0.19.2, 2022-11-03 + * Fix #263, pmap regression in 0.19.1. Element access sometimes unreliable after insert. + Thanks @mwchase for reporting this! + +0.19.1, 2022-10-30 + * Fix #159 (through PR #243). Pmap keys/values/items now behave more like the corresponding Python 3 + methods on dicts. Previously they returned a materialized PVector holding the items, now they return + views instead. This is a slight backwards incompatibility compared to previous behaviour, hence stepping + version to 0.19. Thanks @noahbenson for this! + * Fix #244, type for argument to PVector.delete missing. @thanks dscrofts for this! + * Fix #249, rename perf test directory to avoid tripping up automatic discovery in more recent setuptools versions + * Fix #247, performance bug when setting elements in maps and adding elements to sets + * Fix #248, build pure Python wheels. This is used by some installers. Thanks @andyreagan for this! + * Fix #254, #258, support manylinux_2014_aarch64 wheels. Thanks @Aaron-Durant for this! + +0.19.0 - Never released due to issues found on test-PyPI + 0.18.1, 2022-01-14 * Add universal wheels for MacOS, thanks @ntamas for this! * Add support for Python 3.10, thanks @hugovk for this! @@ -170,6 +190,7 @@ v0.11.10, 2015-12-27, NOTE! This release contains a backwards incompatible change despite only stepping the patch version number. See below. + * Implement #74, attribute access on PClass evolver * Implement #75, lazily evaluated invariant messages by providing a callable with no arguments. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.18.1/PKG-INFO new/pyrsistent-0.19.3/PKG-INFO --- old/pyrsistent-0.18.1/PKG-INFO 2022-01-14 20:50:04.960447500 +0100 +++ new/pyrsistent-0.19.3/PKG-INFO 2022-12-29 08:51:12.178382600 +0100 @@ -1,12 +1,12 @@ Metadata-Version: 2.1 Name: pyrsistent -Version: 0.18.1 +Version: 0.19.3 Summary: Persistent/Functional/Immutable data structures -Home-page: http://github.com/tobgu/pyrsistent/ +Home-page: https://github.com/tobgu/pyrsistent/ Author: Tobias Gustafsson Author-email: tobias.l.gustafs...@gmail.com License: MIT -Platform: UNKNOWN +Project-URL: Changelog, https://pyrsistent.readthedocs.io/en/latest/changes.html Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent @@ -14,6 +14,7 @@ Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 Classifier: Programming Language :: Python :: Implementation :: PyPy Requires-Python: >=3.7 Description-Content-Type: text/x-rst @@ -25,7 +26,8 @@ :target: https://github.com/tobgu/pyrsistent/actions/workflows/tests.yaml -.. _Pyrthon: https://www.github.com/tobgu/pyrthon/ +.. _Pyrthon: https://www.github.com/tobgu/pyrthon +.. _Pyrsistent_extras: https://github.com/mingmingrr/pyrsistent-extras Pyrsistent is a number of persistent collections (by some referred to as functional data structures). Persistent in the sense that they are immutable. @@ -43,8 +45,13 @@ It aims at taking these concepts and make them as pythonic as possible so that they can be easily integrated into any python program without hassle. -If you want to go all in on persistent data structures and use literal syntax to define them in your code rather -than function calls check out Pyrthon_. +If you want use literal syntax to define them in your code rather +than function calls check out Pyrthon_. Be aware, that one is experimental, unmaintained and alpha software. + +If you cannot find the persistent data structure you're looking for here you may want to take a look at +Pyrsistent_extras_ which is maintained by @mingmingrr. If you still don't find what you're looking for please +open an issue for discussion. If we agree that functionality is missing you may want to go ahead and create +a Pull Request implement the missing functionality. Examples -------- @@ -726,6 +733,13 @@ Ben Beasley https://github.com/musicinmybrain +Noah C. Benson https://github.com/noahbenson + +dscrofts https://github.com/dscrofts + +Andy Reagan https://github.com/andyreagan + +Aaron Durant https://github.com/Aaron-Durant Contributing ------------ @@ -750,7 +764,7 @@ * Update README.rst with any new contributors and potential info needed. * Update _pyrsistent_version.py * Commit and tag with new version: `git add -u . && git commit -m 'Prepare version vX.Y.Z' && git tag -a vX.Y.Z -m 'vX.Y.Z'` -* Push commit and tags: `git push && git push --tags` +* Push commit and tags: `git push --follow-tags` * Build new release using Github actions Project status @@ -767,5 +781,3 @@ If you feel that you have a grand master plan for where you would like Pyrsistent to go and have the time to put into it please don't hesitate to discuss this with me and submit PRs for it. If all goes well I'd be more than happy to add additional maintainers to the project! - - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.18.1/README new/pyrsistent-0.19.3/README --- old/pyrsistent-0.18.1/README 2022-01-14 20:50:00.000000000 +0100 +++ new/pyrsistent-0.19.3/README 2022-12-29 08:50:58.000000000 +0100 @@ -4,7 +4,8 @@ :target: https://github.com/tobgu/pyrsistent/actions/workflows/tests.yaml -.. _Pyrthon: https://www.github.com/tobgu/pyrthon/ +.. _Pyrthon: https://www.github.com/tobgu/pyrthon +.. _Pyrsistent_extras: https://github.com/mingmingrr/pyrsistent-extras Pyrsistent is a number of persistent collections (by some referred to as functional data structures). Persistent in the sense that they are immutable. @@ -22,8 +23,13 @@ It aims at taking these concepts and make them as pythonic as possible so that they can be easily integrated into any python program without hassle. -If you want to go all in on persistent data structures and use literal syntax to define them in your code rather -than function calls check out Pyrthon_. +If you want use literal syntax to define them in your code rather +than function calls check out Pyrthon_. Be aware, that one is experimental, unmaintained and alpha software. + +If you cannot find the persistent data structure you're looking for here you may want to take a look at +Pyrsistent_extras_ which is maintained by @mingmingrr. If you still don't find what you're looking for please +open an issue for discussion. If we agree that functionality is missing you may want to go ahead and create +a Pull Request implement the missing functionality. Examples -------- @@ -705,6 +711,13 @@ Ben Beasley https://github.com/musicinmybrain +Noah C. Benson https://github.com/noahbenson + +dscrofts https://github.com/dscrofts + +Andy Reagan https://github.com/andyreagan + +Aaron Durant https://github.com/Aaron-Durant Contributing ------------ @@ -729,7 +742,7 @@ * Update README.rst with any new contributors and potential info needed. * Update _pyrsistent_version.py * Commit and tag with new version: `git add -u . && git commit -m 'Prepare version vX.Y.Z' && git tag -a vX.Y.Z -m 'vX.Y.Z'` -* Push commit and tags: `git push && git push --tags` +* Push commit and tags: `git push --follow-tags` * Build new release using Github actions Project status diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.18.1/README.rst new/pyrsistent-0.19.3/README.rst --- old/pyrsistent-0.18.1/README.rst 2022-01-14 20:50:00.000000000 +0100 +++ new/pyrsistent-0.19.3/README.rst 2022-12-29 08:50:58.000000000 +0100 @@ -4,7 +4,8 @@ :target: https://github.com/tobgu/pyrsistent/actions/workflows/tests.yaml -.. _Pyrthon: https://www.github.com/tobgu/pyrthon/ +.. _Pyrthon: https://www.github.com/tobgu/pyrthon +.. _Pyrsistent_extras: https://github.com/mingmingrr/pyrsistent-extras Pyrsistent is a number of persistent collections (by some referred to as functional data structures). Persistent in the sense that they are immutable. @@ -22,8 +23,13 @@ It aims at taking these concepts and make them as pythonic as possible so that they can be easily integrated into any python program without hassle. -If you want to go all in on persistent data structures and use literal syntax to define them in your code rather -than function calls check out Pyrthon_. +If you want use literal syntax to define them in your code rather +than function calls check out Pyrthon_. Be aware, that one is experimental, unmaintained and alpha software. + +If you cannot find the persistent data structure you're looking for here you may want to take a look at +Pyrsistent_extras_ which is maintained by @mingmingrr. If you still don't find what you're looking for please +open an issue for discussion. If we agree that functionality is missing you may want to go ahead and create +a Pull Request implement the missing functionality. Examples -------- @@ -705,6 +711,13 @@ Ben Beasley https://github.com/musicinmybrain +Noah C. Benson https://github.com/noahbenson + +dscrofts https://github.com/dscrofts + +Andy Reagan https://github.com/andyreagan + +Aaron Durant https://github.com/Aaron-Durant Contributing ------------ @@ -729,7 +742,7 @@ * Update README.rst with any new contributors and potential info needed. * Update _pyrsistent_version.py * Commit and tag with new version: `git add -u . && git commit -m 'Prepare version vX.Y.Z' && git tag -a vX.Y.Z -m 'vX.Y.Z'` -* Push commit and tags: `git push && git push --tags` +* Push commit and tags: `git push --follow-tags` * Build new release using Github actions Project status diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.18.1/_pyrsistent_version.py new/pyrsistent-0.19.3/_pyrsistent_version.py --- old/pyrsistent-0.18.1/_pyrsistent_version.py 2022-01-14 20:50:00.000000000 +0100 +++ new/pyrsistent-0.19.3/_pyrsistent_version.py 2022-12-29 08:50:58.000000000 +0100 @@ -1 +1 @@ -__version__ = '0.18.1' +__version__ = '0.19.3' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.18.1/pyrsistent/_immutable.py new/pyrsistent-0.19.3/pyrsistent/_immutable.py --- old/pyrsistent-0.18.1/pyrsistent/_immutable.py 2022-01-14 20:50:00.000000000 +0100 +++ new/pyrsistent-0.19.3/pyrsistent/_immutable.py 2022-12-29 08:50:58.000000000 +0100 @@ -60,14 +60,9 @@ return '' - verbose_string = "" - if sys.version_info < (3, 7): - # Verbose is no longer supported in Python 3.7 - verbose_string = ", verbose={verbose}".format(verbose=verbose) - quoted_members = ', '.join("'%s'" % m for m in members) template = """ -class {class_name}(namedtuple('ImmutableBase', [{quoted_members}]{verbose_string})): +class {class_name}(namedtuple('ImmutableBase', [{quoted_members}])): __slots__ = tuple() def __repr__(self): @@ -87,7 +82,6 @@ """.format(quoted_members=quoted_members, member_set="set([%s])" % quoted_members if quoted_members else 'set()', frozen_member_test=frozen_member_test(), - verbose_string=verbose_string, class_name=name) if verbose: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.18.1/pyrsistent/_pmap.py new/pyrsistent-0.19.3/pyrsistent/_pmap.py --- old/pyrsistent-0.18.1/pyrsistent/_pmap.py 2022-01-14 20:50:00.000000000 +0100 +++ new/pyrsistent-0.19.3/pyrsistent/_pmap.py 2022-12-29 08:50:58.000000000 +0100 @@ -3,6 +3,105 @@ from pyrsistent._pvector import pvector from pyrsistent._transformations import transform +class PMapView: + """View type for the persistent map/dict type `PMap`. + + Provides an equivalent of Python's built-in `dict_values` and `dict_items` + types that result from expreessions such as `{}.values()` and + `{}.items()`. The equivalent for `{}.keys()` is absent because the keys are + instead represented by a `PSet` object, which can be created in `O(1)` time. + + The `PMapView` class is overloaded by the `PMapValues` and `PMapItems` + classes which handle the specific case of values and items, respectively + + Parameters + ---------- + m : mapping + The mapping/dict-like object of which a view is to be created. This + should generally be a `PMap` object. + """ + # The public methods that use the above. + def __init__(self, m): + # Make sure this is a persistnt map + if not isinstance(m, PMap): + # We can convert mapping objects into pmap objects, I guess (but why?) + if isinstance(m, Mapping): + m = pmap(m) + else: + raise TypeError("PViewMap requires a Mapping object") + object.__setattr__(self, '_map', m) + + def __len__(self): + return len(self._map) + + def __setattr__(self, k, v): + raise TypeError("%s is immutable" % (type(self),)) + + def __reversed__(self): + raise TypeError("Persistent maps are not reversible") + +class PMapValues(PMapView): + """View type for the values of the persistent map/dict type `PMap`. + + Provides an equivalent of Python's built-in `dict_values` type that result + from expreessions such as `{}.values()`. See also `PMapView`. + + Parameters + ---------- + m : mapping + The mapping/dict-like object of which a view is to be created. This + should generally be a `PMap` object. + """ + def __iter__(self): + return self._map.itervalues() + + def __contains__(self, arg): + return arg in self._map.itervalues() + + # The str and repr methods imitate the dict_view style currently. + def __str__(self): + return f"pmap_values({list(iter(self))})" + + def __repr__(self): + return f"pmap_values({list(iter(self))})" + + def __eq__(self, x): + # For whatever reason, dict_values always seem to return False for == + # (probably it's not implemented), so we mimic that. + if x is self: return True + else: return False + +class PMapItems(PMapView): + """View type for the items of the persistent map/dict type `PMap`. + + Provides an equivalent of Python's built-in `dict_items` type that result + from expreessions such as `{}.items()`. See also `PMapView`. + + Parameters + ---------- + m : mapping + The mapping/dict-like object of which a view is to be created. This + should generally be a `PMap` object. + """ + def __iter__(self): + return self._map.iteritems() + + def __contains__(self, arg): + try: (k,v) = arg + except Exception: return False + return k in self._map and self._map[k] == v + + # The str and repr methods mitate the dict_view style currently. + def __str__(self): + return f"pmap_items({list(iter(self))})" + + def __repr__(self): + return f"pmap_items({list(iter(self))})" + + def __eq__(self, x): + if x is self: return True + elif not isinstance(x, type(self)): return False + else: return self._map == x._map class PMap(object): """ @@ -89,6 +188,12 @@ def __iter__(self): return self.iterkeys() + # If this method is not defined, then reversed(pmap) will attempt to reverse + # the map using len() and getitem, usually resulting in a mysterious + # KeyError. + def __reversed__(self): + raise TypeError("Persistent maps are not reversible") + def __getattr__(self, key): try: return self[key] @@ -115,13 +220,14 @@ yield k, v def values(self): - return pvector(self.itervalues()) + return PMapValues(self) def keys(self): - return pvector(self.iterkeys()) + from ._pset import PSet + return PSet(self) def items(self): - return pvector(self.iteritems()) + return PMapItems(self) def __len__(self): return self._size @@ -296,11 +402,9 @@ self.set(key, val) def set(self, key, val): - if len(self._buckets_evolver) < 0.67 * self._size: - self._reallocate(2 * len(self._buckets_evolver)) - kv = (key, val) index, bucket = PMap._get_bucket(self._buckets_evolver, key) + reallocation_required = len(self._buckets_evolver) < 0.67 * self._size if bucket: for k, v in bucket: if k == key: @@ -310,17 +414,28 @@ return self + # Only check and perform reallocation if not replacing an existing value. + # This is a performance tweak, see #247. + if reallocation_required: + self._reallocate() + return self.set(key, val) + new_bucket = [kv] new_bucket.extend(bucket) self._buckets_evolver[index] = new_bucket self._size += 1 else: + if reallocation_required: + self._reallocate() + return self.set(key, val) + self._buckets_evolver[index] = [kv] self._size += 1 return self - def _reallocate(self, new_size): + def _reallocate(self): + new_size = 2 * len(self._buckets_evolver) new_list = new_size * [None] buckets = self._buckets_evolver.persistent() for k, v in chain.from_iterable(x for x in buckets if x): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.18.1/pyrsistent/_toolz.py new/pyrsistent-0.19.3/pyrsistent/_toolz.py --- old/pyrsistent-0.18.1/pyrsistent/_toolz.py 2022-01-14 20:50:00.000000000 +0100 +++ new/pyrsistent-0.19.3/pyrsistent/_toolz.py 2022-12-29 08:50:58.000000000 +0100 @@ -4,7 +4,7 @@ See https://github.com/pytoolz/toolz/. -toolz is relased under BSD licence. Below is the licence text +toolz is released under BSD licence. Below is the licence text from toolz as it appeared when copying the code. -------------------------------------------------------------- @@ -72,7 +72,7 @@ 0 >>> get_in(['y'], {}, no_default=True) Traceback (most recent call last): - ... + ... KeyError: 'y' """ try: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.18.1/pyrsistent/typing.pyi new/pyrsistent-0.19.3/pyrsistent/typing.pyi --- old/pyrsistent-0.18.1/pyrsistent/typing.pyi 2022-01-14 20:50:00.000000000 +0100 +++ new/pyrsistent-0.19.3/pyrsistent/typing.pyi 2022-12-29 08:50:58.000000000 +0100 @@ -68,7 +68,7 @@ def __len__(self) -> int: ... def __mul__(self, other: PVector[T]) -> PVector[T]: ... def append(self, val: T) -> PVector[T]: ... - def delete(self, index: int, stop: Optional[int]) -> PVector[T]: ... + def delete(self, index: int, stop: Optional[int] = None) -> PVector[T]: ... def evolver(self) -> PVectorEvolver[T]: ... def extend(self, obj: Iterable[T]) -> PVector[T]: ... def tolist(self) -> List[T]: ... diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.18.1/pyrsistent.egg-info/PKG-INFO new/pyrsistent-0.19.3/pyrsistent.egg-info/PKG-INFO --- old/pyrsistent-0.18.1/pyrsistent.egg-info/PKG-INFO 2022-01-14 20:50:04.000000000 +0100 +++ new/pyrsistent-0.19.3/pyrsistent.egg-info/PKG-INFO 2022-12-29 08:51:12.000000000 +0100 @@ -1,12 +1,12 @@ Metadata-Version: 2.1 Name: pyrsistent -Version: 0.18.1 +Version: 0.19.3 Summary: Persistent/Functional/Immutable data structures -Home-page: http://github.com/tobgu/pyrsistent/ +Home-page: https://github.com/tobgu/pyrsistent/ Author: Tobias Gustafsson Author-email: tobias.l.gustafs...@gmail.com License: MIT -Platform: UNKNOWN +Project-URL: Changelog, https://pyrsistent.readthedocs.io/en/latest/changes.html Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent @@ -14,6 +14,7 @@ Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 Classifier: Programming Language :: Python :: Implementation :: PyPy Requires-Python: >=3.7 Description-Content-Type: text/x-rst @@ -25,7 +26,8 @@ :target: https://github.com/tobgu/pyrsistent/actions/workflows/tests.yaml -.. _Pyrthon: https://www.github.com/tobgu/pyrthon/ +.. _Pyrthon: https://www.github.com/tobgu/pyrthon +.. _Pyrsistent_extras: https://github.com/mingmingrr/pyrsistent-extras Pyrsistent is a number of persistent collections (by some referred to as functional data structures). Persistent in the sense that they are immutable. @@ -43,8 +45,13 @@ It aims at taking these concepts and make them as pythonic as possible so that they can be easily integrated into any python program without hassle. -If you want to go all in on persistent data structures and use literal syntax to define them in your code rather -than function calls check out Pyrthon_. +If you want use literal syntax to define them in your code rather +than function calls check out Pyrthon_. Be aware, that one is experimental, unmaintained and alpha software. + +If you cannot find the persistent data structure you're looking for here you may want to take a look at +Pyrsistent_extras_ which is maintained by @mingmingrr. If you still don't find what you're looking for please +open an issue for discussion. If we agree that functionality is missing you may want to go ahead and create +a Pull Request implement the missing functionality. Examples -------- @@ -726,6 +733,13 @@ Ben Beasley https://github.com/musicinmybrain +Noah C. Benson https://github.com/noahbenson + +dscrofts https://github.com/dscrofts + +Andy Reagan https://github.com/andyreagan + +Aaron Durant https://github.com/Aaron-Durant Contributing ------------ @@ -750,7 +764,7 @@ * Update README.rst with any new contributors and potential info needed. * Update _pyrsistent_version.py * Commit and tag with new version: `git add -u . && git commit -m 'Prepare version vX.Y.Z' && git tag -a vX.Y.Z -m 'vX.Y.Z'` -* Push commit and tags: `git push && git push --tags` +* Push commit and tags: `git push --follow-tags` * Build new release using Github actions Project status @@ -767,5 +781,3 @@ If you feel that you have a grand master plan for where you would like Pyrsistent to go and have the time to put into it please don't hesitate to discuss this with me and submit PRs for it. If all goes well I'd be more than happy to add additional maintainers to the project! - - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.18.1/setup.py new/pyrsistent-0.19.3/setup.py --- old/pyrsistent-0.18.1/setup.py 2022-01-14 20:50:00.000000000 +0100 +++ new/pyrsistent-0.19.3/setup.py 2022-12-29 08:50:58.000000000 +0100 @@ -15,7 +15,7 @@ readme = "Persistent collections, see https://github.com/tobgu/pyrsistent/ for details." extensions = [] -if platform.python_implementation() == 'CPython': +if platform.python_implementation() == 'CPython' and os.getenv("PYRSISTENT_SKIP_EXTENSION") is None: extensions = [Extension('pvectorc', sources=['pvectorcmodule.c'])] needs_pytest = {'pytest', 'test', 'ptr'}.intersection(sys.argv) @@ -57,7 +57,10 @@ long_description_content_type='text/x-rst', author='Tobias Gustafsson', author_email='tobias.l.gustafs...@gmail.com', - url='http://github.com/tobgu/pyrsistent/', + url='https://github.com/tobgu/pyrsistent/', + project_urls={ + 'Changelog': 'https://pyrsistent.readthedocs.io/en/latest/changes.html', + }, license='MIT', license_files=['LICENSE.mit'], py_modules=['_pyrsistent_version'], @@ -69,6 +72,7 @@ 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', 'Programming Language :: Python :: Implementation :: PyPy', ], test_suite='tests', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.18.1/tests/map_test.py new/pyrsistent-0.19.3/tests/map_test.py --- old/pyrsistent-0.18.1/tests/map_test.py 2022-01-14 20:50:00.000000000 +0100 +++ new/pyrsistent-0.19.3/tests/map_test.py 2022-12-29 08:50:58.000000000 +0100 @@ -4,6 +4,7 @@ from pyrsistent import pmap, m, PVector import pickle + def test_instance_of_hashable(): assert isinstance(m(), Hashable) @@ -18,8 +19,8 @@ def test_empty_initialization(): - map = pmap() - assert len(map) == 0 + a_map = pmap() + assert len(a_map) == 0 def test_initialization_with_one_element(): @@ -54,26 +55,35 @@ def test_various_iterations(): - assert set(['a', 'b']) == set(m(a=1, b=2)) + assert {'a', 'b'} == set(m(a=1, b=2)) assert ['a', 'b'] == sorted(m(a=1, b=2).keys()) - assert isinstance(m().keys(), PVector) - assert set([1, 2]) == set(m(a=1, b=2).itervalues()) + assert {1, 2} == set(m(a=1, b=2).itervalues()) assert [1, 2] == sorted(m(a=1, b=2).values()) - assert isinstance(m().values(), PVector) - assert set([('a', 1), ('b', 2)]) == set(m(a=1, b=2).iteritems()) - assert set([('a', 1), ('b', 2)]) == set(m(a=1, b=2).items()) - assert isinstance(m().items(), PVector) + assert {('a', 1), ('b', 2)} == set(m(a=1, b=2).iteritems()) + assert {('a', 1), ('b', 2)} == set(m(a=1, b=2).items()) + + pm = pmap({k:k for k in range(100)}) + assert len(pm) == len(pm.keys()) + assert len(pm) == len(pm.values()) + assert len(pm) == len(pm.items()) + ks = pm.keys() + assert all(k in pm for k in ks) + assert all(k in ks for k in ks) + us = pm.items() + assert all(pm[k] == v for (k,v) in us) + vs = pm.values() + assert all(v in vs for v in vs) def test_initialization_with_two_elements(): - map = pmap({'a': 2, 'b': 3}) - assert len(map) == 2 - assert map['a'] == 2 - assert map['b'] == 3 + map1 = pmap({'a': 2, 'b': 3}) + assert len(map1) == 2 + assert map1['a'] == 2 + assert map1['b'] == 3 - map2 = map.remove('a') + map2 = map1.remove('a') assert 'a' not in map2 assert map2['b'] == 3 @@ -243,9 +253,11 @@ def test_addition(): assert m(x=1, y=2) + m(y=3, z=4) == m(x=1, y=3, z=4) + def test_union_operator(): assert m(x=1, y=2) | m(y=3, z=4) == m(x=1, y=3, z=4) + def test_transform_base_case(): # Works as set when called with only one key x = m(a=1, b=2) @@ -280,39 +292,39 @@ dummy3 = HashDummy() dummy4 = HashDummy() - map = pmap({dummy1: 1, dummy2: 2, dummy3: 3}) - assert map[dummy1] == 1 - assert map[dummy2] == 2 - assert map[dummy3] == 3 - assert dummy4 not in map + map1 = pmap({dummy1: 1, dummy2: 2, dummy3: 3}) + assert map1[dummy1] == 1 + assert map1[dummy2] == 2 + assert map1[dummy3] == 3 + assert dummy4 not in map1 keys = set() values = set() - for k, v in map.iteritems(): + for k, v in map1.iteritems(): keys.add(k) values.add(v) - assert keys == set([dummy1, dummy2, dummy3]) - assert values == set([1, 2, 3]) + assert keys == {dummy1, dummy2, dummy3} + assert values == {1, 2, 3} - map2 = map.set(dummy1, 11) + map2 = map1.set(dummy1, 11) assert map2[dummy1] == 11 # Re-use existing structure when inserted element is the same assert map2.set(dummy1, 11) is map2 - map3 = map.set('a', 22) + map3 = map1.set('a', 22) assert map3['a'] == 22 assert map3[dummy3] == 3 # Remove elements - map4 = map.discard(dummy2) + map4 = map1.discard(dummy2) assert len(map4) == 2 assert map4[dummy1] == 1 assert dummy2 not in map4 assert map4[dummy3] == 3 - assert map.discard(dummy4) is map + assert map1.discard(dummy4) is map1 # Empty map handling empty_map = map4.remove(dummy1).remove(dummy3) @@ -321,19 +333,19 @@ def test_bitmap_indexed_iteration(): - map = pmap({'a': 2, 'b': 1}) + a_map = pmap({'a': 2, 'b': 1}) keys = set() values = set() count = 0 - for k, v in map.iteritems(): + for k, v in a_map.iteritems(): count += 1 keys.add(k) values.add(v) assert count == 2 - assert keys == set(['a', 'b']) - assert values == set([2, 1]) + assert keys == {'a', 'b'} + assert values == {2, 1} def test_iteration_with_many_elements(): @@ -348,12 +360,12 @@ # those properly as well init_dict[hash_dummy1] = 12345 init_dict[hash_dummy2] = 54321 - map = pmap(init_dict) + a_map = pmap(init_dict) actual_values = set() actual_keys = set() - for k, v in map.iteritems(): + for k, v in a_map.iteritems(): actual_values.add(v) actual_keys.add(k) @@ -369,6 +381,7 @@ assert m(a=1) assert not m() + def test_update_with(): assert m(a=1).update_with(add, m(a=2, b=4)) == m(a=3, b=4) assert m(a=1).update_with(lambda l, r: l, m(a=2, b=4)) == m(a=1, b=4) @@ -388,7 +401,7 @@ def test_set_with_relocation(): - x = pmap({'a':1000}, pre_size=1) + x = pmap({'a': 1000}, pre_size=1) x = x.set('b', 3000) x = x.set('c', 4000) x = x.set('d', 5000) @@ -490,6 +503,17 @@ weakref.ref(m(a=1)) +def test_insert_and_get_many_elements(): + # This test case triggers reallocation of the underlying bucket structure. + a_map = m() + for x in range(1000): + a_map = a_map.set(str(x), x) + + assert len(a_map) == 1000 + for x in range(1000): + assert a_map[str(x)] == x, x + + def test_iterable(): """ PMaps can be created from iterables even though they can't be len() hinted.