Python: warnings and deprecation

Aside the logging library resides the less known warning library. The former is meant to log events related to execution whereas the later is meant to warn more or less about improper module usage or deprecated functions. By default, most warnings are displayed once, meaning that they will not clutter your logs by being shown repeatedly. However, some are “ignored by default”, hence not displayed at all. This is where the important difference with logging is: the control you get over them at the command line level.

When you launch your python application, you can specify how warnings should be handled with the “-W” flag. It means that when you run your tests you may want to use “-W once” to display all warnings at least once and all really means all so it includes the DeprecationWarning, PendingDeprecationWarning and ImportWarning. The more rigorous parameter is “error” which will turn warnings into exceptions, making sure you will catch all of them.

Here is a very basic code example.

import warnings

def foo():
    warnings.warn("Foo warning")
    warnings.warn("Deprecated thing!", DeprecationWarning)

foo()
foo() # calling it a second time
print("Normal end of program")

And when you run it:

%> python test.py
test.py:4: UserWarning: Foo warning
  warnings.warn("Foo warning")
Normal end of program

The second warning is not displayed because by default DeprecationWarning is muted. Now specifying the “-W once” flag will display them both.

%> python -W once test.py
test.py:4: UserWarning: Foo warning
  warnings.warn("Foo warning")
test.py:5: DeprecationWarning: Deprecated thing!
  warnings.warn("Deprecated thing!", DeprecationWarning)
Normal end of program

I now use the “-W once” whenever I can. It’s especially handy to catch problems early if you intend to upgrade a module to a new version.

Leave a Reply