From 93092331adf7a4a4b9970258c4acbc69f13e9b7fc07ebeabf7926613d4f9a972 Mon Sep 17 00:00:00 2001 From: Matej Cepl Date: Thu, 5 Aug 2021 06:24:35 +0000 Subject: [PATCH] - Upstream fixed problems with 32bit systems (gh#MagicStack/immutables#69) so we have removed skip_32bit_tests.patch and added new solution which actually fixes the issue: test_none_collisions-32-bit.patch. OBS-URL: https://build.opensuse.org/package/show/devel:languages:python/python-immutables?expand=0&rev=15 --- python-immutables.changes | 8 ++++ python-immutables.spec | 6 +-- skip_32bit_tests.patch | 24 ----------- test_none_collisions-32-bit.patch | 71 +++++++++++++++++++++++++++++++ 4 files changed, 82 insertions(+), 27 deletions(-) delete mode 100644 skip_32bit_tests.patch create mode 100644 test_none_collisions-32-bit.patch diff --git a/python-immutables.changes b/python-immutables.changes index e91a335..43fb7c0 100644 --- a/python-immutables.changes +++ b/python-immutables.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Thu Aug 5 06:23:30 UTC 2021 - Matej Cepl + +- Upstream fixed problems with 32bit systems + (gh#MagicStack/immutables#69) so we have removed + skip_32bit_tests.patch and added new solution which actually fixes the + issue: test_none_collisions-32-bit.patch. + ------------------------------------------------------------------- Thu Apr 22 20:28:33 UTC 2021 - Dirk Müller diff --git a/python-immutables.spec b/python-immutables.spec index d7788e2..76ed3dc 100644 --- a/python-immutables.spec +++ b/python-immutables.spec @@ -25,9 +25,9 @@ Summary: Immutable collections for Python License: Apache-2.0 URL: https://github.com/MagicStack/immutables Source: https://files.pythonhosted.org/packages/source/i/immutables/immutables-%{version}.tar.gz -# PATCH-FIX-UPSTREAM skip_32bit_tests.patch gh#MagicStack/immutables#53 mcepl@suse.com -# skip failing tests on 32bit architectures -Patch0: skip_32bit_tests.patch +# PATCH-FIX-UPSTREAM test_none_collisions-32-bit.patch gh#MagicStack/immutables#69 mcepl@suse.com +# Fix test_none_collisions on 32-bit systems +Patch0: test_none_collisions-32-bit.patch BuildRequires: %{python_module devel} BuildRequires: %{python_module setuptools} BuildRequires: fdupes diff --git a/skip_32bit_tests.patch b/skip_32bit_tests.patch deleted file mode 100644 index 1067480..0000000 --- a/skip_32bit_tests.patch +++ /dev/null @@ -1,24 +0,0 @@ -Index: immutables-0.15/tests/test_none_keys.py -=================================================================== ---- immutables-0.15.orig/tests/test_none_keys.py -+++ immutables-0.15/tests/test_none_keys.py -@@ -1,8 +1,10 @@ - import unittest -+import sys - - from immutables.map import map_hash, map_mask, Map as PyMap - from immutables._testutils import HashKey - -+is_32bits = sys.maxsize <= 2**32 # 32bit-dness - - none_hash = map_hash(None) - assert(none_hash != 1) -@@ -35,6 +37,8 @@ class NoneCollision(HashKey): - class BaseNoneTest: - Map = None - -+ @unittest.skipIf(is_32bits, -+ "fail on 32bit arch, gh#MagicStack/immutables#53") - def test_none_collisions(self): - collisions = [NoneCollision('a', level) for level in range(7)] - indices = [map_mask(none_hash, shift) for shift in range(0, 32, 5)] diff --git a/test_none_collisions-32-bit.patch b/test_none_collisions-32-bit.patch new file mode 100644 index 0000000..d382d91 --- /dev/null +++ b/test_none_collisions-32-bit.patch @@ -0,0 +1,71 @@ +From a52107d45023a29fe24b97efe849915429e9bb96 Mon Sep 17 00:00:00 2001 +From: Elvis Pranskevichus +Date: Tue, 3 Aug 2021 18:04:22 -0700 +Subject: [PATCH] Fix test_none_collisions on 32-bit systems + +There are two issues at play here: + +1. Python version of `map_hash` unnecessarily performs hash truncation + even if the hash is already 32-bit wide, which potentially converts + it from signed int to unsigned long. + +2. The `test_none_collisions` test generates a collision node with + hash greater than 2^32. + +Both of these are problematic on 32-bit systems, where `sizeof(Py_hash_t)` +is 4, and so anything that doesn't fit into `Py_hash_t` gets bit-mangled, +breaking the `hash(x) != x` invariance that the test relies upon. + +Fixes: #53 +Fixes: #50 +--- + immutables/map.py | 5 ++++- + tests/test_none_keys.py | 14 +++++++++----- + 2 files changed, 13 insertions(+), 6 deletions(-) + +--- a/immutables/map.py ++++ b/immutables/map.py +@@ -19,7 +19,10 @@ _mut_id = itertools.count(1).__next__ + + def map_hash(o): + x = hash(o) +- return (x & 0xffffffff) ^ ((x >> 32) & 0xffffffff) ++ if sys.hash_info.width > 32: ++ return (x & 0xffffffff) ^ ((x >> 32) & 0xffffffff) ++ else: ++ return x + + + def map_mask(hash, shift): +--- a/tests/test_none_keys.py ++++ b/tests/test_none_keys.py +@@ -1,3 +1,4 @@ ++import ctypes + import unittest + + from immutables.map import map_hash, map_mask, Map as PyMap +@@ -6,16 +7,19 @@ from immutables._testutils import HashKe + + none_hash = map_hash(None) + assert(none_hash != 1) +-assert((none_hash >> 32) == 0) ++assert(none_hash.bit_length() <= 32) + +-not_collision = 0xffffffff & (~none_hash) ++none_hash_u = ctypes.c_size_t(none_hash).value ++not_collision = 0xffffffff & (~none_hash_u) + + mask = 0x7ffffffff +-none_collisions = [none_hash & (mask >> shift) ++none_collisions = [none_hash_u & (mask >> shift) + for shift in reversed(range(0, 32, 5))] + assert(len(none_collisions) == 7) +-none_collisions = [h | (not_collision & (mask << shift)) +- for shift, h in zip(range(5, 37, 5), none_collisions)] ++none_collisions = [ ++ ctypes.c_ssize_t(h | (not_collision & (mask << shift))).value ++ for shift, h in zip(range(5, 37, 5), none_collisions) ++] + + + class NoneCollision(HashKey):