Skip to content

Commit d8fe8bf

Browse files
committed
Merged revisions 74479 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r74479 | gregory.p.smith | 2009-08-16 14:54:45 -0700 (Sun, 16 Aug 2009) | 2 lines Clean up the C library import code (based on suggestions in issue6281). ........
1 parent 1768343 commit d8fe8bf

File tree

1 file changed

+33
-33
lines changed

1 file changed

+33
-33
lines changed

Lib/hashlib.py

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@
5353
5454
"""
5555

56+
# This tuple and __get_builtin_constructor() must be modified if a new
57+
# always available algorithm is added.
58+
__always_supported = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512')
59+
60+
__all__ = __always_supported + ('new',)
61+
5662

5763
def __get_builtin_constructor(name):
5864
if name in ('SHA1', 'sha1'):
@@ -76,7 +82,19 @@ def __get_builtin_constructor(name):
7682
elif bs == '384':
7783
return _sha512.sha384
7884

79-
raise ValueError("unsupported hash type")
85+
raise ValueError('unsupported hash type %s' % name)
86+
87+
88+
def __get_openssl_constructor(name):
89+
try:
90+
f = getattr(_hashlib, 'openssl_' + name)
91+
# Allow the C module to raise ValueError. The function will be
92+
# defined but the hash not actually available thanks to OpenSSL.
93+
f()
94+
# Use the C function directly (very fast)
95+
return f
96+
except (AttributeError, ValueError):
97+
return __get_builtin_constructor(name)
8098

8199

82100
def __py_new(name, data=b''):
@@ -102,39 +120,21 @@ def __hash_new(name, data=b''):
102120

103121
try:
104122
import _hashlib
105-
# use the wrapper of the C implementation
106123
new = __hash_new
107-
108-
for opensslFuncName in filter(lambda n: n.startswith('openssl_'), dir(_hashlib)):
109-
funcName = opensslFuncName[len('openssl_'):]
110-
try:
111-
# try them all, some may not work due to the OpenSSL
112-
# version not supporting that algorithm.
113-
f = getattr(_hashlib, opensslFuncName)
114-
f()
115-
# Use the C function directly (very fast)
116-
exec(funcName + ' = f')
117-
except ValueError:
118-
try:
119-
# Use the builtin implementation directly (fast)
120-
exec(funcName + ' = __get_builtin_constructor(funcName)')
121-
except ValueError:
122-
# this one has no builtin implementation, don't define it
123-
pass
124-
# clean up our locals
125-
del f
126-
del opensslFuncName
127-
del funcName
128-
124+
__get_hash = __get_openssl_constructor
129125
except ImportError:
130-
# We don't have the _hashlib OpenSSL module?
131-
# use the built in legacy interfaces via a wrapper function
132126
new = __py_new
127+
__get_hash = __get_builtin_constructor
128+
129+
for __func_name in __always_supported:
130+
# try them all, some may not work due to the OpenSSL
131+
# version not supporting that algorithm.
132+
try:
133+
globals()[__func_name] = __get_hash(__func_name)
134+
except ValueError:
135+
import logging
136+
logging.exception('code for hash %s was not found.', __func_name)
133137

134-
# lookup the C function to use directly for the named constructors
135-
md5 = __get_builtin_constructor('md5')
136-
sha1 = __get_builtin_constructor('sha1')
137-
sha224 = __get_builtin_constructor('sha224')
138-
sha256 = __get_builtin_constructor('sha256')
139-
sha384 = __get_builtin_constructor('sha384')
140-
sha512 = __get_builtin_constructor('sha512')
138+
# Cleanup locals()
139+
del __always_supported, __func_name, __get_hash
140+
del __py_new, __hash_new, __get_openssl_constructor

0 commit comments

Comments
 (0)