Welcome to warn’s documentation!

Warn is an experimental module which attempt to provide a more flexible and powerful control over python warnings. It mainly allow you to not only filter warnings depending on the module that trigger the warnings, but to filter depending on where the warning come from.

Direct Usage

Replace your usual import of warnings.warn, warnings.warn_explicit and warnings.filter by the same import from warn, use them as usual except you have some extra options.

To emit a warning:

import warn

warn.warn("I can use the as usual; this is awesone",
          DeprecationWarning,
          stacklevel=1 )

To add a filter a warning, use the filter function as usual:

import warn

warn.filter('default', DeprecationWarning, module='__main__')

Using as long as you do not use warn specific option, using warn.filter should have the exact same effect as calling warnings.filter and affect all emitted warnings.

Extra Functionality

The main extra functionality of the warn module is to be able to filter warnings not only by what _trigger_ them, but what _emit_ them. For example:

# dependency.py

import warn

def deprecated_function():
    # the warning is emitted here
    warn.warning("I am a deprecation warning",
                 DeprecationWarning,
                 stacklevel=2
# downstream.py

from dependency import deprecated_function

def feature():
    # I will trigger the warning.
    deprecated_function()

While the Python standard library only allow to filter by the module that _trigger_ the warning (above downstream module, and this only if deprecated_function set the stacklevel correctly, warn allows you to filter depending on the _emitter_ module (here dependency). To do so use the emodule keyword of warn.filter, which take a string or a regular expression:

import warn

warn.filterwarnings('error', DeprecationWarning, emodule='dependency')

Monkey Patching the standard library

The functionality of warn are usually only available if you are explicitly use the warn exposed functions. Though it might be useful occasionally to use the warn functionality with module that uses the standard library warnings.

For this use case we provide the patch function that will replace monkey patch the standard library and automatically provide warn’s function to all modules that get imported after the patch have been applied.

The teardown function is also provided and attempt to un-patch the warnings. Though any module that have retain a reference to the warn, warn_explicit and filter function will still be using the warn module functionalities.

patch and teardown keep a reference count of how many time each have been called to un-patch only when necessary, it should thus be safe to nest calls.

patch can also be used as a context manager to automatically un-patch on context manager exit.

Import and usage Styleguide

Because of the experimental nature of this module, there is some strange advised style guides. In particular you are encouraged to use the fully qualified name when calling import, both when using the warn module as well as when using the standard library warnings module. For example:

import warnings

warnings.warn('This is a good way of using warning')

########

from warnings import warn

warn('Advance features of `warn` will not be available....')

Monkey patch and compiled module

Compiles modules directly access the C-implementation of the warning module. Monkey Patching thus have no effect. We are aware of the limitation.

How does it work

Python’s warning filter are required to be fives-tuples with restricted types and values, in particular to be compatible with efficient c-implementation of the python standard lib.

In order to interoperate with standard library warnings, when using specific warn’s functionality we actually inject a phony five-tuple which is no-op into warnings.filters and use it as a key for a proxy-dict that store the actual parameters.

This allows complete backward compatibility with the warn module and ensure that in the worse case scenario, the rules you set using the warn module just have no-effects.

We would really welcome any modification into Core Python that allow to have custom warning filters to make this less hackish.

When to use warn

Warn is still experimental and we do not yet recommend it for production. First as this is a pure python implementation, depending on the number of warning your code base have, you may notice a performance decrease.

Warn is extremely interesting for integration-testing and unit testing. We in particular recommend selectively enabling warning-as-error for all your direct dependencies. This is usually feasible with the default python warning module, except when warning are raised at import time, or if the underlying library does not make use of the stacklevel keyword. More generally you might want to consider enabling warning-as-error globally and silence them on a module-by-module basis if you decide they are false positive.

Warn is also extremely useful while developing locally to make sure you develop your code as early possible without using functionality that might be removed in the near future.

Indices and tables