Add clarification, as suggested by Nick
This commit is contained in:
parent
37d8aa6639
commit
9677bf7d5d
56
pep-3151.txt
56
pep-3151.txt
|
@ -167,11 +167,31 @@ Compatibility strategy
|
||||||
Reworking the exception hierarchy will obviously change the exact semantics
|
Reworking the exception hierarchy will obviously change the exact semantics
|
||||||
of at least some existing code. While it is not possible to improve on the
|
of at least some existing code. While it is not possible to improve on the
|
||||||
current situation without changing exact semantics, it is possible to define
|
current situation without changing exact semantics, it is possible to define
|
||||||
a narrower type of compatibility, which we will call **useful compatibility**,
|
a narrower type of compatibility, which we will call *useful compatibility*.
|
||||||
and define as follows:
|
|
||||||
|
|
||||||
* *useful compatibility* doesn't make exception catching any narrower, but
|
For this we first must explain what we will call *careful* and *careless*
|
||||||
it can be broader for *naïve* exception-catching code. Given the following
|
exception handling. *Careless* (or "naïve") code is defined as code which
|
||||||
|
blindly catches either of ``OSError``, ``IOError``, ``socket.error``,
|
||||||
|
``mmap.error``, ``WindowsError``, ``select.error`` without cheking the ``errno``
|
||||||
|
attribute. This is because such exception types are much too broad to signify
|
||||||
|
anything. Either of them can be raised for error conditions as diverse as: a
|
||||||
|
bad file descriptor (which will usually indicate a programming error), an
|
||||||
|
unconnected socket (ditto), a socket timeout, a file type mismatch, an invalid
|
||||||
|
argument, a transmission failure, insufficient permissions, a non-existent
|
||||||
|
directory, a full filesystem, etc.
|
||||||
|
|
||||||
|
(moreover, the use of certain of these exceptions is irregular; `Appendix B`_
|
||||||
|
exposes the case of the `select`_ module, which raises different exceptions
|
||||||
|
depending on the implementation)
|
||||||
|
|
||||||
|
*Careful* code is defined as code which, when catching any of the above
|
||||||
|
exceptions, examines the ``errno`` attribute to determine the actual error
|
||||||
|
condition and takes action depending on it.
|
||||||
|
|
||||||
|
The we can define *useful compatibility* as follows:
|
||||||
|
|
||||||
|
* useful compatibility doesn't make exception catching any narrower, but
|
||||||
|
it can be broader for *careless* exception-catching code. Given the following
|
||||||
kind of snippet, all exceptions caught before this PEP will also be
|
kind of snippet, all exceptions caught before this PEP will also be
|
||||||
caught after this PEP, but the reverse may be false::
|
caught after this PEP, but the reverse may be false::
|
||||||
|
|
||||||
|
@ -180,7 +200,7 @@ and define as follows:
|
||||||
except OSError:
|
except OSError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
* *useful compatibility* doesn't alter the behaviour of *careful*
|
* useful compatibility doesn't alter the behaviour of *careful*
|
||||||
exception-catching code. Given the following kind of snippet, the same
|
exception-catching code. Given the following kind of snippet, the same
|
||||||
errors should be silenced or re-raised, regardless of whether this PEP
|
errors should be silenced or re-raised, regardless of whether this PEP
|
||||||
has been implemented or not::
|
has been implemented or not::
|
||||||
|
@ -191,13 +211,13 @@ and define as follows:
|
||||||
if e.errno != errno.ENOENT:
|
if e.errno != errno.ENOENT:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
The rationale for this compromise is that careless (or "naïve") code
|
The rationale for this compromise is that careless code can't really be
|
||||||
can't really be helped, but at least code which "works" won't suddenly
|
helped, but at least code which "works" won't suddenly raise errors and
|
||||||
raise errors and crash. This is important since such code is likely to
|
crash. This is important since such code is likely to be present in
|
||||||
be present in scripts used as cron tasks or automated system administration
|
scripts used as cron tasks or automated system administration programs.
|
||||||
programs.
|
|
||||||
|
|
||||||
Careful code should not be penalized.
|
Careful code, on the other hand, should not be penalized. Actually, one
|
||||||
|
purpose of this PEP is to ease writing careful code.
|
||||||
|
|
||||||
|
|
||||||
.. _Step 1:
|
.. _Step 1:
|
||||||
|
@ -481,6 +501,20 @@ The moratorium in effect on language builtins means this PEP has little
|
||||||
chance to be accepted for Python 3.2.
|
chance to be accepted for Python 3.2.
|
||||||
|
|
||||||
|
|
||||||
|
Implementation
|
||||||
|
==============
|
||||||
|
|
||||||
|
A reference implementation has been started in ``branches/pep-3151`` in the
|
||||||
|
Python SVN repository. For now only `Step 1`_ is implemented, and without
|
||||||
|
the deprecation warnings. However, it shows that coalescing the exception
|
||||||
|
types doesn't produce any significant annoyance in the standard library.
|
||||||
|
The only observed trouble is with the respective constructors of ``IOError``
|
||||||
|
and ``WindowsError``, which are slightly incompatible. The way it is solved
|
||||||
|
is by keeping the ``IOError`` semantics and adding a fourth optional argument
|
||||||
|
to allow passing the Windows error code (which is different from the POSIX
|
||||||
|
errno). All ``PyErr_SetFromWindowsErr*`` functions still do the right thing.
|
||||||
|
|
||||||
|
|
||||||
Possible alternative
|
Possible alternative
|
||||||
====================
|
====================
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue