从Python访问errno?
我被一个相当复杂的 Python 模块困住了,它不返回有用的错误代码(它实际上默默地失败了,令人不安)。 然而,它调用的底层 C 库设置了 errno。
通常 errno 是通过 OSError 属性出现的,但由于我没有例外,所以我无法理解它。
使用 ctypes,libc.errno 不起作用,因为 errno 是 GNU libc 中的宏。 Python 2.6 有一些功能,但 Debian 仍然使用 Python 2.5。 仅仅为了读取 errno 就将 C 模块插入到我的纯 Python 程序中,这让我感到恶心。
有什么方法可以访问 errno 吗? 仅限 Linux 的解决方案很好,因为所包装的库仅限 Linux。 我也不必担心线程,因为在可能失败的时间内我只运行一个线程。
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.
Normally errno comes in over OSError attributes, but since I don't have an exception, I can't get at it.
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.
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
以下是允许访问
errno
的代码片段:重要的是在函数调用后尽快检查
errno
,否则它可能已经被覆盖。Here is a snippet of code that allows to access
errno
:The important thing is that you check
errno
as soon as possible after your function call, otherwise it may already be overwritten.更新:在Python 2.6+上,使用<代码>ctypes.get_errno()。
Python 2.5
下面的代码不可靠(或者不全面,有多种方法可以定义 errno),但它应该可以帮助您入门(或者重新考虑您在一个小型扩展模块上的位置(毕竟在 Debian 上)
python setup.py install
或easy_install
构建它应该没有问题))。 来自 http://codespeak.net/pypy/dist/pypy/rpython /lltypesystem/ll2ctypes.py其中标准_c_lib:
Update: On Python 2.6+, use
ctypes.get_errno()
.Python 2.5
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 Debianpython setup.py install
oreasy_install
should have no problem to build it)). From http://codespeak.net/pypy/dist/pypy/rpython/lltypesystem/ll2ctypes.pyWhere
standard_c_lib
:看起来您可以使用此补丁,它将为您提供
ctypes.get_errno/set_errno
http: //bugs.python.org/issue1798
这是实际应用于存储库的补丁:
http://svn.python.org/view?view=rev&revision=63977
否则,添加一个新的 C 模块除了返回 errno /is/ 之外什么也不做,令人厌恶,但也是如此您正在使用的库。 我会这样做而不是自己修补 python。
It looks like you can use this patch that will provide you with
ctypes.get_errno/set_errno
http://bugs.python.org/issue1798
This is the patch that was actually applied to the repository:
http://svn.python.org/view?view=rev&revision=63977
Otherwise, adding a new C module that does nothing but return errno /is/ disgusting, but so is the library that you're using. I would do that in preference to patching python myself.
放弃并通过 C 标头进行跟踪。
它在 python 命令提示符下不起作用,因为它会将 errno 重置为从 stdin 读取。
一旦您了解了__errno_location 的神奇词,这看起来就像是一种常见模式。 但只有 errno 我就迷失了方向。
Gave up and tracked through the C headers.
It doesn't work in the python command prompt because it resets errno to read from stdin.
Once you know the magic word of __errno_location this looks like a common pattern. But with just errno I was pretty lost.
我不确定这是否是您和 Jerub 所指的,但您可以编写一个非常短的 C 扩展,仅导出 errno,即 Python 语言接口。
否则,我同意你的观点,必须添加这一小段编译代码是一件痛苦的事情。
I'm not sure if this is what you and Jerub are referring to, but you could write a very short C extension that just exports errno, i.e. with the python language interface.
Otherwise, I agree with you that having to add this small bit of compiled code is a pain.
ctypes 实际上提供了一种访问 python 的 c 实现的标准方法,即使用 errno。 我没有在我的(linux)系统以外的任何系统上测试过这个,但这应该是非常可移植的:
ctypes.c_int.in_dll(ctypes.pythonapi,"errno")
它返回一个包含当前值的 c_int 。
ctypes actually gives a standard way to access python's c implementation, which is using errno. I haven't tested this on anything other than my (linux) system, but this should be very portable:
ctypes.c_int.in_dll(ctypes.pythonapi,"errno")
which returns a c_int containing the current value.