Kaydet (Commit) 99954c9c authored tarafından Gregory P. Smith's avatar Gregory P. Smith

Clean up the C library import code (based on suggestions in issue6281).

üst df756775
...@@ -54,6 +54,12 @@ More condensed: ...@@ -54,6 +54,12 @@ More condensed:
""" """
# This tuple and __get_builtin_constructor() must be modified if a new
# always available algorithm is added.
__always_supported = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512')
__all__ = __always_supported + ('new',)
def __get_builtin_constructor(name): def __get_builtin_constructor(name):
if name in ('SHA1', 'sha1'): if name in ('SHA1', 'sha1'):
...@@ -77,7 +83,19 @@ def __get_builtin_constructor(name): ...@@ -77,7 +83,19 @@ def __get_builtin_constructor(name):
elif bs == '384': elif bs == '384':
return _sha512.sha384 return _sha512.sha384
raise ValueError, "unsupported hash type" raise ValueError('unsupported hash type %s' % name)
def __get_openssl_constructor(name):
try:
f = getattr(_hashlib, 'openssl_' + name)
# Allow the C module to raise ValueError. The function will be
# defined but the hash not actually available thanks to OpenSSL.
f()
# Use the C function directly (very fast)
return f
except (AttributeError, ValueError):
return __get_builtin_constructor(name)
def __py_new(name, string=''): def __py_new(name, string=''):
...@@ -103,39 +121,21 @@ def __hash_new(name, string=''): ...@@ -103,39 +121,21 @@ def __hash_new(name, string=''):
try: try:
import _hashlib import _hashlib
# use the wrapper of the C implementation
new = __hash_new new = __hash_new
__get_hash = __get_openssl_constructor
for opensslFuncName in filter(lambda n: n.startswith('openssl_'), dir(_hashlib)):
funcName = opensslFuncName[len('openssl_'):]
try:
# try them all, some may not work due to the OpenSSL
# version not supporting that algorithm.
f = getattr(_hashlib, opensslFuncName)
f()
# Use the C function directly (very fast)
exec funcName + ' = f'
except ValueError:
try:
# Use the builtin implementation directly (fast)
exec funcName + ' = __get_builtin_constructor(funcName)'
except ValueError:
# this one has no builtin implementation, don't define it
pass
# clean up our locals
del f
del opensslFuncName
del funcName
except ImportError: except ImportError:
# We don't have the _hashlib OpenSSL module?
# use the built in legacy interfaces via a wrapper function
new = __py_new new = __py_new
__get_hash = __get_builtin_constructor
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)
# lookup the C function to use directly for the named constructors # Cleanup locals()
md5 = __get_builtin_constructor('md5') del __always_supported, __func_name, __get_hash
sha1 = __get_builtin_constructor('sha1') del __py_new, __hash_new, __get_openssl_constructor
sha224 = __get_builtin_constructor('sha224')
sha256 = __get_builtin_constructor('sha256')
sha384 = __get_builtin_constructor('sha384')
sha512 = __get_builtin_constructor('sha512')
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment