Raising and handling Exceptions

suggest change

This is the Python 2 syntax, note the commas , on the raise and except lines:

try:
    raise IOError, "input/output error"
except IOError, exc:
    print exc

In Python 3, the , syntax is dropped and replaced by parenthesis and the as keyword:

try:
    raise IOError("input/output error")
except IOError as exc:
    print(exc)

For backwards compatibility, the Python 3 syntax is also available in Python 2.6 onwards, so it should be used for all new code that does not need to be compatible with previous versions.

Python 3 also adds exception chaining, wherein you can signal that some other exception was the cause for this exception. For example

try:
    file = open('database.db')
except FileNotFoundError as e:
    raise DatabaseError('Cannot open {}') from e

The exception raised in the except statement is of type DatabaseError, but the original exception is marked as the __cause__ attribute of that exception. When the traceback is displayed, the original exception will also be displayed in the traceback:

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
FileNotFoundError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
DatabaseError('Cannot open database.db')

If you throw in an except block without explicit chaining:

try:
   file = open('database.db')
except FileNotFoundError as e:
   raise DatabaseError('Cannot open {}')

The traceback is

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
FileNotFoundError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
DatabaseError('Cannot open database.db')

Neither one is supported in Python 2.x; the original exception and its traceback will be lost if another exception is raised in the except block. The following code can be used for compatibility:

import sys
import traceback

try:
    funcWithError()
except:
    sys_vers = getattr(sys, 'version_info', (0,))
    if sys_vers < (3, 0):
        traceback.print_exc()
    raise Exception("new exception")

To “forget” the previously thrown exception, use raise from None

try:
    file = open('database.db')
except FileNotFoundError as e:
    raise DatabaseError('Cannot open {}') from None

Now the traceback would simply be

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
DatabaseError('Cannot open database.db')

Or in order to make it compatible with both Python 2 and 3 you may use the six package like so:

import six
try:
    file = open('database.db')
except FileNotFoundError as e:
    six.raise_from(DatabaseError('Cannot open {}'), None)

Feedback about page:

Feedback:
Optional: your email if you want me to get back to you:


Incompatibilities moving from Python 2 to Python 3:
* Raising and handling Exceptions
* map

Table Of Contents
2 Filter
3 List
7 Loops
22 Reduce
27 Classes
31 Set
39 Incompatibilities moving from Python 2 to Python 3
42 Tuple
45 Enum
62 Sockets
89 urllib
92 Idioms
104 Stack
105 Profiling
109 Logging
111 os module
118 Mixins
120 ArcPy
126 Arrays
132 2to3 tool
135 Unicode
138 Neo4j
140 Curses
141 Templates
145 heapq
146 tkinter
154 Audio
155 pyglet
157 ijson
160 Flask
161 Groupby
163 pygame
165 hashlib
166 Gzip
167 ctypes
185 pyaudio
186 shelve