diff --git a/django/conf/__init__.py b/django/conf/__init__.py index efb56b28718..f876c490c86 100644 --- a/django/conf/__init__.py +++ b/django/conf/__init__.py @@ -8,6 +8,7 @@ a list of all possible variables. import logging import os +import sys import time # Needed for Windows import warnings @@ -57,14 +58,15 @@ class LazySettings(LazyObject): """ Setup logging from LOGGING_CONFIG and LOGGING settings. """ - try: - # Route warnings through python logging - logging.captureWarnings(True) - # Allow DeprecationWarnings through the warnings filters - warnings.simplefilter("default", DeprecationWarning) - except AttributeError: - # No captureWarnings on Python 2.6, DeprecationWarnings are on anyway - pass + if not sys.warnoptions: + try: + # Route warnings through python logging + logging.captureWarnings(True) + # Allow DeprecationWarnings through the warnings filters + warnings.simplefilter("default", DeprecationWarning) + except AttributeError: + # No captureWarnings on Python 2.6, DeprecationWarnings are on anyway + pass if self.LOGGING_CONFIG: from django.utils.log import DEFAULT_LOGGING diff --git a/django/core/management/commands/test.py b/django/core/management/commands/test.py index 48b330aa6dc..2b8e8019eb8 100644 --- a/django/core/management/commands/test.py +++ b/django/core/management/commands/test.py @@ -1,3 +1,4 @@ +import logging import sys import os from optparse import make_option, OptionParser @@ -6,6 +7,7 @@ from django.conf import settings from django.core.management.base import BaseCommand from django.test.utils import get_runner + class Command(BaseCommand): option_list = BaseCommand.option_list + ( make_option('--noinput', @@ -57,6 +59,21 @@ class Command(BaseCommand): version=self.get_version(), option_list=options) + def execute(self, *args, **options): + if int(options['verbosity']) > 0: + # ensure that deprecation warnings are displayed during testing + # the following state is assumed: + # logging.capturewarnings is true + # a "default" level warnings filter has been added for + # DeprecationWarning. See django.conf.LazySettings._configure_logging + logger = logging.getLogger('py.warnings') + handler = logging.StreamHandler() + logger.addHandler(handler) + super(Command, self).execute(*args, **options) + if int(options['verbosity']) > 0: + # remove the testing-specific handler + logger.removeHandler(handler) + def handle(self, *test_labels, **options): from django.conf import settings from django.test.utils import get_runner diff --git a/django/test/simple.py b/django/test/simple.py index 684e3193a2c..7195d94a3aa 100644 --- a/django/test/simple.py +++ b/django/test/simple.py @@ -1,4 +1,3 @@ -import logging import unittest as real_unittest from django.conf import settings @@ -366,19 +365,7 @@ class DjangoTestSuiteRunner(object): self.setup_test_environment() suite = self.build_suite(test_labels, extra_tests) old_config = self.setup_databases() - if self.verbosity > 0: - # ensure that deprecation warnings are displayed during testing - # the following state is assumed: - # logging.capturewarnings is true - # a "default" level warnings filter has been added for - # DeprecationWarning. See django.conf.LazySettings._configure_logging - logger = logging.getLogger('py.warnings') - handler = logging.StreamHandler() - logger.addHandler(handler) result = self.run_suite(suite) - if self.verbosity > 0: - # remove the testing-specific handler - logger.removeHandler(handler) self.teardown_databases(old_config) self.teardown_test_environment() return self.suite_result(suite, result) diff --git a/tests/runtests.py b/tests/runtests.py index af47224fb95..ee2488c4a17 100755 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +import logging import os import shutil import subprocess @@ -82,6 +83,14 @@ def setup(verbosity, test_labels): settings.LANGUAGE_CODE = 'en' settings.SITE_ID = 1 + if verbosity > 0: + # Ensure any warnings captured to logging are piped through a verbose + # logging handler. If any -W options were passed explicitly on command + # line, warnings are not captured, and this has no effect. + logger = logging.getLogger('py.warnings') + handler = logging.StreamHandler() + logger.addHandler(handler) + # Load all the ALWAYS_INSTALLED_APPS. get_apps() diff --git a/tests/test_runner/deprecation_app/tests.py b/tests/test_runner/deprecation_app/tests.py index e676c3e3d57..6dee0888ec5 100644 --- a/tests/test_runner/deprecation_app/tests.py +++ b/tests/test_runner/deprecation_app/tests.py @@ -2,6 +2,8 @@ import warnings from django.test import TestCase +warnings.warn("module-level warning from deprecation_app", DeprecationWarning) + class DummyTest(TestCase): def test_warn(self): warnings.warn("warning from test", DeprecationWarning) diff --git a/tests/test_runner/tests.py b/tests/test_runner/tests.py index 6ba2fb3e525..9f0cc794b79 100644 --- a/tests/test_runner/tests.py +++ b/tests/test_runner/tests.py @@ -299,7 +299,8 @@ class DeprecationDisplayTest(AdminScriptTestCase): def test_runner_deprecation_verbosity_default(self): args = ['test', '--settings=test_project.settings'] out, err = self.run_django_admin(args) - self.assertTrue("DeprecationWarning: warning from test" in err) + self.assertIn("DeprecationWarning: warning from test", err) + self.assertIn("DeprecationWarning: module-level warning from deprecation_app", err) @unittest.skipIf(sys.version_info[:2] == (2, 6), "On Python 2.6, DeprecationWarnings are visible anyway")