Update PEP to cover the deprecation of BaseException.message in Python 2.6.
This commit is contained in:
parent
e3aab6db4b
commit
ba82685d7d
167
pep-0352.txt
167
pep-0352.txt
|
@ -2,8 +2,7 @@ PEP: 352
|
|||
Title: Required Superclass for Exceptions
|
||||
Version: $Revision$
|
||||
Last-Modified: $Date$
|
||||
Author: Brett Cannon <brett@python.org>
|
||||
Guido van Rossum <guido@python.org>
|
||||
Author: Brett Cannon, Guido van Rossum
|
||||
Status: Final
|
||||
Type: Standards Track
|
||||
Content-Type: text/x-rst
|
||||
|
@ -15,16 +14,14 @@ Abstract
|
|||
========
|
||||
|
||||
In Python 2.4 and before, any (classic) class can be raised as an
|
||||
exception. The plan is to allow new-style classes starting in Python
|
||||
2.5, but this makes the problem worse -- it would mean *any* class (or
|
||||
instance) can be raised! (This is not the case in the final version;
|
||||
only built-in exceptions can be new-style which means you need to
|
||||
inherit from a built-in exception to have user-defined exceptions also
|
||||
be new-style) This is a problem because it
|
||||
prevents any guarantees from being made about the interface of exceptions.
|
||||
exception. The plan for 2.5 was to allow new-style classes, but this
|
||||
makes the problem worse -- it would mean *any* class (or
|
||||
instance) can be raised! This is a problem as it prevents any
|
||||
guarantees from being made about the interface of exceptions.
|
||||
This PEP proposes introducing a new superclass that all raised objects
|
||||
must inherit from. Imposing the restriction will allow a standard
|
||||
interface for exceptions to exist that can be relied upon.
|
||||
interface for exceptions to exist that can be relied upon. It also
|
||||
leads to a known hierarchy for all exceptions to adhere to.
|
||||
|
||||
One might counter that requiring a specific base class for a
|
||||
particular interface is unPythonic. However, in the specific case of
|
||||
|
@ -40,13 +37,13 @@ currently stands, all exceptions in the built-in namespace inherit
|
|||
from Exception. This is a problem since this includes two exceptions
|
||||
(KeyboardInterrupt and SystemExit) that often need to be excepted from
|
||||
the application's exception handling: the default behavior of shutting
|
||||
the interpreter down with resp. Without a traceback is usually more
|
||||
desirable than whatever the application might do (with the possible
|
||||
exception of applications that emulate Python's interactive command
|
||||
loop with ``>>>`` prompt). Changing it so that these two exceptions
|
||||
inherit from the common superclass instead of Exception will make it
|
||||
easy for people to write ``except`` clauses that are not overreaching
|
||||
and not catch exceptions that should propagate up.
|
||||
the interpreter down without a traceback is usually more desirable than
|
||||
whatever the application might do (with the possible exception of
|
||||
applications that emulate Python's interactive command loop with
|
||||
``>>>`` prompt). Changing it so that these two exceptions inherit
|
||||
from the common superclass instead of Exception will make it easy for
|
||||
people to write ``except`` clauses that are not overreaching and not
|
||||
catch exceptions that should propagate up.
|
||||
|
||||
This PEP is based on previous work done for PEP 348 [#pep348]_.
|
||||
|
||||
|
@ -55,8 +52,7 @@ Requiring a Common Superclass
|
|||
=============================
|
||||
|
||||
This PEP proposes introducing a new exception named BaseException that
|
||||
is a new-style class and has a single attribute, ``message`` (that
|
||||
will cause the deprecation of the existing ``args`` attribute) Below
|
||||
is a new-style class and has a single attribute, ``args``. Below
|
||||
is the code as the exception will work in Python 3.0 (how it will
|
||||
work in Python 2.x is covered in the `Transition Plan`_ section)::
|
||||
|
||||
|
@ -64,46 +60,36 @@ work in Python 2.x is covered in the `Transition Plan`_ section)::
|
|||
|
||||
"""Superclass representing the base of the exception hierarchy.
|
||||
|
||||
Provides a 'message' attribute that contains either the single
|
||||
argument to the constructor or the empty string. This attribute
|
||||
is used in the string representation for the
|
||||
exception. This is so that it provides the extra details in the
|
||||
traceback.
|
||||
|
||||
Provides an 'args' attribute that contains all arguments passed
|
||||
to the constructor. Suggested practice, though, is that only a
|
||||
single string argument be passed to the constructor.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, message=''):
|
||||
"""Set the 'message' attribute'"""
|
||||
self.message = message
|
||||
def __init__(self, *args):
|
||||
"""Set the 'args' attribute'"""
|
||||
self.args = args
|
||||
|
||||
def __str__(self):
|
||||
"""Return the str of 'message'"""
|
||||
return str(self.message)
|
||||
"""Return the str of
|
||||
``args[0] if len(args) == 1 else args``."""
|
||||
if len(self.args) == 1:
|
||||
return str(self.args[0])
|
||||
else:
|
||||
return str(self.args)
|
||||
|
||||
def __repr__(self):
|
||||
return "%s(%s)" % (self.__class__.__name__, repr(self.message))
|
||||
return "%s(*%s)" % (self.__class__.__name__, repr(self.args))
|
||||
|
||||
The ``message`` attribute will contain either the first argument
|
||||
passed in at instantiation of the object or the empty string if no
|
||||
arguments were passed in. The attribute is meant to act as a common
|
||||
location to store any message that is to be passed along
|
||||
with the exception that goes beyond the location of where the exception
|
||||
occurred and the exception's type.
|
||||
|
||||
No restriction is placed upon what may be passed in for ``message``
|
||||
No restriction is placed upon what may be passed in for ``args``
|
||||
for backwards-compatibility reasons. In practice, though, only
|
||||
strings should be used. This keeps the string representation of the
|
||||
exception to be a useful message about the exception that is
|
||||
human-readable. Including programmatic information (e.g., an error
|
||||
code number) should be stored as a separate attribute in a subclass.
|
||||
|
||||
The ``args`` attribute is deprecated. While allowing multiple
|
||||
arguments to be passed can be helpful, it is in no way essential. It
|
||||
also does not make it clear which argument is going to be represented
|
||||
by the ``__str__`` method. Restricting initialization to accepting a
|
||||
single argument keeps the API simple and clear. This also means
|
||||
providing a ``__getitem__`` method is unneeded for exceptions and thus
|
||||
will be deprecated as well.
|
||||
a single string argument should be used. This keeps the string
|
||||
representation of the exception to be a useful message about the
|
||||
exception that is human-readable; this is why the ``__str__`` method
|
||||
special-cases on length-1 ``args`` value. Including programmatic
|
||||
information (e.g., an error code number) should be stored as a
|
||||
separate attribute in a subclass.
|
||||
|
||||
The ``raise`` statement will be changed to require that any object
|
||||
passed to it must inherit from BaseException. This will make sure
|
||||
|
@ -183,37 +169,18 @@ Here is BaseException as implemented in the 2.x series::
|
|||
|
||||
"""Superclass representing the base of the exception hierarchy.
|
||||
|
||||
Provides a 'message' attribute that contains any single argument
|
||||
passed in during instantiation. If more than one argument is
|
||||
passed, it is set to the empty string. It is meant to represent
|
||||
any message (usually some text) that should be printed out with
|
||||
the traceback. Unfortunately, for backwards-compatibility, the
|
||||
'args' attribute (discussed below) is used for printing out to
|
||||
tracebacks.
|
||||
|
||||
The 'args' attribute and __getitem__ method are provided for
|
||||
backwards-compatibility and will be deprecated at some point.
|
||||
The __getitem__ method is provided for backwards-compatibility
|
||||
and will be deprecated at some point. The 'message' attribute
|
||||
is also deprecated.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, *args):
|
||||
"""Set 'message' and 'args' attribute.
|
||||
|
||||
'args' will eventually be deprecated. But it is still used
|
||||
when printing out tracebacks for backwards-compatibility.
|
||||
Once 'args' is removed, though, 'message' will be used instead.
|
||||
|
||||
"""
|
||||
"""Set the 'args' attribute."""
|
||||
self.args = args
|
||||
self.message = args[0] if args else ''
|
||||
|
||||
def __str__(self):
|
||||
"""Return the str of args[0] or args, depending on length.
|
||||
|
||||
Once 'args' has been removed, 'message' will be used
|
||||
exclusively for the str representation for exceptions.
|
||||
|
||||
"""
|
||||
"""Return the str of args[0] or args, depending on length."""
|
||||
return str(self.args[0]
|
||||
if len(self.args) <= 1
|
||||
else self.args)
|
||||
|
@ -231,6 +198,16 @@ Here is BaseException as implemented in the 2.x series::
|
|||
"""
|
||||
return self.args[index]
|
||||
|
||||
def _get_message(self):
|
||||
"""Method for 'message' property."""
|
||||
warnings.warn("the 'message' attribute has been deprecated "
|
||||
"since Python 2.6")
|
||||
return self.args[0] if len(args) == 1 else ''
|
||||
|
||||
message = property(_get_message)
|
||||
|
||||
|
||||
|
||||
|
||||
Deprecation of features in Python 2.9 is optional. This is because it
|
||||
is not known at this time if Python 2.9 (which is slated to be the
|
||||
|
@ -242,7 +219,7 @@ the proposed deprecation warnings for Python 2.9 will be revisited
|
|||
when development of that version begins to determine if they are still
|
||||
desired.
|
||||
|
||||
* Python 2.5
|
||||
* Python 2.5 [done]
|
||||
|
||||
- all standard exceptions become new-style classes
|
||||
|
||||
|
@ -254,35 +231,56 @@ desired.
|
|||
|
||||
* Python 2.6
|
||||
|
||||
- deprecate catching string exceptions
|
||||
- deprecate catching string exceptions [done]
|
||||
|
||||
- deprecate ``message`` attribute (see `Retracted Ideas`_)
|
||||
|
||||
* Python 2.7
|
||||
|
||||
- deprecate raising exceptions that do not inherit from BaseException
|
||||
|
||||
- remove ``message`` attribute
|
||||
|
||||
* Python 2.8
|
||||
|
||||
- deprecate catching exceptions that do not inherit from BaseException
|
||||
|
||||
* Python 2.9
|
||||
|
||||
- deprecate ``args`` and ``__getitem__`` (optional)
|
||||
- deprecate ``__getitem__`` (optional)
|
||||
|
||||
* Python 3.0
|
||||
|
||||
- drop everything that was deprecated above:
|
||||
|
||||
+ string exceptions (both raising and catching)
|
||||
+ string exceptions (both raising and catching) [done]
|
||||
|
||||
+ all exceptions must inherit from BaseException
|
||||
+ all exceptions must inherit from BaseException [done]
|
||||
|
||||
+ drop ``args`` and ``__getitem__``
|
||||
+ drop ``__getitem__``, ``message``
|
||||
|
||||
|
||||
Implementation
|
||||
==============
|
||||
Retracted Ideas
|
||||
===============
|
||||
|
||||
A previous version of this PEP that was implemented in Python 2.5
|
||||
included a 'message' attribute on BaseException. Its purpose was to
|
||||
begin a transition to BaseException accepting only a single argument.
|
||||
This was to tighten the interface and to force people to use
|
||||
attributes in subclasses to carry arbitrary information with an
|
||||
exception instead of cramming it all into ``args``.
|
||||
|
||||
Unfortunately, while implementing the removal of the ``args``
|
||||
attribute in Python 3.0 at the PyCon 2007 sprint
|
||||
[#pycon2007-sprint-email]_, it was discovered that the transition was
|
||||
very painful, especially for C extension modules. It was decided that
|
||||
it would be better to deprecate the ``message`` attribute in
|
||||
Python 2.6 (and remove in Python 2.7 and Python 3.0) and consider a
|
||||
more long-term transition strategy in Python 3.0 to remove
|
||||
multiple-argument support in BaseException in preference of accepting
|
||||
only a single argument. Thus the introduction of ``message`` and the
|
||||
original deprecation of ``args`` has been retracted.
|
||||
|
||||
The initial implementation of this PEP has been checked into Python 2.5 .
|
||||
|
||||
References
|
||||
==========
|
||||
|
@ -296,6 +294,9 @@ References
|
|||
.. [#SF_1104669] SF patch #1104669 (new-style exceptions)
|
||||
http://www.python.org/sf/1104669
|
||||
|
||||
.. [#pycon2007-sprint-email] python-3000 email ("How far to go with cleaning up exceptions")
|
||||
http://mail.python.org/pipermail/python-3000/2007-March/005911.html
|
||||
|
||||
|
||||
Copyright
|
||||
=========
|
||||
|
|
Loading…
Reference in New Issue