Home

__context__ vs __cause__ attributes in exception handling

__context__ vs __cause__ attributes in exception handling

Since Python 3.0, raising an exception in an except block will automatically add the caught exception in the __context__ attribute of the new one. That will cause both exceptions to be printed. Essentially this is a way for the current exception to carry information about the previous exception. For example:

try:
	raise ValueError('ValueError')
except ValueError:
	raise TypeError('TypeError')

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

During handling of the above exception, another exception occurred:

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

You also can add __cause__ to any exception with the raise ... from expression. In the below example you see that message changed:

try:
	raise ValueError('ValueError')
except ValueError as ve:
	raise TypeError('TypeError') from ve

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

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

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

A more sophisticated examples with printing all the private variables we talked so far to better understand the difference:

try:
	try:
		raise ValueError("ValueError")
	except ValueError as first:
		raise TypeError("TypeError")
except TypeError as second:
	print("The exception was", repr(second))
	print("Its __context__ was", repr(second.__context__))
	print("Its __cause__ was", repr(second.__cause__))
The exception was TypeError('TypeError',)
Its __context__ was ValueError('ValueError',)
Its __cause__ was None
try:
	try:
		raise ValueError("ValueError")
	except ValueError as first:
		raise TypeError("TypeError") from first
except TypeError as second:
	print("The exception was", repr(second))
	print("Its __context__ was", repr(second.__context__))
	print("Its __cause__ was", repr(second.__cause__))
The exception was TypeError('TypeError',)
Its __context__ was ValueError('ValueError',)
Its __cause__ was ValueError('ValueError',)
Support author