How do I get warnings.warn to issue a warning and not ignore the line?

14,674

Solution 1

From the docs:

By default, Python installs several warning filters, which can be overridden by the command-line options passed to -W and calls to filterwarnings().

  • DeprecationWarning and PendingDeprecationWarning, and ImportWarning are ignored.
  • BytesWarning is ignored unless the -b option is given once or twice; in this case this warning is either printed (-b) or turned into an exception (-bb).

By default, DeprecationWarning is ignored. You can change the filters using the following:

warnings.simplefilter('always', DeprecationWarning)

Now your warnings should be printed:

>>> import warnings
>>> warnings.simplefilter('always', DeprecationWarning)
>>> warnings.warn('test', DeprecationWarning)
/home/guest/.env/bin/ipython:1: DeprecationWarning: test
  #!/home/guest/.env/bin/python

Solution 2

The warnings module implements filtering of warnings based on certain conditions. You can show the default filters by printing warnings.filters:

$ python -c "import warnings; print(warnings.filters)"
[('ignore', None, <type 'exceptions.DeprecationWarning'>, None, 0),
 ('ignore', None, <type 'exceptions.PendingDeprecationWarning'>, None, 0),
 ('ignore', None, <type 'exceptions.ImportWarning'>, None, 0),
 ('ignore', None, <type 'exceptions.BytesWarning'>, None, 0)]

As you can see, DeprecationWarning is ignored by default. You can use the functions in the warnings module and the -W command-line option to Python to configure the filters -- see the documentation for details.

Example:

$ python -Wall
Python 2.7.3 (default, Sep 26 2013, 20:03:06) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import warnings
>>> warnings.warn("test", DeprecationWarning)
__main__:1: DeprecationWarning: test
Share:
14,674
Damgaard
Author by

Damgaard

Updated on June 02, 2022

Comments

  • Damgaard
    Damgaard almost 2 years

    I'm trying to raise a DeprecationWarning, with a code snippet based on the example shown in the docs. http://docs.python.org/2/library/warnings.html#warnings.warn

    Official

    def deprecation(message):
        warnings.warn(message, DeprecationWarning, stacklevel=2)
    

    Mine

    import warnings
    warnings.warn("This is a warnings.", DeprecationWarning, stacklevel=2) is None  # returns True
    

    I've tried removing the stacklevel argument, setting it to negative, 0, 2 and 20000. The warning is always silently swallowed. It doesn't issue a warning or raise an exception. It just ignores the line and returns None. The docs doesn't mention the criteria for ignoring. Giving a message, makes warnings.warn correctly issue a Userwarning.

    What can be causing this and how do I get warn to actually warn?

  • Damgaard
    Damgaard over 10 years
    I see. I'm not sure I agree with that decision to change it from being loud to non-loud in 2.7. Users should, by default, be told when things are changing so they don't get caught completely unaware. Thanks.
  • naught101
    naught101 over 8 years
    @Damgaard: users don't care, as long as it works. It's a warning for developers, who should be testing with -W all or -W once anyway.
  • Marcel Wilson
    Marcel Wilson over 7 years
    Is there a way to programmatically turn on all warnings? (e.g. not at commandline?)
  • Sven Marnach
    Sven Marnach over 7 years
    @MarcelWilson Something like warnings.simplefilter("always") (or warnings.simplefilter("default"), if you only want to see the first occurrence of each warning). Just read the warnings module documentation for details.