5

We are updating our application from Django 1.6 to 1.7.

We see a lot of these message:RemovedInDjango18Warning

Is there a way to filter them? They get emitted during importing.

We tried warnings.filterwarnings('ignore', '...') but the warnings get emitted before we call warnings.filterwarnings().

How can I filter these warnings which happen during importing?

guettli
  • 25,042
  • 81
  • 346
  • 663
  • @Andy. I think this is a different question. I know how to use `warnings.filterwarnings()`. My problem is the timing: A lot of messages get emitted during importing. I don't know how to call warnings.filterwarnings() early enough – guettli Aug 24 '15 at 08:09
  • What about to [write your own filter](https://docs.djangoproject.com/en/1.8/topics/logging/#id5) in settings.py? – dani herrera Aug 24 '15 at 11:39
  • @danhip AFAIK the warnings get emitted before settings.py gets loaded. A filter in settings.py would be too late. – guettli Aug 24 '15 at 14:08
  • 1
    Look it here: http://stackoverflow.com/a/30716923/842935 – dani herrera Aug 24 '15 at 14:27
  • What WSGI server are you using. If you were using mod_wsgi then it can be achieved using a configuration directive in the Apache configuration file. See item 15 in features added in http://modwsgi.readthedocs.org/en/develop/release-notes/version-3.0.html – Graham Dumpleton Aug 27 '15 at 11:47
  • @GrahamDumpleton thank you very much for the link. This could solve some of the warnings. But we get the same warnings if we run cronjobs. Your solution is a work around. I think there is something not solved in the python world: Configuring logging. It is reimplemented over and over again. Python folks are programmers, they don't care for configuring an environment. Related: http://stackoverflow.com/questions/29962525/configuring-the-logging-of-a-third-party-script – guettli Aug 27 '15 at 15:20

1 Answers1

5

Quickfix

To silence it only when you run manage.py, add these lines after import sys:

# ...
import sys

if not sys.warnoptions:
    sys.warnoptions += [None]

# ...

If you also want to silence it from your WSGI server (i.e. Apache), update your_project/wsgi.py and add the following lines after import os:

# ...
import os
import sys

if not sys.warnoptions:
    sys.warnoptions += [None]

# ...

Explanation

The reason this works is because of how django.utils.log.configure_logging() handles it:

def configure_logging(logging_config, logging_settings):
    if not sys.warnoptions:
        # Route warnings through python logging
        logging.captureWarnings(True)
        # RemovedInNextVersionWarning is a subclass of DeprecationWarning which
        # is hidden by default, hence we force the "default" behavior
        warnings.simplefilter("default", RemovedInNextVersionWarning)
    # ...

It's deliberately called early in the boot process as part of django.setup(), which explains why errors were emitted before you were able to silence them further down the stack.

Adding a new element to sys.warnoptions forces it to evaluate to True, bypassing the logic. This is harmless since it's only used during python startup when loaded by the warnings module.

RemovedInNextVersionWarning is just an alias for RemovedInDjango18Warning in Django 1.7. It is set to RemovedInDjango19Warning in 1.8, and so on for future versions -- this code should be future proof for this type of DeprecationWarning.


Command line methods

Note that sys.warnoptions is normally set during python startup based on the -W argument when calling python. Therefore, a simple way to just silence the warnings when you use the dev server is python -W123 manage.py runserver. This requires no modification of files, but does result in a single harmless warning at startup since 123 is just a placeholder and not a valid warning action.

Another way is python -Wi::DeprecationWarning manage.py runserver, though this will ignore ALL DeprecationWarnings, including possibly ones of interest which are not RemovedInDjango18Warning.

user193130
  • 8,009
  • 4
  • 36
  • 64