Commit 552a90b4 authored by Oliver Beattie's avatar Oliver Beattie Committed by Claude Paroz
Browse files

Fixed #20290 -- Allow override_settings to be nested

Refactored override_settings to store the underlying settings._wrapped
value seen at runtime, not instantiation time.
parent 7314007c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -97,6 +97,7 @@ answer newbie questions, and generally made Django that much better:
    Ned Batchelder <http://www.nedbatchelder.com/>
    batiste@dosimple.ch
    Batman
    Oliver Beattie <oliver@obeattie.com>
    Brian Beck <http://blog.brianbeck.com/>
    Shannon -jj Behrens <http://jjinux.blogspot.com/>
    Esdras Beleza <linux@esdrasbeleza.com>
+2 −1
Original line number Diff line number Diff line
@@ -207,7 +207,6 @@ class override_settings(object):
    """
    def __init__(self, **kwargs):
        self.options = kwargs
        self.wrapped = settings._wrapped

    def __enter__(self):
        self.enable()
@@ -246,6 +245,7 @@ class override_settings(object):
        override = UserSettingsHolder(settings._wrapped)
        for key, new_value in self.options.items():
            setattr(override, key, new_value)
        self.wrapped = settings._wrapped
        settings._wrapped = override
        for key, new_value in self.options.items():
            setting_changed.send(sender=settings._wrapped.__class__,
@@ -253,6 +253,7 @@ class override_settings(object):

    def disable(self):
        settings._wrapped = self.wrapped
        del self.wrapped
        for key in self.options:
            new_value = getattr(settings, key, None)
            setting_changed.send(sender=settings._wrapped.__class__,
+5 −0
Original line number Diff line number Diff line
@@ -95,6 +95,11 @@ class LiveServerAddress(LiveServerBase):
        else:
            del os.environ['DJANGO_LIVE_TEST_SERVER_ADDRESS']

    @classmethod
    def tearDownClass(cls):
        # skip it, as setUpClass doesn't call its parent either
        pass

    @classmethod
    def raises_exception(cls, address, exception):
        os.environ['DJANGO_LIVE_TEST_SERVER_ADDRESS'] = address
+26 −1
Original line number Diff line number Diff line
@@ -9,17 +9,19 @@ from django.test.utils import override_settings
from django.utils import unittest, six


@override_settings(TEST='override')
@override_settings(TEST='override', TEST_OUTER='outer')
class FullyDecoratedTranTestCase(TransactionTestCase):

    available_apps = []

    def test_override(self):
        self.assertEqual(settings.TEST, 'override')
        self.assertEqual(settings.TEST_OUTER, 'outer')

    @override_settings(TEST='override2')
    def test_method_override(self):
        self.assertEqual(settings.TEST, 'override2')
        self.assertEqual(settings.TEST_OUTER, 'outer')

    def test_decorated_testcase_name(self):
        self.assertEqual(FullyDecoratedTranTestCase.__name__, 'FullyDecoratedTranTestCase')
@@ -168,6 +170,29 @@ class SettingsTests(TestCase):
            self.assertRaises(AttributeError, getattr, settings, 'USE_I18N')
        self.assertEqual(settings.USE_I18N, previous_i18n)

    def test_override_settings_nested(self):
        """
        Test that override_settings uses the actual _wrapped attribute at
        runtime, not when it was instantiated.
        """

        self.assertRaises(AttributeError, getattr, settings, 'TEST')
        self.assertRaises(AttributeError, getattr, settings, 'TEST2')

        inner = override_settings(TEST2='override')
        with override_settings(TEST='override'):
            self.assertEqual('override', settings.TEST)
            with inner:
                self.assertEqual('override', settings.TEST)
                self.assertEqual('override', settings.TEST2)
            # inner's __exit__ should have restored the settings of the outer
            # context manager, not those when the class was instantiated
            self.assertEqual('override', settings.TEST)
            self.assertRaises(AttributeError, getattr, settings, 'TEST2')

        self.assertRaises(AttributeError, getattr, settings, 'TEST')
        self.assertRaises(AttributeError, getattr, settings, 'TEST2')

    def test_allowed_include_roots_string(self):
        """
        ALLOWED_INCLUDE_ROOTS is not allowed to be incorrectly set to a string