Python errno模块在不同平台上的可用性

4
在审查系统库socket.py实现时,我遇到了这段代码。
try:
    import errno
except ImportError:
    errno = None
EBADF = getattr(errno, 'EBADF', 9)
EINTR = getattr(errno, 'EINTR', 4)

这段代码是过时的遗物,还是有平台/实现不支持 errno 模块?更明确地说,没有异常处理器是否安全地导入 errno?我对 Python 2.x 和 3.x 的答案都感兴趣。
编辑说明:为了澄清问题:我必须测试在 socket 模块中引发的 IOError 异常中编码的错误代码。上述代码位于 cpython 代码库中的 socket.py,让我怀疑在某些已知情况下,socket 可用但 import errno 将失败。也许这是一个次要问题,但我想避免不必要的代码。

@J.F.Sebastian 不完全正确:我从 IOError 中获取当前的 errno,并且正在寻找一种可移植的测试不同错误原因的方法。类似于 if curr_errno == errno.ENOENT then:... 只是想知道 errno 模块是否真的是可移植的。 - Stefano M
请注意:不同的系统可能会为相同的错误返回不同的errno数字。 - jfs
2个回答

1
errno自Python 1.4版本开始提供。诸如ENOENT之类的名称的可用性可能取决于平台:在 errno模块源代码中有大量的ifdef。在./configure中检查"errno.h"头文件,因此它可能无法在所有地方使用(似乎不在WinCE上使用),但这不应该阻止import errno这是引入errno=None的初始修订版本
 try:
-    from errno import EBADF
+    import errno
 except ImportError:
-    EBADF = 9
+    errno = None
+EBADF = getattr(errno, 'EBADF', 9)
+EINTR = getattr(errno, 'EINTR', 4)

我可以理解之前的状态:from errno import EBADF 可能会引发ImportError,因为系统上可能没有EBADF。但之后的状态,我不太明白。我认为在任何平台上,对于CPython来说,import errno 应该总是成功的。

1

嗯,有时 errno 可能不可用。在说出这句话之前,我没有检查过,但是对于运行在非 Unix 系统上的 Python 实现,例如 Windows、Symbian... 以及在模拟器中运行的 Python 实现(例如基于 JavaScript 的 Python REPL),都是如此。

尽管如此,如果您不提供使用 errno 的替代方法,以及对于那些其他系统使用套接字的替代方法,我建议您可以安全地让导入失败并产生响亮的错误,因为您的代码将无法使用。您可能只想捕获它以抛出更好的、更明确的消息。


1
你是对的:在导入失败的情况下,这是最明智的选择,因为编写一个试图应对未预料到情况的程序可能是不切实际的。最终,如果用户投诉到来,我会知道... - Stefano M

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接