Reputation: 48745
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
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