Reputation: 8317
I am trying to raise a Warning in Python without making the program crash / stop / interrupt.
I use the following simple function to check if the user passed a non-zero number to it. If so, the program should warn them, but continue as per normal. It should work like the code below, but should use class Warning()
, Error()
or Exception()
instead of printing the warning out manually.
def is_zero(i):
if i != 0:
print "OK"
else:
print "WARNING: the input is 0!"
return i
If I use the code below and pass 0 to the function, the program crashes and the value is never returned. Instead, I want the program to continue normally and just inform the user that he passed 0 to the function.
def is_zero(i):
if i != 0:
print "OK"
else:
raise Warning("the input is 0!")
return i
I want to be able to test that a warning has been thrown testing it by unittest. If I simply print the message out, I am not able to test it with assertRaises in unittest.
Upvotes: 412
Views: 376410
Reputation: 10606
Just a small demonstration snippet
I was a bit puzzled how to use warnings.warn
, so I provide here a short demo. Note how print("code running after warning")
is executed / not executed after warnings.warn
/ raise UserWarning
.
Also warnings.warn
prints the warning message only once.
>>> import warnings
>>>
>>> warnings.warn("test warning"); print("code running after warning")
<stdin>:1: UserWarning: test warning
code running after warning
>>>
>>> raise UserWarning('test warning'); print("code running after warning")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UserWarning: test warning
>>>
>>> warnings.warn("test warning"); print("code running after warning")
code running after warning
Upvotes: 10
Reputation: 63312
By default, unlike an exception, a warning doesn't interrupt.
After import warnings
, it is possible to specify a Warnings class when generating a warning. If one is not specified, it is literally UserWarning
by default.
>>> warnings.warn('This is a default warning.')
<string>:1: UserWarning: This is a default warning.
To simply use a preexisting class instead, e.g. DeprecationWarning
:
>>> warnings.warn('This is a particular warning.', DeprecationWarning)
<string>:1: DeprecationWarning: This is a particular warning.
Creating a custom warning class is similar to creating a custom exception class:
>>> class MyCustomWarning(UserWarning):
... pass
...
... warnings.warn('This is my custom warning.', MyCustomWarning)
<string>:1: MyCustomWarning: This is my custom warning.
For testing, consider assertWarns
or assertWarnsRegex
.
As an alternative, especially for standalone applications, consider the logging
module. It can log messages having a level of debug, info, warning, error, etc. Log messages having a level of warning or higher are by default printed to stderr.
Upvotes: 123
Reputation: 319601
You shouldn't raise
the warning, you should be using warnings
module. By raising it you're generating error, rather than warning.
Upvotes: 275
Reputation: 7217
import warnings
warnings.warn("Warning...........Message")
See the python documentation: here
Upvotes: 603