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.