Question

I want a warning raise for each problem detected in a loop, but the warning is only raised once, the first time. For example :

import warnings

for i in range(10):
   print i
   warnings.warn('this is a warning message')

I expect :

0
UserWarning: this is a warning message
1
UserWarning: this is a warning message
2
UserWarning: this is a warning message
3
UserWarning: this is a warning message
4

but the result is :

0
__main__:4: UserWarning: this is a warning message
1
2
3
4

Why do I have only one warning? How can I get a warning for each iteration?

Was it helpful?

Solution

It is by design. See the docs at http://docs.python.org/2/library/warnings.html:

Repetitions of a particular warning for the same source location are typically suppressed.

You can override this behavior by adding a filter with the keyword always, as in:

import warnings

warnings.simplefilter('always', UserWarning)
for i in range(10):
   print i
   warnings.warn('this is a warning message')

OTHER TIPS

From the warnings module documentation:

Repetitions of a particular warning for the same source location are typically suppressed.

This is by design.

I'd not use the warnings module if you want your message to be printed always; you could reset the filters (using warnings.resetwarnings(), but that's very much not recommended as you'd discard any user-configured filters too. You could add an explicit filter that always allows the message with the warnings.simplefilter() function:

warnings.simplefilter('always', UserWarning)

but I'd just write to sys.stderr directly instead.

It'd already mentioned in the other answers that, by default, each warning is printed once for each source file where it occurs. However, you could change that easily from the command line. Invoke the interpreter by saying python -W all:

$ python -W all
Python 2.7.6 (default, Mar 16 2014, 23:42:21)
[GCC 4.5.3] on netbsd6
Type "help", "copyright", "credits" or "license" for more information.
>>> import warnings
>>> for i in range(10):
   print i
   warnings.warn('this is a warning message')... ...
...
0
__main__:3: UserWarning: this is a warning message
1
__main__:3: UserWarning: this is a warning message
2
__main__:3: UserWarning: this is a warning message
3
__main__:3: UserWarning: this is a warning message
4
__main__:3: UserWarning: this is a warning message
5
__main__:3: UserWarning: this is a warning message
6
__main__:3: UserWarning: this is a warning message
7
__main__:3: UserWarning: this is a warning message
8
__main__:3: UserWarning: this is a warning message
9
__main__:3: UserWarning: this is a warning message
>>>

The default filters prevents multiple occurrences of your warning - you can override the filter using simplefilter.

import warnings

warnings.simplefilter("always")
for i in range(10):
    print i
    warnings.warn('this is a warning message')
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top