[pypy-commit] pypy stdlib-2.7.9: Implement _hashlib.openssl_md_meth_names, needed by hashlib.py

amauryfa noreply at buildbot.pypy.org
Sun Dec 14 21:14:45 CET 2014


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: stdlib-2.7.9
Changeset: r74934:1d1bd5f19364
Date: 2011-10-22 00:24 +0200
http://bitbucket.org/pypy/pypy/changeset/1d1bd5f19364/

Log:	Implement _hashlib.openssl_md_meth_names, needed by hashlib.py

diff --git a/pypy/module/_hashlib/__init__.py b/pypy/module/_hashlib/__init__.py
--- a/pypy/module/_hashlib/__init__.py
+++ b/pypy/module/_hashlib/__init__.py
@@ -5,6 +5,7 @@
 class Module(MixedModule):
     interpleveldefs = {
         'new' : 'interp_hashlib.new',
+        'openssl_md_meth_names': 'interp_hashlib.get(space).w_meth_names'
         }
 
     appleveldefs = {
diff --git a/pypy/module/_hashlib/interp_hashlib.py b/pypy/module/_hashlib/interp_hashlib.py
--- a/pypy/module/_hashlib/interp_hashlib.py
+++ b/pypy/module/_hashlib/interp_hashlib.py
@@ -1,17 +1,62 @@
 from __future__ import with_statement
+
+from rpython.rlib import rgc, ropenssl
+from rpython.rlib.objectmodel import we_are_translated
+from rpython.rlib.rstring import StringBuilder
+from rpython.rtyper.lltypesystem import lltype, rffi
+from rpython.tool.sourcetools import func_renamer
+
+from pypy.interpreter.baseobjspace import W_Root
+from pypy.interpreter.error import OperationError
 from pypy.interpreter.gateway import unwrap_spec, interp2app
 from pypy.interpreter.typedef import TypeDef, GetSetProperty
-from pypy.interpreter.error import OperationError
-from rpython.tool.sourcetools import func_renamer
-from pypy.interpreter.baseobjspace import W_Root
-from rpython.rtyper.lltypesystem import lltype, rffi
-from rpython.rlib import rgc, ropenssl
-from rpython.rlib.rstring import StringBuilder
 from pypy.module.thread.os_lock import Lock
 
 
 algorithms = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512')
 
+def hash_name_mapper_callback(obj_name, userdata):
+    state = global_state[0]
+    assert state is not None
+    if not obj_name:
+        return
+    # Ignore aliased names, they pollute the list and OpenSSL appears
+    # to have a its own definition of alias as the resulting list
+    # still contains duplicate and alternate names for several
+    # algorithms.
+    if obj_name[0].c_alias:
+        return
+    try:
+        w_name = state.space.wrap(rffi.charp2str(obj_name[0].c_name))
+        state.space.call_method(state.w_meth_names, "add", w_name)
+    except OperationError, e:
+        state.w_error = e
+
+# XXX make it threadlocal?
+global_state = [None]
+
+class State:
+    def __init__(self, space):
+        self.space = space
+        self.generate_method_names(space)
+
+    def generate_method_names(self, space):
+        if not we_are_translated():
+            ropenssl.init_digests()
+        self.w_error = None
+        try:
+            global_state[0] = self
+            self.w_meth_names = space.call_function(space.w_set)
+            ropenssl.OBJ_NAME_do_all(
+                ropenssl.OBJ_NAME_TYPE_MD_METH,
+                hash_name_mapper_callback, None)
+        finally:
+            global_state[0] = None
+        if self.w_error:
+            raise self.w_error
+
+def get(space):
+    return space.fromcache(State)
 
 class W_Hash(W_Root):
     NULL_CTX = lltype.nullptr(ropenssl.EVP_MD_CTX.TO)
diff --git a/pypy/module/_hashlib/test/test_hashlib.py b/pypy/module/_hashlib/test/test_hashlib.py
--- a/pypy/module/_hashlib/test/test_hashlib.py
+++ b/pypy/module/_hashlib/test/test_hashlib.py
@@ -3,6 +3,11 @@
         "usemodules": ['_hashlib', 'array', 'struct', 'binascii'],
     }
 
+    def test_method_names(self):
+        import _hashlib
+        assert isinstance(_hashlib.openssl_md_meth_names, set)
+        assert "md5" in _hashlib.openssl_md_meth_names
+
     def test_simple(self):
         import _hashlib
         assert _hashlib.new('md5').__class__.__name__ == 'HASH'
diff --git a/rpython/rlib/ropenssl.py b/rpython/rlib/ropenssl.py
--- a/rpython/rlib/ropenssl.py
+++ b/rpython/rlib/ropenssl.py
@@ -144,6 +144,12 @@
          ('name', rffi.CCHARP),
          ])
 
+    OBJ_NAME_st = rffi_platform.Struct(
+        'OBJ_NAME',
+        [('alias', rffi.INT),
+         ('name', rffi.CCHARP),
+         ])
+
 
 for k, v in rffi_platform.configure(CConfig).items():
     globals()[k] = v
@@ -343,6 +349,11 @@
 HASH_MALLOC_SIZE = EVP_MD_SIZE + EVP_MD_CTX_SIZE \
         + rffi.sizeof(EVP_MD) * 2 + 208
 
+OBJ_NAME_CALLBACK = lltype.Ptr(lltype.FuncType(
+        [OBJ_NAME, rffi.VOIDP], lltype.Void))
+OBJ_NAME_do_all = external(
+    'OBJ_NAME_do_all', [rffi.INT, OBJ_NAME_CALLBACK, rffi.VOIDP], lltype.Void)
+
 def init_ssl():
     libssl_SSL_load_error_strings()
     libssl_SSL_library_init()


More information about the pypy-commit mailing list