Author: Amaury Forgeot d'Arc <amaur...@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() _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit