OSError will be the canonical name, not IOError

This commit is contained in:
Antoine Pitrou 2011-08-29 18:36:36 +02:00
parent cb30d24c13
commit 437825a070
1 changed files with 23 additions and 20 deletions

View File

@ -228,11 +228,11 @@ Step 1: coalesce exception types
The first step of the resolution is to coalesce existing exception types.
The following changes are proposed:
* alias both socket.error and select.error to IOError
* alias both socket.error and select.error to OSError
* alias mmap.error to OSError
* alias both WindowsError and VMSError to OSError
* alias OSError to IOError
* coalesce EnvironmentError into IOError
* alias IOError to OSError
* coalesce EnvironmentError into OSError
Each of these changes doesn't preserve exact compatibility, but it does
preserve *useful compatibility* (see "compatibility" section above).
@ -242,7 +242,7 @@ it is considered that the greatest impact can be achieved if this first step
is accepted in full. In this case, the IO exception sub-hierarchy would
become::
+-- IOError (replacing OSError, WindowsError, EnvironmentError, etc.)
+-- OSError (replacing IOError, WindowsError, EnvironmentError, etc.)
+-- io.BlockingIOError
+-- io.UnsupportedOperation (also inherits from ValueError)
+-- socket.gaierror
@ -256,13 +256,16 @@ Not only does this first step present the user a simpler landscape as
explained in the rationale_ section, but it also allows for a better
and more complete resolution of `Step 2`_ (see Prerequisite_).
The rationale for keeping ``IOError`` as the official name for generic
OS-related exceptions is the survey in `Appendix B`_, which shows it is the
dominant error today in the standard library. ``EnvironmentError`` might
be more accurate, but it is more tedious to type and also much lesser-known.
As for third-party Python code, Google Code Search shows IOError
being ten times more popular than EnvironmentError in user code, and
three times more popular than OSError [3]_.
The rationale for keeping ``OSError`` as the official name for generic
OS-related exceptions is that it, precisely, is more generic than ``IOError``.
``EnvironmentError`` is more tedious to type and also much lesser-known.
The survey in `Appendix B`_ shows that IOError is the dominant
error today in the standard library. As for third-party Python code,
Google Code Search shows IOError being ten times more popular than
EnvironmentError in user code, and three times more popular than OSError
[3]_. However, with no intention to deprecate IOError in the middle
term, the lesser popularity of OSError is not a problem.
Exception attributes
--------------------
@ -270,7 +273,7 @@ Exception attributes
Coalescing WindowsError would mean the ``winerror`` attribute would be
present on all platforms, just set to ``None`` if the platform
isn't Windows. Indeed, ``errno``, ``filename`` and ``strerror`` can all
already be None, as is often the case when IOError is raised directly
already be None, as is often the case when OSError is raised directly
by Python code.
Deprecation of names
@ -403,7 +406,7 @@ In addition, the following exception class are proposed for inclusion:
The following drawing tries to sum up the proposed additions, along with
the corresponding errno values (where applicable). The root of the
sub-hierarchy (IOError, assuming `Step 1`_ is accepted in full) is not
sub-hierarchy (OSError, assuming `Step 1`_ is accepted in full) is not
shown::
+-- BlockingIOError EAGAIN, EALREADY, EWOULDBLOCK, EINPROGRESS
@ -449,15 +452,15 @@ modules (either standard or third-party).
The first possibility is to adapt the ``PyErr_SetFromErrno()`` family
of functions (``PyErr_SetFromWindowsErr()`` under Windows) to raise the
appropriate ``IOError`` subclass. This wouldn't cover, however, Python
code raising IOError directly, using the following idiom (seen in
appropriate OSError subclass. This wouldn't cover, however, Python
code raising OSError directly, using the following idiom (seen in
``Lib/tempfile.py``)::
raise IOError(_errno.EEXIST, "No usable temporary file name found")
A second possibility, suggested by Marc-Andre Lemburg, is to adapt
``IOError.__new__`` to instantiate the appropriate subclass. This would
have the benefit of also covering Python code such as the above.
``OSError.__new__`` to instantiate the appropriate subclass. This has
the benefit of also covering Python code such as the above.
Possible objections
@ -505,16 +508,16 @@ also tracked on the bug tracker at http://bugs.python.org/issue12555.
It has been successfully tested on a variety of systems: Linux, Windows,
OpenIndiana and FreeBSD buildbots.
One source of trouble has been with the respective constructors of ``IOError``
One source of trouble has been with the respective constructors of ``OSError``
and ``WindowsError``, which were incompatible. The way it is solved is by
keeping the ``IOError`` signature and adding a fourth optional argument
keeping the ``OSError`` signature and adding a fourth optional argument
to allow passing the Windows error code (which is different from the POSIX
errno). The fourth argument is stored as ``winerror`` and its POSIX
translation as ``errno``. The ``PyErr_SetFromWindowsErr*`` functions have
been adapted to use the right constructor call.
A slight complication is when the ``PyErr_SetExcFromWindowsErr*`` functions
are called with ``IOError`` rather than ``WindowsError``: the ``errno``
are called with ``OSError`` rather than ``WindowsError``: the ``errno``
attribute of the exception object would store the Windows error code (such
as 109 for ERROR_BROKEN_PIPE) rather than its POSIX translation (such as 32
for EPIPE), which it does now. For non-socket error codes, this only occurs