从Python访问errno? [英] Access to errno from Python?

查看:250
本文介绍了从Python访问errno?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我陷入了一个相当复杂的Python模块中,该模块不会返回有用的错误代码(它实际上会以静默方式失败而失败).但是,它调用的基础C库设置了errno.

I am stuck with a fairly complex Python module that does not return useful error codes (it actually fails disturbingly silently). However, the underlying C library it calls sets errno.

通常errno是通过OSError属性传入的,但是由于我没有异常,所以无法理解.

Normally errno comes in over OSError attributes, but since I don't have an exception, I can't get at it.

使用ctypes,libc.errno不起作用,因为errno是GNU libc中的宏. Python 2.6有一些优势,但Debian仍使用Python 2.5.将C模块插入我的纯Python程序中只是为了阅读errno,这使我感到恶心.

Using ctypes, libc.errno doesn't work because errno is a macro in GNU libc. Python 2.6 has some affordances but Debian still uses Python 2.5. Inserting a C module into my pure Python program just to read errno disgusts me.

有什么方法可以访问errno?仅Linux的解决方案很好,因为要包装的库仅Linux.我也不必担心线程,因为我只会在可能失败的时间内运行一个线程.

Is there some way to access errno? A Linux-only solution is fine, since the library being wrapped is Linux-only. I also don't have to worry about threads, as I'm only running one thread during the time in which this can fail.

推荐答案

更新:在 Python 2.6 + 上,使用

Update: On Python 2.6+, use ctypes.get_errno().

下面的代码不可靠(或者说很全面,有很多方法可以定义errno),但是它应该可以让您入门(或者重新考虑您在微型扩展模块上的位置(毕竟在Debian python setup.py installeasy_install应该没有问题来构建它)).来自 http://codespeak.net/pypy/dist/pypy/rpython /lltypesystem/ll2ctypes.py

Belowed code is not reliable (or comprehensive, there are a plefora of ways errno could be defined) but it should get you started (or reconsider your position on a tiny extension module (after all on Debian python setup.py install or easy_install should have no problem to build it)). From http://codespeak.net/pypy/dist/pypy/rpython/lltypesystem/ll2ctypes.py

if not hasattr(ctypes, 'get_errno'):
    # Python 2.5 or older
    if sys.platform == 'win32':
        standard_c_lib._errno.restype = ctypes.POINTER(ctypes.c_int)
        def _where_is_errno():
            return standard_c_lib._errno()

    elif sys.platform in ('linux2', 'freebsd6'):
        standard_c_lib.__errno_location.restype = ctypes.POINTER(ctypes.c_int)
        def _where_is_errno():
            return standard_c_lib.__errno_location()

    elif sys.platform in ('darwin', 'freebsd7'):
        standard_c_lib.__error.restype = ctypes.POINTER(ctypes.c_int)
        def _where_is_errno():
            return standard_c_lib.__error()
    ctypes.get_errno = lambda: _where_is_errno().contents.value 

standard_c_lib所在的位置:

def get_libc_name():
    if sys.platform == 'win32':
        # Parses sys.version and deduces the version of the compiler
        import distutils.msvccompiler
        version = distutils.msvccompiler.get_build_version()
        if version is None:
            # This logic works with official builds of Python.
            if sys.version_info < (2, 4):
                clibname = 'msvcrt'
            else:
                clibname = 'msvcr71'
        else:
            if version <= 6:
                clibname = 'msvcrt'
            else:
                clibname = 'msvcr%d' % (version * 10)

        # If python was built with in debug mode
        import imp
        if imp.get_suffixes()[0][0] == '_d.pyd':
            clibname += 'd'

        return clibname+'.dll'
    else:
        return ctypes.util.find_library('c')

# Make sure the name is determined during import, not at runtime
libc_name = get_libc_name() 
standard_c_lib = ctypes.cdll.LoadLibrary(get_libc_name())

这篇关于从Python访问errno?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆