From 5ae0915cc9a314f446bf4baa3b3001253d39a158 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Mon, 24 Nov 2025 15:51:33 +0100 Subject: [PATCH 1/2] test_hashlib: better handle support for SHA3 It's possible that the SSL library supports only SHA3 algo and doesn't have SHAKE one. The current test wrongly detect this and set both HASH and HASHXOF to None expecting to have the extra SHA3 attributes present but this should only be true for SHAKE algo. To better handle this, move the HASH condition to a dedicated try-expect condition and check if HASHXOF is None in the relevant code effectively checking if SHA3 is supported by the SSL library but SHAKE algo needs to use the sha3module one. Signed-off-by: Christian Marangi --- Lib/test/test_hashlib.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py index 33845d8a9e2651..fa99baa4a42c61 100644 --- a/Lib/test/test_hashlib.py +++ b/Lib/test/test_hashlib.py @@ -40,9 +40,13 @@ openssl_hashlib = import_fresh_module('hashlib', fresh=['_hashlib']) try: - from _hashlib import HASH, HASHXOF, openssl_md_meth_names, get_fips_mode + from _hashlib import HASH except ImportError: HASH = None + +try: + from _hashlib import HASHXOF, openssl_md_meth_names, get_fips_mode +except ImportError: HASHXOF = None openssl_md_meth_names = frozenset() @@ -631,9 +635,14 @@ def check_sha3(self, name, capacity, rate, suffix): constructors = self.constructors_to_test[name] for hash_object_constructor in constructors: m = hash_object_constructor() - if HASH is not None and isinstance(m, HASH): - # _hashopenssl's variant does not have extra SHA3 attributes - continue + if name.startswith('shake_'): + if HASHXOF is not None and isinstance(m, HASHXOF): + # _hashopenssl's variant does not have extra SHA3 attributes + continue + else: + if HASH is not None and isinstance(m, HASH): + # _hashopenssl's variant does not have extra SHA3 attributes + continue self.assertEqual(capacity + rate, 1600) self.assertEqual(m._capacity_bits, capacity) self.assertEqual(m._rate_bits, rate) @@ -1156,7 +1165,8 @@ def test_disallow_instantiation(self): def test_hash_disallow_instantiation(self): # internal types like _hashlib.HASH are not constructable support.check_disallow_instantiation(self, HASH) - support.check_disallow_instantiation(self, HASHXOF) + if HASHXOF is not None: + support.check_disallow_instantiation(self, HASHXOF) def test_readonly_types(self): for algorithm, constructors in self.constructors_to_test.items(): From a30cf41994de4dcc0b02caa93e11a18eb3213a0e Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Mon, 24 Nov 2025 16:58:55 +0000 Subject: [PATCH 2/2] rework the conditional import for all its attrs --- Lib/test/test_hashlib.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py index fa99baa4a42c61..489bb049d2fadb 100644 --- a/Lib/test/test_hashlib.py +++ b/Lib/test/test_hashlib.py @@ -40,16 +40,15 @@ openssl_hashlib = import_fresh_module('hashlib', fresh=['_hashlib']) try: - from _hashlib import HASH + import _hashlib except ImportError: - HASH = None - -try: - from _hashlib import HASHXOF, openssl_md_meth_names, get_fips_mode -except ImportError: - HASHXOF = None - openssl_md_meth_names = frozenset() - + _hashlib = None +# The extension module may exist but only define some of these. gh-141907 +HASH = getattr(_hashlib, 'HASH', None) +HASHXOF = getattr(_hashlib, 'HASHXOF', None) +openssl_md_meth_names = getattr(_hashlib, 'openssl_md_meth_names', frozenset()) +get_fips_mode = getattr(_hashlib, 'get_fips_mode', None) +if not get_fips_mode: def get_fips_mode(): return 0