Chapter 7: Exception Handling and Debugging — Jython Book v1.0 documentation
Issuing Warnings¶
Warnings can be raised at any time in your program and can be used to display
some type of warning message, but they do not necessarily cause execution to
abort. A good example is when you wish to deprecate a method or implementation
but still make it usable for compatibility. You could create a warning to alert
the user and let them know that such methods are deprecated and point them to
the new definition, but the program would not abort. Warnings are easy to
define, but they can be complex if you wish to define rules on them using
filters. Warning filters are used to modify the behavior of a particular
warning. Much like exceptions, there are a number of defined warnings that can
be used for categorizing. In order to allow these warnings to be easily
converted into exceptions, they are all instances of the Exception type.
Remember that exceptions are not necessarily errors, but rather alerts or
messages. For instance, the StopIteration exception is raised by a program to
stop the iteration of a loop…not to flag an error with the program.To issue a warning, you must first import the warnings module into your
program. Once this has been done then it is as simple as making a call to the
warnings.warn() function and passing it a string with the warning message.
However, if you’d like to control the type of warning that is issued, you can
also pass the warning class. Warnings are listed in Table 7-2.Listing 7-21. Issuing a Warning
# Always import the warnings module first import warnings # A couple of examples for setting up warnings warnings.warn("this feature will be deprecated") warnings.warn("this is a more involved warning", RuntimeWarning) # Using A Warning in a Function # Suppose that use of the following function has been deprecated, # warnings can be used to alert the function users # The following function calculates what the year will be if we # add the specified number of days to the current year. Of course, # this is pre-Y2K code so it is being deprecated. We certainly do not # want this code around when we get to year 3000! >>> def add_days(current_year, days): ... warnings.warn("This function has been deprecated as of version x.x", DeprecationWarning) ... num_years = 0 ... if days > 365: ... num_years = days/365 ... return current_year + num_years ... # Calling the function will return the warning that has been set up, # but it does not raise an error...the expected result is still returned. >>> add_days(2009, 450) __main__:2: DeprecationWarning: This function has been deprecated as of version x.x 2010Table 7-2. Python Warning Categories
Warning Description Warning Root warning class UserWarning A user-defined warning DeprecationWarning Warns about use of a deprecated feature SyntaxWarning Syntax issues RuntimeWarning Runtime issues FutureWarning Warns that a particular feature will be changing in a
future releaseImporting the warnings module into your code gives you access to a number of
built-in warning functions that can be used. If you’d like to filter a warning
and change its behavior then you can do so by creating a filter. Table 7-3
lists functions that come with the warnings module.Table 7-3. Warning Functions
Function Description warn(message[,
category[,
stacklevel]])Issues a warning. Parameters include a message
string, the optional category of warning, and the
optional stack level that tells which stack frame the
warning should originate from, usually either the
calling function or the source of the function
itself.warn_explicit(message,
category, filename,
lineno[, module[,
registry]])This offers a more detailed warning message and makes
category a mandatory parameter. filename, lineno, and
module tell where the warning is located. registry
represents all of the current warning filters that
are active.showwarning(message,
category, filename,
lineno[, file])Gives you the ability to write the warning to a file. formatwarning(message,
category, filename,
lineno)Creates a formatted string representing the warning. simplefilter(action[,
category[, lineno[,
append]]])Inserts simple entry into the ordered list of
warnings filters. Regular expressions are not needed
for simplefilter as the filter always matches any
message in any module as long as the category and
line number match. filterwarnings() described below
uses a regular expression to match against warnings.resetwarnings() Resets all of the warning filters. filterwarnings(action[,
message[, category[,
module[, lineno[,
append]]]]])This adds an entry into a warning filter list.
Warning filters allow you to modify the behavior of a
warning. The action in the warning filter can be one
from those listed in Table 7-4, message is a regular
expression, category is the type of a warning to be
issued, module can be a regular expression, lineno is
a line number to match against all lines, append
specifies whether the filter should be appended to
the list of all filters.Table 7-4. Python Filter Actions
Filter Actions ‘always’ Always print warning message ‘default’ Print warning once for each location where warning occurs ‘error’ Converts a warning into an exception ‘ignore’ Ignores the warning ‘module’ Print warning once for each module in which warning occurs ‘once’ Print warning only one time Let’s take a look at a few ways to use warning filters in the examples below.
Listing 7-22. Warning Filter Examples
# Set up a simple warnings filter to raise a warning as an exception >>> warnings.simplefilter('error', UserWarning) >>> warnings.warn('This will be raised as an exception') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/Applications/Jython/jython2.5.1rc2/Lib/warnings.py", line 63, in warn warn_explicit(message, category, filename, lineno, module, registry, File "/Applications/Jython/jython2.5.1rc2/Lib/warnings.py", line 104, in warn_explicit raise message UserWarning: This will be raised as an exception # Turn off all active filters using resetwarnings() >>> warnings.resetwarnings() >>> warnings.warn('This will not be raised as an exception') __main__:1: UserWarning: This will not be raised as an exception # Use a regular expression to filter warnings # In this case, we ignore all warnings containing the word “one” >>> warnings.filterwarnings('ignore', '.*one*.',) >>> warnings.warn('This is warning number zero') __main__:1: UserWarning: This is warning number zero >>> warnings.warn('This is warning number one') >>> warnings.warn('This is warning number two') __main__:1: UserWarning: This is warning number two >>>There can be many different warning filters in use, and each call to the
filterwarnings() function will append another warning to the ordered list of
filters if so desired. The specific warning is matched against each filter
specification in the list in turn until a match is found. In order to see which
filters are currently in use, issue the command print warnings.filters. One can
also specify a warning filter from the command line by use of the –W option.
Lastly, all warnings can be reset to defaults by using the resetwarnings()
function.It is also possible to set up a warnings filter using a command-line argument.
This can be quite useful for filtering warnings on a per-script or per-module
basis. For instance, if you are interested in filtering warnings on a
per-script basis then you could issue the -W command line argument while
invoking the script.