SethMMorton
SethMMorton

Reputation: 48745

TypeError when chaining exception from a warning

I am trying to catch a warning that is raised as an error by applying the 'error' filter of warnings.simplefilter. A minimum working example is given below:

>>> import warnings
>>> warnings.simplefilter('error')
>>> try:
...     warnings.warn('test')
... except UserWarning:
...     raise ValueError
...
ValueError: 

This works fine, but if I want to chain this so that the traceback from the warning is included, I get the following TypeError:

>>> import sys
>>> try:
...     warnings.warn('test')
... except UserWarning:
...     raise ValueError from sys.exc_info()[2]
...
TypeError: exception causes must derive from BaseException

It seems that even though I am raising a class derived from BaseException (i.e. the ValueError), the information from the traceback from the UserWarning seems to be tricking Python into thinking I am still raising the UserWarning.

Is this the expected behavior? If so, is there a good workaround?

I am on Python 3.4.3.

Upvotes: 0

Views: 299

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1122342

You are trying to use the traceback object as the exception:

raise ValueError from sys.exc_info()[2]

sys.exc_info() returns a tuple of (ExceptionType, exception_instance, traceback); you'd want index 1 here (remember Python counts indices from 0!):

raise ValueError from sys.exc_info()[1]

Much better, capture the exception instance in a variable directly:

try:
    warnings.warn('test')
except UserWarning as warning:
    raise ValueError from warning

That way you don't have to count out tuple indices.

When you set the warnings filter to 'error', the exceptions are subclasses of the Warning exception class, which inherits from Exception, see the Exception Hierachy section.

Upvotes: 1

Related Questions