.. index:: single: OpenSSL; (use in module hashlib)
Constructors for hash algorithms that are always present in this module are
-:func:`sha1`, :func:`sha224`, :func:`sha256`, :func:`sha384`, :func:`sha512`,
-:func:`sha3_224`, :func:`sha3_256`, :func:`sha3_384`, :func:`sha3_512`,
-:func:`shake_128`, :func:`shake_256`, :func:`blake2b`, and :func:`blake2s`.
-:func:`md5` is normally available as well, though it may be missing or blocked
-if you are using a rare "FIPS compliant" build of Python.
-These correspond to :data:`algorithms_guaranteed`.
+:func:`md5`, :func:`sha1`, :func:`sha224`, :func:`sha256`, :func:`sha384`,
+:func:`sha512`, :func:`sha3_224`, :func:`sha3_256`, :func:`sha3_384`,
+:func:`sha3_512`, :func:`shake_128`, :func:`shake_256`, :func:`blake2b`, and
+:func:`blake2s`. These correspond to :data:`algorithms_guaranteed`.
+
+Any of these may nonetheless be missing or blocked in unusual environments,
+such as a rare "FIPS compliant" build of Python or when OpenSSL's "FIPS mode"
+is configured to exclude some algorithms from its default provider. Calling
+the constructor of an algorithm that is unavailable raises :exc:`ValueError`.
Additional algorithms may also be available if your Python distribution's
:mod:`!hashlib` was linked against a build of OpenSSL that provides others.
return digestobj
-__logging = None
for __func_name in __always_supported:
# try them all, some may not work due to the OpenSSL
# version not supporting that algorithm.
try:
globals()[__func_name] = __get_hash(__func_name)
- except ValueError as __exc:
- import logging as __logging
- __logging.error('hash algorithm %s will not be supported at runtime '
- '[reason: %s]', __func_name, __exc)
+ except ValueError:
+ # Don't log here: logging at import time has global side effects and
+ # would tell the wrong audience; code that uses a missing algorithm
+ # gets a ValueError from the stub installed below.
# The following code can be simplified in Python 3.19
# once "string" is removed from the signature.
__code = f'''\
'''
exec(__code, {"__UNSET": object()}, __locals := {})
globals()[__func_name] = __locals[__func_name]
- del __exc, __code, __locals
+ del __code, __locals
# Cleanup locals()
del __always_supported, __func_name, __get_hash
del __py_new, __hash_new, __get_openssl_constructor
-del __logging
--- /dev/null
+Importing :mod:`hashlib` no longer logs an error to stderr when a normally
+guaranteed hash algorithm is unavailable in the current runtime (for example
+under an OpenSSL FIPS configuration or a build using
+:option:`--without-builtin-hashlib-hashes <--with-builtin-hashlib-hashes>`).
+Code that actually uses the missing algorithm still gets a clear
+:exc:`ValueError`.