[Tutor] errno module - was File copying - best way?

Michael P. Reilly arcege@speakeasy.net
Sun, 5 Aug 2001 14:53:33 -0400


On Sun, Aug 05, 2001 at 01:06:09PM -0400, fleet@teachout.org wrote:
> 
> I will study this and look at the rest of the exceptions listed for 'os;'
> but what about the 'errno' module?

>>> import os, sys
>>> os.strerror
<built-in function strerror>
>>> print os.strerror.__doc__
strerror(code) -> string
Translate an error code to a message string.
>>> import errno
>>> errno.ENOENT
2
>>> os.strerror(errno.ENOENT)
'No such file or directory'

The strerror() function is just like in C.

Lets try a few errors.  The open() function raises the IOError exception,
which is related to the OSError exception.  The actual error is a field
in the exception instance.

>>> try: open('/etc/nosuchfile')
... except IOError, err1: pass
...
>>> err1
<exceptions.IOError instance at 80cc9e8>
>>> print err1
[Errno 2] No such file or directory: '/etc/nosuchfile'
>>> vars(err1)
{'filename': '/etc/nosuchfile', 'strerror': 'No such file or directory',
'args': (2, 'No such file or directory'), 'errno': 2}
>>> err1.errno
2
>>> errno.ENOENT == err1.errno
1

So the 'errno' member of the exception is the same as the C global.

>>> try: open('/etc/passwd', 'w')
... except IOError, err2: pass
...
>>> print err2
[Errno 13] Permission denied: '/etc/passwd'
>>> err2.errno == errno.EACCES
1
>>> err2.errno
13

Also notice that the filename is included.  Not on all, but the ones that
relate to file errors, will have this attribute.

Since a lot of different possible values can come from the exception,
sometimes it is valuable to search for the proper error in the except
clause:

try:
  dbfile = open(dbfilename, 'rb+')
except IOError, err:
  if err.errno == errno.EACCES:
    dbfilename = find_alternate_location(dbfilename)
    dbfile = open(dbfilename, 'wb')

  elif err.errno == errno.ENOENT:
    dbfile = open(dbfilename, 'wb+')
    initialize_database(dbfile)

The only other purpose I have found for using the errno module is when
you are raising your own IOError or OSError exceptions.

  import errno
  ...
  raise IOError(errno.EAGAIN, os.strerror(errno.EAGAIN))

That's pretty much it.

  -Arcege

-- 
+----------------------------------+-----------------------------------+
| Michael P. Reilly                | arcege@speakeasy.net              |