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 first step of the resolution is to coalesce existing exception types.
The following changes are proposed: 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 mmap.error to OSError
* alias both WindowsError and VMSError to OSError * alias both WindowsError and VMSError to OSError
* alias OSError to IOError * alias IOError to OSError
* coalesce EnvironmentError into IOError * coalesce EnvironmentError into OSError
Each of these changes doesn't preserve exact compatibility, but it does Each of these changes doesn't preserve exact compatibility, but it does
preserve *useful compatibility* (see "compatibility" section above). 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 is accepted in full. In this case, the IO exception sub-hierarchy would
become:: become::
+-- IOError (replacing OSError, WindowsError, EnvironmentError, etc.) +-- OSError (replacing IOError, WindowsError, EnvironmentError, etc.)
+-- io.BlockingIOError +-- io.BlockingIOError
+-- io.UnsupportedOperation (also inherits from ValueError) +-- io.UnsupportedOperation (also inherits from ValueError)
+-- socket.gaierror +-- 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 explained in the rationale_ section, but it also allows for a better
and more complete resolution of `Step 2`_ (see Prerequisite_). and more complete resolution of `Step 2`_ (see Prerequisite_).
The rationale for keeping ``IOError`` as the official name for generic The rationale for keeping ``OSError`` as the official name for generic
OS-related exceptions is the survey in `Appendix B`_, which shows it is the OS-related exceptions is that it, precisely, is more generic than ``IOError``.
dominant error today in the standard library. ``EnvironmentError`` might ``EnvironmentError`` is more tedious to type and also much lesser-known.
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 The survey in `Appendix B`_ shows that IOError is the dominant
being ten times more popular than EnvironmentError in user code, and error today in the standard library. As for third-party Python code,
three times more popular than OSError [3]_. 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 Exception attributes
-------------------- --------------------
@ -270,7 +273,7 @@ Exception attributes
Coalescing WindowsError would mean the ``winerror`` attribute would be Coalescing WindowsError would mean the ``winerror`` attribute would be
present on all platforms, just set to ``None`` if the platform present on all platforms, just set to ``None`` if the platform
isn't Windows. Indeed, ``errno``, ``filename`` and ``strerror`` can all 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. by Python code.
Deprecation of names 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 following drawing tries to sum up the proposed additions, along with
the corresponding errno values (where applicable). The root of the 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:: shown::
+-- BlockingIOError EAGAIN, EALREADY, EWOULDBLOCK, EINPROGRESS +-- 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 The first possibility is to adapt the ``PyErr_SetFromErrno()`` family
of functions (``PyErr_SetFromWindowsErr()`` under Windows) to raise the of functions (``PyErr_SetFromWindowsErr()`` under Windows) to raise the
appropriate ``IOError`` subclass. This wouldn't cover, however, Python appropriate OSError subclass. This wouldn't cover, however, Python
code raising IOError directly, using the following idiom (seen in code raising OSError directly, using the following idiom (seen in
``Lib/tempfile.py``):: ``Lib/tempfile.py``)::
raise IOError(_errno.EEXIST, "No usable temporary file name found") raise IOError(_errno.EEXIST, "No usable temporary file name found")
A second possibility, suggested by Marc-Andre Lemburg, is to adapt A second possibility, suggested by Marc-Andre Lemburg, is to adapt
``IOError.__new__`` to instantiate the appropriate subclass. This would ``OSError.__new__`` to instantiate the appropriate subclass. This has
have the benefit of also covering Python code such as the above. the benefit of also covering Python code such as the above.
Possible objections 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, It has been successfully tested on a variety of systems: Linux, Windows,
OpenIndiana and FreeBSD buildbots. 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 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 to allow passing the Windows error code (which is different from the POSIX
errno). The fourth argument is stored as ``winerror`` and its POSIX errno). The fourth argument is stored as ``winerror`` and its POSIX
translation as ``errno``. The ``PyErr_SetFromWindowsErr*`` functions have translation as ``errno``. The ``PyErr_SetFromWindowsErr*`` functions have
been adapted to use the right constructor call. been adapted to use the right constructor call.
A slight complication is when the ``PyErr_SetExcFromWindowsErr*`` functions 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 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 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 for EPIPE), which it does now. For non-socket error codes, this only occurs