• ImportError: No module named _md5解决方案


    将使用cx_freeze打包的python程序copy到别的机器上运行时碰到这样的错误:
    jerrykwan@jerrykwan:~/Downloads/exe.linux-x86_64-2.7$ ./server_family_info
    Traceback (most recent call last):
      File "/usr/local/lib/python2.7/site-packages/cx_Freeze/initscripts/Console.py", line 27, in <module>
      File "server_family_info.py", line 14, in <module>
      File "/usr/local/lib/python2.7/site-packages/tornado-2.4.1-py2.7.egg/tornado/web.py", line 59, in <module>
      File "/usr/local/lib/python2.7/email/utils.py", line 27, in <module>
      File "/usr/local/lib/python2.7/random.py", line 49, in <module>
      File "/usr/local/lib/python2.7/hashlib.py", line 136, in <module>
      File "/usr/local/lib/python2.7/hashlib.py", line 71, in __get_builtin_constructor
    ImportError: No module named _md5
    通过日志可以看出问题很明显,应该就是在hashlib模块中出的问题.
    hashlib源码如下:

    # 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')
    
    algorithms = __always_supported
    
    __all__ = __always_supported + ('new', 'algorithms')
    
    
    def __get_builtin_constructor(name):
        try:
            if name in ('SHA1', 'sha1'):
                import _sha
                return _sha.new
            elif name in ('MD5', 'md5'):
                import _md5
                return _md5.new
            elif name in ('SHA256', 'sha256', 'SHA224', 'sha224'):
                import _sha256
                bs = name[3:]
                if bs == '256':
                    return _sha256.sha256
                elif bs == '224':
                    return _sha256.sha224
            elif name in ('SHA512', 'sha512', 'SHA384', 'sha384'):
                import _sha512
                bs = name[3:]
                if bs == '512':
                    return _sha512.sha512
                elif bs == '384':
                    return _sha512.sha384
        except ImportError:
            pass  # no extension module, this hash is unsupported.
    
        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, string=''):
        """new(name, string='') - Return a new hashing object using the named algorithm;
        optionally initialized with a string.
        """
        return __get_builtin_constructor(name)(string)
    
    
    def __hash_new(name, string=''):
        """new(name, string='') - Return a new hashing object using the named algorithm;
        optionally initialized with a string.
        """
        try:
            return _hashlib.new(name, string)
        except ValueError:
            # If the _hashlib module (OpenSSL) doesn't support the named
            # hash, try using our builtin implementations.
            # This allows for SHA224/256 and SHA384/512 support even though
            # the OpenSSL library prior to 0.9.8 doesn't provide them.
            return __get_builtin_constructor(name)(string)
    
    
    try:
        import _hashlib
        new = __hash_new
        __get_hash = __get_openssl_constructor
    except ImportError:
        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)
    
    # Cleanup locals()
    del __always_supported, __func_name, __get_hash
    del __py_new, __hash_new, __get_openssl_constructor

    从hashlib.py的源码很容易看出,对于hashlib提供的('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512')等算法,hashlib的做法是先去检验python内置的_hashlib是否支持openssh,这点儿可以认为是python编译的时候是否加入了openssl的支持,如果已经拥有openssl的支持,则直接使用python内置的openssl提供的算法,否则使用其他第三方的算法
    可以确定的是,我们使用cx_freeze进行编译的时候机器上的python是支持openssl的,但为什么编译完的程序却不具备该功能呢?
    通过使用ldd查看动态库依赖关系可以看出如下信息:
    jerrykwan@jerrykwan:~/Downloads/exe.linux-x86_64-2.7$ ldd server_family_info
        linux-vdso.so.1 =>  (0x00007fff5c5ff000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fe755d1f000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fe755b1b000)
        libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007fe755917000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fe75561b000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe75525c000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fe755f53000)
    jerrykwan@jerrykwan:~/Downloads/exe.linux-x86_64-2.7$ ldd _hashlib.so
        linux-vdso.so.1 =>  (0x00007fff042f3000)
        libssl.so.6 => not found
        libcrypto.so.6 => not found
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f2ed15fd000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2ed123e000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f2ed1a36000)
    原来是 libssl.so.6libcrypto.so.6等动态库找不到的原因导致hashlib模块认为使用cx_freeze编译后的python环境不具备openssl支持,进而使用第三方md5等算法,但此时运行环境中第三方md5等模块也不具备,所以程序运行时出错
    为解决这一问题可以在打包时将libssl.so.6libcrypto.so.6 copy到运行环境中,也可以调整系统的/etc/ld.so.conf以便很方便的找到libssl.so.6libcrypto.so.6



  • 相关阅读:
    [Docker]如何实现使用scp从任意路径中向Docker镜像中复制文件
    puma web server如何监听所有IP地址
    Consider increasing the configuration parameter "max_wal_size
    ABFramework中使用select查询表时,想要排除某些字段不显示的方法
    FireDAC内存表过虑的错误
    有了ABMeeting,远程控制再也不用什么向X葵了
    ABFramework中设置关联表下拉选择的方法
    太牛逼了
    python3 利用scapy抓取网卡数据包并保存pcap
    json数组根据某属性去重
  • 原文地址:https://www.cnblogs.com/Jerryshome/p/2998217.html
Copyright © 2020-2023  润新知