mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 23:21:29 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			51 lines
		
	
	
	
		
			1.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			51 lines
		
	
	
	
		
			1.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
import functools
 | 
						|
import hashlib
 | 
						|
import unittest
 | 
						|
 | 
						|
try:
 | 
						|
    import _hashlib
 | 
						|
except ImportError:
 | 
						|
    _hashlib = None
 | 
						|
 | 
						|
 | 
						|
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}' is not available."
 | 
						|
                )
 | 
						|
            return func_or_class(*args, **kwargs)
 | 
						|
        return wrapper
 | 
						|
    return decorator
 |