4

While reviewing the system library socket.py implementation I came across this code

try:
    import errno
except ImportError:
    errno = None
EBADF = getattr(errno, 'EBADF', 9)
EINTR = getattr(errno, 'EINTR', 4)

Is this code just a relic of a bygone age, or there are platforms/implementations out there for which there is no errno module?

To be more explicit, is it safe to import errno without an exception handler?

I'm interested in answers for both python 2.x and 3.x.

Edit

To clarify the question: I have to test error codes encoded in IOError exceptions raised inside the socket module. The above code, which is in the cpython code base, made me suspicious about known situations in which socket is available, but import errno would fail. Maybe a minor question, but I would like to avoid unnecessary code.

Stefano M
  • 4,267
  • 2
  • 27
  • 45
  • related: [Access to errno from Python?](http://stackoverflow.com/q/661017/4279) – jfs May 08 '14 at 17:50
  • @J.F.Sebastian not quite: I get the current `errno` from `IOError` and I'm looking for a portable way of testing against different error causes. Something like `if curr_errno == errno.ENOENT then:`... Just wondering if the `errno` module is really portable. – Stefano M May 08 '14 at 20:33
  • note: different system may return different errno numbers for the same errors – jfs May 08 '14 at 21:33

2 Answers2

1

well, there may be cases where errno might not be available. I did not check before saying it, but for python implementations that run on non-Unix systems, such as windows, symbian... As well as for python implementations running in emulator (like the Javascript based python REPL).

Though, if you don't provide an alternative to using errno, and actually to the use of sockets for those other systems, I'd say you can safely leave the import fail loudly, as your code won't be usable. You may just want to catch it to throw a nicer more explicit message off.

zmo
  • 24,463
  • 4
  • 54
  • 90
  • 1
    You are right: failing at the import is the most sensible option, given that it may be unpractical to write a program that tries to cope with an unforeseen situation. Eventually, if user complaints arrive, I will know... – Stefano M May 08 '14 at 20:59
1

errno is available since Python 1.4. The availability of the names such as ENOENT may depend on the platform: there are tons of ifdefs in the errno module source. "errno.h" header is checked in ./configure so it might not be available everywhere (it seems it is not used on WinCE) but it shouldn't prevent import errno.

Here's the initial revision that introduces 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)

I can understand the state before: from errno import EBADF may raise ImportError because EBADF might not be available on the system. The state after, I don't understand. I think import errno should be always successful on CPython on any platform.

jfs
  • 399,953
  • 195
  • 994
  • 1,670