cpython/Lib/test/support/hashlib_helper.py
Bénédikt Tran 8f11af45de
gh-130149: refactor tests for HMAC (#130150)
Since we plan to introduce a built-in implementation for HMAC based on HACL*,
it becomes important for the HMAC tests to be flexible enough to avoid code
duplication.

In addition to the new layout based on mixin classes, we extend test coverage by
also testing the `__repr__` of HMAC objects and the HMAC one-shot functions.

We also fix the import to `_sha256` which, since gh-101924, resulted in some tests being
skipped as the module is no more available (its content was moved to the `_sha2` module).
2025-03-03 11:22:05 +01:00

55 lines
2 KiB
Python

import functools
import hashlib
import unittest
try:
import _hashlib
except ImportError:
_hashlib = None
def requires_hashlib():
return unittest.skipIf(_hashlib is None, "requires _hashlib")
def requires_hashdigest(digestname, openssl=None, usedforsecurity=True):
"""Decorator raising SkipTest if a hashing algorithm is not available
The hashing algorithm could be missing or blocked by a strict crypto
policy.
If 'openssl' is True, then the decorator checks that OpenSSL provides
the algorithm. Otherwise the check falls back to built-in
implementations. The usedforsecurity flag is passed to the constructor.
ValueError: [digital envelope routines: EVP_DigestInit_ex] disabled for FIPS
ValueError: unsupported hash type md4
"""
def decorator(func_or_class):
if isinstance(func_or_class, type):
setUpClass = func_or_class.__dict__.get('setUpClass')
if setUpClass is None:
def setUpClass(cls):
super(func_or_class, cls).setUpClass()
setUpClass.__qualname__ = func_or_class.__qualname__ + '.setUpClass'
setUpClass.__module__ = func_or_class.__module__
else:
setUpClass = setUpClass.__func__
setUpClass = classmethod(decorator(setUpClass))
func_or_class.setUpClass = setUpClass
return func_or_class
@functools.wraps(func_or_class)
def wrapper(*args, **kwargs):
try:
if openssl and _hashlib is not None:
_hashlib.new(digestname, usedforsecurity=usedforsecurity)
else:
hashlib.new(digestname, usedforsecurity=usedforsecurity)
except ValueError:
raise unittest.SkipTest(
f"hash digest {digestname!r} is not available."
)
return func_or_class(*args, **kwargs)
return wrapper
return decorator