diff options
author | Gregory P. Smith <greg@mad-scientist.com> | 2009-08-16 21:54:45 (GMT) |
---|---|---|
committer | Gregory P. Smith <greg@mad-scientist.com> | 2009-08-16 21:54:45 (GMT) |
commit | 99954c9c45ffd192f7c9cf96998e830e07020b28 (patch) | |
tree | 65d541a0297687049d03d884427a225dcea217d0 /Lib/hashlib.py | |
parent | df756775f5c56c5eef959a90321a513802fbda8c (diff) | |
download | cpython-99954c9c45ffd192f7c9cf96998e830e07020b28.zip cpython-99954c9c45ffd192f7c9cf96998e830e07020b28.tar.gz cpython-99954c9c45ffd192f7c9cf96998e830e07020b28.tar.bz2 |
Clean up the C library import code (based on suggestions in issue6281).
Diffstat (limited to 'Lib/hashlib.py')
-rw-r--r-- | Lib/hashlib.py | 66 |
1 files changed, 33 insertions, 33 deletions
diff --git a/Lib/hashlib.py b/Lib/hashlib.py index a9068a5..5ecca2b 100644 --- a/Lib/hashlib.py +++ b/Lib/hashlib.py @@ -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): if name in ('SHA1', 'sha1'): @@ -77,7 +83,19 @@ def __get_builtin_constructor(name): elif bs == '384': 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=''): @@ -103,39 +121,21 @@ def __hash_new(name, string=''): try: import _hashlib - # use the wrapper of the C implementation new = __hash_new - - 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 - + __get_hash = __get_openssl_constructor except ImportError: - # We don't have the _hashlib OpenSSL module? - # use the built in legacy interfaces via a wrapper function 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 - md5 = __get_builtin_constructor('md5') - sha1 = __get_builtin_constructor('sha1') - sha224 = __get_builtin_constructor('sha224') - sha256 = __get_builtin_constructor('sha256') - sha384 = __get_builtin_constructor('sha384') - sha512 = __get_builtin_constructor('sha512') +# Cleanup locals() +del __always_supported, __func_name, __get_hash +del __py_new, __hash_new, __get_openssl_constructor |