(Contributed by Jiahao Li in :gh:`134580`.)
+hashlib
+-------
+
+* Ensure that hash functions guaranteed to be always *available* exist as
+ attributes of :mod:`hashlib` even if they will not work at runtime due to
+ missing backend implementations. For instance, ``hashlib.md5`` will no
+ longer raise :exc:`AttributeError` if OpenSSL is not available and Python
+ has been built without MD5 support.
+ (Contributed by Bénédikt Tran in :gh:`136929`.)
+
+
http.client
-----------
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:
- import logging
- logging.exception('code for hash %s was not found.', __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)
+ # The following code can be simplified in Python 3.19
+ # once "string" is removed from the signature.
+ __code = f'''\
+def {__func_name}(data=__UNSET, *, usedforsecurity=True, string=__UNSET):
+ if data is __UNSET and string is not __UNSET:
+ import warnings
+ warnings.warn(
+ "the 'string' keyword parameter is deprecated since "
+ "Python 3.15 and slated for removal in Python 3.19; "
+ "use the 'data' keyword parameter or pass the data "
+ "to hash as a positional argument instead",
+ DeprecationWarning, stacklevel=2)
+ if data is not __UNSET and string is not __UNSET:
+ raise TypeError("'data' and 'string' are mutually exclusive "
+ "and support for 'string' keyword parameter "
+ "is slated for removal in a future version.")
+ raise ValueError("unsupported hash algorithm {__func_name}")
+'''
+ exec(__code, {"__UNSET": object()}, __locals := {})
+ globals()[__func_name] = __locals[__func_name]
+ del __exc, __code, __locals
# Cleanup locals()
del __always_supported, __func_name, __get_hash
del __py_new, __hash_new, __get_openssl_constructor
+del __logging