[ sf.net patch # 1121611 ]

A new hashlib module to replace the md5 and sha modules.  It adds
support for additional secure hashes such as SHA-256 and SHA-512.  The
hashlib module uses OpenSSL for fast platform optimized
implementations of algorithms when available.  The old md5 and sha
modules still exist as wrappers around hashlib to preserve backwards
compatibility.
diff --git a/Lib/hmac.py b/Lib/hmac.py
index 11b0fb3..41d6c6c 100644
--- a/Lib/hmac.py
+++ b/Lib/hmac.py
@@ -28,27 +28,33 @@
 
         key:       key for the keyed hash object.
         msg:       Initial input for the hash, if provided.
-        digestmod: A module supporting PEP 247. Defaults to the md5 module.
+        digestmod: A module supporting PEP 247.  *OR*
+                   A hashlib constructor returning a new hash object.
+                   Defaults to hashlib.md5.
         """
 
         if key is _secret_backdoor_key: # cheap
             return
 
         if digestmod is None:
-            import md5
-            digestmod = md5
+            import hashlib
+            digestmod = hashlib.md5
 
-        self.digestmod = digestmod
-        self.outer = digestmod.new()
-        self.inner = digestmod.new()
-        self.digest_size = digestmod.digest_size
+        if callable(digestmod):
+            self.digest_cons = digestmod
+        else:
+            self.digest_cons = lambda d='': digestmod.new(d)
+
+        self.outer = self.digest_cons()
+        self.inner = self.digest_cons()
+        self.digest_size = self.inner.digest_size
 
         blocksize = 64
         ipad = "\x36" * blocksize
         opad = "\x5C" * blocksize
 
         if len(key) > blocksize:
-            key = digestmod.new(key).digest()
+            key = self.digest_cons(key).digest()
 
         key = key + chr(0) * (blocksize - len(key))
         self.outer.update(_strxor(key, opad))
@@ -70,7 +76,7 @@
         An update to this copy won't affect the original object.
         """
         other = HMAC(_secret_backdoor_key)
-        other.digestmod = self.digestmod
+        other.digest_cons = self.digest_cons
         other.digest_size = self.digest_size
         other.inner = self.inner.copy()
         other.outer = self.outer.copy()