warnings.warn() vs. logging.warning()

What is the difference between warnings.warn() and logging.warn() in terms of what they do and how they should be used?


I agree with the other answer -- logging is for logging and warning is for warning -- but I'd like to add more detail.

Here is a tutorial-style HOWTO taking you through the steps in using the logging module. https://docs.python.org/3/howto/logging.html

It directly answers your question:

warnings.warn() in library code if the issue is avoidable and the client application should be modified to eliminate the warning

logging.warning() if there is nothing the client application can do about the situation, but the event should still be noted


logging.warning just logs something at the WARNING level, in the same way that logging.info logs at the INFO level and logging.error logs at the ERROR level. It has no special behaviour.

warnings.warn emits a Warning, which may be printed to stderr, ignored completely, or thrown like a normal Exception (potentially crashing your application) depending upon the precise Warning subclass emitted and how you've configured your Warnings Filter. By default, warnings will be printed to stderr or ignored.

Warnings emitted by warnings.warn are often useful to know about, but easy to miss (especially if you're running a Python program in a background process and not capturing stderr). For that reason, it can be helpful to have them logged.

Python provides a built-in integration between the logging module and the warnings module to let you do this; just call logging.captureWarnings(True) at the start of your script and all warnings emitted by the warnings module will automatically be logged at level WARNING.


Besides the canonical explanation in official documentation

warnings.warn() in library code if the issue is avoidable and the client application should be modified to eliminate the warning

logging.warning() if there is nothing the client application can do about the situation, but the event should still be noted

It is also worth noting that, by default warnings.warn("same message") will show up only once. That is a major noticeable difference. Quoted from official doc

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

>>> import warnings
>>> warnings.warn("foo")
__main__:1: UserWarning: foo
>>> warnings.warn("foo")
>>> warnings.warn("foo")
>>>
>>> import logging
>>> logging.warn("bar")
WARNING:root:bar
>>> logging.warn("bar")
WARNING:root:bar
>>> logging.warn("bar")
WARNING:root:bar
>>>
>>>
>>> warnings.warn("fur")
__main__:1: UserWarning: fur
>>> warnings.warn("fur")
>>> warnings.warn("fur")
>>>