Movatterモバイル変換


[0]ホーム

URL:


Following system colour schemeSelected dark colour schemeSelected light colour scheme

Python Enhancement Proposals

PEP 3109 – Raising Exceptions in Python 3000

Author:
Collin Winter <collinwinter at google.com>
Status:
Final
Type:
Standards Track
Created:
19-Jan-2006
Python-Version:
3.0
Post-History:


Table of Contents

Abstract

This PEP introduces changes to Python’s mechanisms for raisingexceptions intended to reduce both line noise and the size of thelanguage.

Rationale

One of Python’s guiding maxims is“there should be one – andpreferably only one – obvious way to do it”. Python 2.x’sraise statement violates this principle, permitting multipleways of expressing the same thought. For example, these statementsare equivalent:

raiseE,VraiseE(V)

There is a third form of theraise statement, allowing arbitrarytracebacks to be attached to an exception[1]:

raiseE,V,T

where T is a traceback. As specified inPEP 344,exception objects in Python 3.x will possess a__traceback__attribute, admitting this translation of the three-expressionraise statement:

raiseE,V,T

is translated to

e=E(V)e.__traceback__=Traisee

Using these translations, we can reduce theraise statement fromfour forms to two:

  1. raise (with no arguments) is used to re-raise the activeexception in anexcept suite.
  2. raiseEXCEPTION is used to raise a new exception. This form hastwo sub-variants:EXCEPTION may be an exception class or aninstance of an exception class; valid exception classes areBaseException and its subclasses (PEP 352). IfEXCEPTIONis a subclass, it will be called with no arguments to obtainan exception instance.

    To raise anything else is an error.

There is a further, more tangible benefit to be obtained through thisconsolidation, as noted by A.M. Kuchling[2].

PEP8doesn't express any preference between thetwoformsofraisestatements:raiseValueError,'blah'raiseValueError("blah")Ilikethesecondformbetter,becauseiftheexceptionargumentsarelongorincludestringformatting,youdon't need to use linecontinuationcharactersbecauseofthecontainingparens.

The BDFL has concurred[3] and endorsed theconsolidation of the severalraise forms.

Grammar Changes

In Python 3, the grammar forraise statements will changefrom[1]

raise_stmt:'raise'[test[','test[','test]]]

to

raise_stmt:'raise'[test]

Changes to Builtin Types

Because of its relation to exception raising, the signature for thethrow() method on generator objects will change, dropping theoptional second and third parameters. The signature thus changes (PEP 342)from

generator.throw(E,[V,[T]])

to

generator.throw(EXCEPTION)

WhereEXCEPTION is either a subclass ofBaseException or aninstance of a subclass ofBaseException.

Semantic Changes

In Python 2, the followingraise statement is legal

raise((E1,(E2,E3)),E4),V

The interpreter will take the tuple’s first element as the exceptiontype (recursively), making the above fully equivalent to

raiseE1,V

As of Python 3.0, support for raising tuples like this will bedropped. This change will bringraise statements into line withthethrow() method on generator objects, which already disallowsthis.

Compatibility Issues

All two- and three-expressionraise statements will requiremodification, as will all two- and three-expressionthrow() callson generators. Fortunately, the translation from Python 2.x toPython 3.x in this case is simple and can be handled mechanicallyby Guido van Rossum’s 2to3 utility[4] using theraise andthrow fixers ([5],[6]).

The following translations will be performed:

  1. Zero- and one-expressionraise statements will be leftintact.
  2. Two-expressionraise statements will be converted from
    raiseE,V

    to

    raiseE(V)

    Two-expressionthrow() calls will be converted from

    generator.throw(E,V)

    to

    generator.throw(E(V))

    See point #5 for a caveat to this transformation.

  3. Three-expressionraise statements will be converted from
    raiseE,V,T

    to

    e=E(V)e.__traceback__=Traisee

    Three-expressionthrow() calls will be converted from

    generator.throw(E,V,T)

    to

    e=E(V)e.__traceback__=Tgenerator.throw(e)

    See point #5 for a caveat to this transformation.

  4. Two- and three-expressionraise statements whereE is atuple literal can be converted automatically using2to3’sraise fixer.raise statements whereE is a non-literaltuple, e.g., the result of a function call, will need to beconverted manually.
  5. Two- and three-expressionraise statements whereE is anexception class andV is an exception instance will needspecial attention. These cases break down into two camps:
    1. raiseE,V as a long-hand version of the zero-argumentraise statement. As an example, assuming F is a subclassof E
      try:something()exceptFasV:raiseF(V)exceptEasV:handle(V)

      This would be better expressed as

      try:something()exceptF:raiseexceptEasV:handle(V)
    2. raiseE,V as a way of “casting” an exception to anotherclass. Taking an example fromdistutils.compiler.unixcompiler
      try:self.spawn(pp_args)exceptDistutilsExecErrorasmsg:raiseCompileError(msg)

      This would be better expressed as

      try:self.spawn(pp_args)exceptDistutilsExecErrorasmsg:raiseCompileErrorfrommsg

      Using theraise...from... syntax introduced inPEP 344.

Implementation

This PEP was implemented in revision 57783[7].

References

[1] (1,2)
http://docs.python.org/reference/simple_stmts.html#raise
[2]
https://mail.python.org/pipermail/python-dev/2005-August/055187.html
[3]
https://mail.python.org/pipermail/python-dev/2005-August/055190.html
[4]
http://svn.python.org/view/sandbox/trunk/2to3/
[5]
http://svn.python.org/view/sandbox/trunk/2to3/fixes/fix_raise.py
[6]
http://svn.python.org/view/sandbox/trunk/2to3/fixes/fix_throw.py
[7]
http://svn.python.org/view/python/branches/py3k/Include/?rev=57783&view=rev

Copyright

This document has been placed in the public domain.


Source:https://github.com/python/peps/blob/main/peps/pep-3109.rst

Last modified:2025-02-01 08:59:27 GMT


[8]ページ先頭

©2009-2025 Movatter.jp