Sitelet https://github.com/python/cpython/commit/99954c9c45ffd192f7c9cf96998e830e07020b28
Skip to content

Commit 99954c9

Browse files
committed
Clean up the C library import code (based on suggestions in issue6281).
1 parent df75677 commit 99954c9

1 file changed

Lines changed: 33 additions & 33 deletions

File tree

‎Lib/hashlib.py‎

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

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

5864
def __get_builtin_constructor(name):
5965
if name in ('SHA1', 'sha1'):
@@ -77,7 +83,19 @@ def __get_builtin_constructor(name):
7783
elif bs == '384':
7884
return _sha512.sha384
7985

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

82100

83101
def __py_new(name, string=''):
@@ -103,39 +121,21 @@ def __hash_new(name, string=''):
103121

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

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

0 commit comments

Comments
 (0)