From 361201327bb146d8a504b2bea0c7c5c50ec7fcc5 Mon Sep 17 00:00:00 2001 From: Benjamin A. Beasley Date: Jan 14 2022 20:14:11 +0000 Subject: Make pyrsistent._pmap doctests order-insensitive This is the fix merged upstream for RHBZ#2040164. Stop skipping affected doctests. --- diff --git a/239.patch b/239.patch new file mode 100644 index 0000000..b66d54a --- /dev/null +++ b/239.patch @@ -0,0 +1,145 @@ +From 70f3f3c87fcb254373f54011270fbe40b6507a0d Mon Sep 17 00:00:00 2001 +From: "Benjamin A. Beasley" +Date: Thu, 13 Jan 2022 20:30:54 -0500 +Subject: [PATCH 1/2] Make pyrsistent._pmap doctests order-insensitive +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This keeps them from failing if CPython’s hashing algorithms change, +fixing #238. +--- + pyrsistent/_pmap.py | 48 ++++++++++++++++++++++----------------------- + 1 file changed, 24 insertions(+), 24 deletions(-) + +diff --git a/pyrsistent/_pmap.py b/pyrsistent/_pmap.py +index 81d99c0..056d478 100644 +--- a/pyrsistent/_pmap.py ++++ b/pyrsistent/_pmap.py +@@ -31,12 +31,12 @@ class PMap(object): + >>> m1 = m(a=1, b=3) + >>> m2 = m1.set('c', 3) + >>> m3 = m2.remove('a') +- >>> m1 +- pmap({'b': 3, 'a': 1}) +- >>> m2 +- pmap({'c': 3, 'b': 3, 'a': 1}) +- >>> m3 +- pmap({'c': 3, 'b': 3}) ++ >>> m1 == {'a': 1, 'b': 3} ++ True ++ >>> m2 == {'a': 1, 'b': 3, 'c': 3} ++ True ++ >>> m3 == {'b': 3, 'c': 3} ++ True + >>> m3['c'] + 3 + >>> m3.c +@@ -171,12 +171,12 @@ def set(self, key, val): + >>> m1 = m(a=1, b=2) + >>> m2 = m1.set('a', 3) + >>> m3 = m1.set('c' ,4) +- >>> m1 +- pmap({'b': 2, 'a': 1}) +- >>> m2 +- pmap({'b': 2, 'a': 3}) +- >>> m3 +- pmap({'c': 4, 'b': 2, 'a': 1}) ++ >>> m1 == {'a': 1, 'b': 2} ++ True ++ >>> m2 == {'a': 3, 'b': 2} ++ True ++ >>> m3 == {'a': 1, 'b': 2, 'c': 4} ++ True + """ + return self.evolver().set(key, val).persistent() + +@@ -213,8 +213,8 @@ def update(self, *maps): + maps the rightmost (last) value is inserted. + + >>> m1 = m(a=1, b=2) +- >>> m1.update(m(a=2, c=3), {'a': 17, 'd': 35}) +- pmap({'c': 3, 'b': 2, 'a': 17, 'd': 35}) ++ >>> m1.update(m(a=2, c=3), {'a': 17, 'd': 35}) == {'a': 17, 'b': 2, 'c': 3, 'd': 35} ++ True + """ + return self.update_with(lambda l, r: r, *maps) + +@@ -225,8 +225,8 @@ def update_with(self, update_fn, *maps): + + >>> from operator import add + >>> m1 = m(a=1, b=2) +- >>> m1.update_with(add, m(a=2)) +- pmap({'b': 2, 'a': 3}) ++ >>> m1.update_with(add, m(a=2)) == {'a': 3, 'b': 2} ++ True + + The reverse behaviour of the regular merge. Keep the leftmost element instead of the rightmost. + +@@ -381,15 +381,15 @@ def evolver(self): + + The underlying pmap remains the same: + +- >>> m1 +- pmap({'b': 2, 'a': 1}) ++ >>> m1 == {'a': 1, 'b': 2} ++ True + + The changes are kept in the evolver. An updated pmap can be created using the + persistent() function on the evolver. + + >>> m2 = e.persistent() +- >>> m2 +- pmap({'c': 3, 'b': 2}) ++ >>> m2 == {'b': 2, 'c': 3} ++ True + + The new pmap will share data with the original pmap in the same way that would have + been done if only using operations on the pmap. +@@ -442,8 +442,8 @@ def pmap(initial={}, pre_size=0): + may have a positive performance impact in the cases where you know beforehand that a large number of elements + will be inserted into the map eventually since it will reduce the number of reallocations required. + +- >>> pmap({'a': 13, 'b': 14}) +- pmap({'b': 14, 'a': 13}) ++ >>> pmap({'a': 13, 'b': 14}) == {'a': 13, 'b': 14} ++ True + """ + if not initial and pre_size == 0: + return _EMPTY_PMAP +@@ -455,7 +455,7 @@ def m(**kwargs): + """ + Creates a new persistent map. Inserts all key value arguments into the newly created map. + +- >>> m(a=13, b=14) +- pmap({'b': 14, 'a': 13}) ++ >>> m(a=13, b=14) == {'a': 13, 'b': 14} ++ True + """ + return pmap(kwargs) + +From e09ed69b32b8c5ab139a32e154ebe6e6a3e5744e Mon Sep 17 00:00:00 2001 +From: "Benjamin A. Beasley" +Date: Thu, 13 Jan 2022 20:33:21 -0500 +Subject: [PATCH 2/2] No longer need to set PYTHONHASHSEED=0 + +Now that there are no doctests sensitive to string keying order, +randomized hashing will not cause doctest failures. +--- + tox.ini | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/tox.ini b/tox.ini +index b77d93b..f05caeb 100644 +--- a/tox.ini ++++ b/tox.ini +@@ -44,9 +44,6 @@ changedir = . + commands = python tests/memory_profiling.py + + [testenv:doctest38] +-# Need to disable the random hashing or all docs printing a map with more than +-# one item in it will be flaky. +-setenv = PYTHONHASHSEED=0 + basepython = python3.8 + deps = pytest + changedir = . diff --git a/python-pyrsistent.spec b/python-pyrsistent.spec index 16423af..5608d9b 100644 --- a/python-pyrsistent.spec +++ b/python-pyrsistent.spec @@ -16,6 +16,10 @@ Source0: %{url}/archive/v%{version}/pyrsistent-%{version}.tar.gz # Relax dependencies specified in setup.py (allow newer pytest/hypothesis) Patch0: 00-relax-dependencies.patch +# Make pyrsistent._pmap doctests order-insensitive +# https://github.com/tobgu/pyrsistent/issues/238 +# https://bugzilla.redhat.com/show_bug.cgi?id=2040164 +Patch1: %{url}/pull/239.patch BuildRequires: python3-devel @@ -136,11 +140,8 @@ PYTHONPATH="${PWD}" %make_build -C docs latex SPHINXOPTS='-n %{?_smp_mflags}' %check %pytest # PMap order changes in Python 3.11a3, causing a doctest failure -# https://github.com/tobgu/pyrsistent/issues/238 -# https://bugzilla.redhat.com/show_bug.cgi?id=2040164 # See tox.ini: -env PYTHONHASHSEED=0 %pytest --doctest-modules pyrsistent \ - -k 'not pyrsistent._pmap.PMap.update' +%pytest --doctest-modules pyrsistent %files -n python3-pyrsistent -f %{pyproject_files}