[Python-ideas] PEP 3151 - Reworking the OS and IO exception hierarchy (again)

M.-A. Lemburg mal at egenix.com
Fri Nov 12 00:31:18 CET 2010

Nick Coghlan wrote:
> On Fri, Nov 12, 2010 at 1:03 AM, M.-A. Lemburg <mal at egenix.com> wrote:
>> There's nothing wrong with code such as this:
>> try:
>>  ...
>> except socket.error:
>>  print 'Network problem'
>> except IOError:
>>  print 'File I/O problem'
>> except OSError:
>>  print 'File system problem'
>> You probably have a different use of try-except in mind. Those
>> exception handling blocks are used at various levels in an
>> application and the code run between try-except may well be dealing
>> with sockets and file I/O, but require two different sets of
>> problem resolution or reporting implementations.
>> The PEP breaks such code.
> No, that's the kind of code we're saying is already subtly broken, and
> we're just changing the way it is broken to be far more obvious
> (instead of *sometimes* printing the wrong message based on exactly
> what went wrong, it will instead consistently print the message
> associated with whichever of IOError and OSError is listed first). The
> standard library may have been consistent about IOError vs OSError at
> one point in time, but that time is in the past. Any code which
> doesn't catch (or ignore) them both and treat them as equivalent to
> each other is either already broken (if the try block contains code
> which may raise either exception) or won't be affected by the proposal
> in the PEP (if the try block is guaranteed to raise only the exception
> type already caught by the try block).

I don't follow you.

Example: If I run code that e.g. uses os.fork()
and get an IOError, I don't want to catch that, since this is
likely a programming error of some sort which I don't want to
mask. However, if I get an OSError (the error raised by os.fork()),
I can report this as a resource problem to higher level code
which can then take appropriate action.

Your arguing that because the stdlib has blurred the distinction
between IOError and OSError (as a result of making OSError builtin
rather than letting it live in the os module), it is OK to now
blur the distinction between error handling code that was meant
to run for issues that are related to the actually used functions
and possibly causing the error reporting to malfunction.

Antoine is arguing that simply by relying on the errno you
can write "careful" code. That's not correct. If I write
code that only checks the errno without knowing in which context
this was set, I cannot always make assumptions on what that
errno really means, e.g. EACCES, EBADF or EPERM are used by lots
of C lib and OS functions, so there's no implicit hint to
the subsystem where the error originated.

If we go down that route, we might as well merge TypeError
into ValueError as well, since the distinction between those
has been blurred long before OSError was even introduced.

But we don't do that. And the reason is that we know which
functions or methods return which types of errors and use
that knowledge to direct the flow of error handling into
the right lanes.

Besides, there are lots of functions in the os module that don't do
any I/O in the standard sense - why should those raise an IOError ?
Most of the functions deal with OS services, so the name OSError
is a lot more appropriate.

Note that the same kind of blurring is likely going to happen
for the newly suggested additional exceptions. Sooner or later
people are going to use ConnectionError for all kinds of connections,
not only socket-related ones. Same for TimeoutError and

So in the end, you have to go and check the errno code again,
just to see whether the exception you're looking at really
originated from a socket or file operation which set errno,
provided .errno isn't set to the E-values mentioned in the PEP
per default... or we just merge everything back again into
IOError and leave it to the programmers to find some other
way to signal where the exception originated.

Not very helpful.

Perhaps it's indeed better to clearly draw the line between
IOError and OSError again, like you say, instead of trying to
"fix" things by further blurring information.

Marc-Andre Lemburg

Professional Python Services directly from the Source  (#1, Nov 11 2010)
>>> Python/Zope Consulting and Support ...        http://www.egenix.com/
>>> mxODBC.Zope.Database.Adapter ...             http://zope.egenix.com/
>>> mxODBC, mxDateTime, mxTextTools ...        http://python.egenix.com/

::: Try our new mxODBC.Connect Python Database Interface for free ! ::::

   eGenix.com Software, Skills and Services GmbH  Pastor-Loeh-Str.48
    D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg
           Registered at Amtsgericht Duesseldorf: HRB 46611

More information about the Python-ideas mailing list