[Python-checkins] r74482 - in python/branches/py3k: Lib/hashlib.py

gregory.p.smith python-checkins at python.org
Mon Aug 17 00:08:57 CEST 2009


Author: gregory.p.smith
Date: Mon Aug 17 00:08:56 2009
New Revision: 74482

Log:
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).
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Lib/hashlib.py

Modified: python/branches/py3k/Lib/hashlib.py
==============================================================================
--- python/branches/py3k/Lib/hashlib.py	(original)
+++ python/branches/py3k/Lib/hashlib.py	Mon Aug 17 00:08:56 2009
@@ -53,6 +53,12 @@
 
 """
 
+# 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'):
@@ -76,7 +82,19 @@
         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, data=b''):
@@ -102,39 +120,21 @@
 
 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


More information about the Python-checkins mailing list