Please leave IOError and OSError alone
From Lawrence Oluyede's blog entry about recent Python SVN updates:
- urllib raises IOError if the servers response contains an invalid HTTP status line.
Augh. Wait, that's not strong enough, let me try again: AUGH.
In fact, it gets worse. To quote from the urrlib2 SVN source
code's comment about its URLError
error class:
URLError is a sub-type of IOError, but it doesn't share any of the implementation. [...]
(urllib2 also directly raises mis-formatted IOError
exceptions for
some things.)
Python's IOError
and OSError
have a very specific purpose; they
report low level operating system errors. That is the only thing they
should be used for, most especially if you are not going to carefully
mimic the existing exception object format (which you can't do, because
you don't have a real errno
value). Having an alleged IOError object
that looks nothing like real IOError objects is actively offensive,
especially when it is in the standard library.
What these people have done, whether they realize it or not, is to turn
IOError exception objects into nothing more than strings, because
these modules have insured that there is no higher structure that you
can count on an IOError instance having. Unfortunately the relevant
Python documentation
does not mention this, and continues to mislead the innocent into
believing that when they catch an IOError exception they can do useful
things like look at its errno
or strerror
attribute.
Or, to boil it down: never raise or subclass IOError, OSError, or EnvironmentError.
(This applies to EnvironmentError
as a whole because using it in an
except
clause is the common way to catch both IOError and OSError at
once.)
The only exception is if you are somehow directly calling a C library
function (that is documented as setting errno
on failures, which not
everything does), in which case you should do the research to exactly
mimic how the Python core code does it.
To my horror, urllib2 is hardly the only offender; there are even some in C level modules (in bz2module.c and zipimport.c). But that doesn't excuse them making the situation worse; in fact they should be moving towards making the situation better. Even with backwards compatibility concerns they could have raised URLError instead of IOError directly (or taken the opportunity to introduce a proper error class if they felt URLError was inapplicable).
(This rant has been brought to you by my attempt to catch up on Planet Python.)
|
|