Granularity of OSError

Jeff McNeil jeff at jmcneil.net
Fri Sep 18 15:42:38 EDT 2009


On Sep 18, 3:05 pm, Sean DiZazzo <half.ital... at gmail.com> wrote:
> On Sep 18, 11:54 am, kj <no.em... at please.post> wrote:
>
>
>
>
>
> > I've often come across the idea that good Python style deals with
> > potential errors using an EAFP ("easier to ask forgiveness than
> > permission") strategy rather than a LBYL ("look before you leap")
> > strategy.
>
> > For example, LBYL would look like this:
>
> > if os.path.isfile(some_file):
> >     os.unlink(some_file)
>
> > In contrast, EAFP would look like this:
>
> > try:
> >     os.unlink(some_file)
> > except OSError:
> >     pass
>
> > But, as written, the EAFP code above is not satisfactory, because
> > there can be OSError's triggered for reasons other than the
> > non-existence of the regular file some_file.
>
> > What one needs is a finer granularity of exception, mapping to
> > exactly the error that one is guarding against.
>
> > Is there a standard approach to refining the granularity of exceptions
> > such as OSError?  The only approach I can think of is to somehow
> > parse the error string (assuming is available) to determine whether
> > the exception is indeed of the specific kind we're trying to catch.
> > But this strikes me as grossly inelegant.  Is there a better way?
>
> > (BTW, the problem is generic, because client code has no control
> > over the specificity of the exceptions raised by a library module.
> > If these exceptions turn out to be too broad, client code has to
> > somehow deal with this reality, at least in the short term.)
>
> > TIA!
>
> > kynn
>
> You can access the exception object which gives you greater detail.
>
> try:
>     os.unlink(some_file)
> except OSError, e:
>     print e.errno
>     print e.strerror
>
>     if e.errno == 2:
>         pass
>     else:
>         raise
>
> If it's the error you are looking for, handle it, or else raise.
>
> ~Sean

I do this myself in a lot of places, almost exactly like this. It's
slightly clearer to use 'if e.errno == errno.ENOENT' in my opinion,
but, whatever.

The only place I've run into issues with this is when dealing with
socket programming across operating systems. Python on Windows exports
all of the WSA errors when dealing with sockets, but 'WSAEHOSTUNREACH'
is not the same as 'ENETUNREACH.' In cases like that, you've got to be
careful to check for all possible variations of the same error if you
care about supporting Windows.

Thanks,

Jeff
mcjeff.blogspot.com



More information about the Python-list mailing list