Fixed #20290 -- Allow override_settings to be nested
Refactored override_settings to store the underlying settings._wrapped value seen at runtime, not instantiation time.
This commit is contained in:
parent
7314007c5b
commit
552a90b444
1
AUTHORS
1
AUTHORS
|
@ -97,6 +97,7 @@ answer newbie questions, and generally made Django that much better:
|
||||||
Ned Batchelder <http://www.nedbatchelder.com/>
|
Ned Batchelder <http://www.nedbatchelder.com/>
|
||||||
batiste@dosimple.ch
|
batiste@dosimple.ch
|
||||||
Batman
|
Batman
|
||||||
|
Oliver Beattie <oliver@obeattie.com>
|
||||||
Brian Beck <http://blog.brianbeck.com/>
|
Brian Beck <http://blog.brianbeck.com/>
|
||||||
Shannon -jj Behrens <http://jjinux.blogspot.com/>
|
Shannon -jj Behrens <http://jjinux.blogspot.com/>
|
||||||
Esdras Beleza <linux@esdrasbeleza.com>
|
Esdras Beleza <linux@esdrasbeleza.com>
|
||||||
|
|
|
@ -207,7 +207,6 @@ class override_settings(object):
|
||||||
"""
|
"""
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
self.options = kwargs
|
self.options = kwargs
|
||||||
self.wrapped = settings._wrapped
|
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
self.enable()
|
self.enable()
|
||||||
|
@ -246,6 +245,7 @@ class override_settings(object):
|
||||||
override = UserSettingsHolder(settings._wrapped)
|
override = UserSettingsHolder(settings._wrapped)
|
||||||
for key, new_value in self.options.items():
|
for key, new_value in self.options.items():
|
||||||
setattr(override, key, new_value)
|
setattr(override, key, new_value)
|
||||||
|
self.wrapped = settings._wrapped
|
||||||
settings._wrapped = override
|
settings._wrapped = override
|
||||||
for key, new_value in self.options.items():
|
for key, new_value in self.options.items():
|
||||||
setting_changed.send(sender=settings._wrapped.__class__,
|
setting_changed.send(sender=settings._wrapped.__class__,
|
||||||
|
@ -253,6 +253,7 @@ class override_settings(object):
|
||||||
|
|
||||||
def disable(self):
|
def disable(self):
|
||||||
settings._wrapped = self.wrapped
|
settings._wrapped = self.wrapped
|
||||||
|
del self.wrapped
|
||||||
for key in self.options:
|
for key in self.options:
|
||||||
new_value = getattr(settings, key, None)
|
new_value = getattr(settings, key, None)
|
||||||
setting_changed.send(sender=settings._wrapped.__class__,
|
setting_changed.send(sender=settings._wrapped.__class__,
|
||||||
|
|
|
@ -95,6 +95,11 @@ class LiveServerAddress(LiveServerBase):
|
||||||
else:
|
else:
|
||||||
del os.environ['DJANGO_LIVE_TEST_SERVER_ADDRESS']
|
del os.environ['DJANGO_LIVE_TEST_SERVER_ADDRESS']
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def tearDownClass(cls):
|
||||||
|
# skip it, as setUpClass doesn't call its parent either
|
||||||
|
pass
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def raises_exception(cls, address, exception):
|
def raises_exception(cls, address, exception):
|
||||||
os.environ['DJANGO_LIVE_TEST_SERVER_ADDRESS'] = address
|
os.environ['DJANGO_LIVE_TEST_SERVER_ADDRESS'] = address
|
||||||
|
|
|
@ -9,17 +9,19 @@ from django.test.utils import override_settings
|
||||||
from django.utils import unittest, six
|
from django.utils import unittest, six
|
||||||
|
|
||||||
|
|
||||||
@override_settings(TEST='override')
|
@override_settings(TEST='override', TEST_OUTER='outer')
|
||||||
class FullyDecoratedTranTestCase(TransactionTestCase):
|
class FullyDecoratedTranTestCase(TransactionTestCase):
|
||||||
|
|
||||||
available_apps = []
|
available_apps = []
|
||||||
|
|
||||||
def test_override(self):
|
def test_override(self):
|
||||||
self.assertEqual(settings.TEST, 'override')
|
self.assertEqual(settings.TEST, 'override')
|
||||||
|
self.assertEqual(settings.TEST_OUTER, 'outer')
|
||||||
|
|
||||||
@override_settings(TEST='override2')
|
@override_settings(TEST='override2')
|
||||||
def test_method_override(self):
|
def test_method_override(self):
|
||||||
self.assertEqual(settings.TEST, 'override2')
|
self.assertEqual(settings.TEST, 'override2')
|
||||||
|
self.assertEqual(settings.TEST_OUTER, 'outer')
|
||||||
|
|
||||||
def test_decorated_testcase_name(self):
|
def test_decorated_testcase_name(self):
|
||||||
self.assertEqual(FullyDecoratedTranTestCase.__name__, 'FullyDecoratedTranTestCase')
|
self.assertEqual(FullyDecoratedTranTestCase.__name__, 'FullyDecoratedTranTestCase')
|
||||||
|
@ -168,6 +170,29 @@ class SettingsTests(TestCase):
|
||||||
self.assertRaises(AttributeError, getattr, settings, 'USE_I18N')
|
self.assertRaises(AttributeError, getattr, settings, 'USE_I18N')
|
||||||
self.assertEqual(settings.USE_I18N, previous_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):
|
def test_allowed_include_roots_string(self):
|
||||||
"""
|
"""
|
||||||
ALLOWED_INCLUDE_ROOTS is not allowed to be incorrectly set to a string
|
ALLOWED_INCLUDE_ROOTS is not allowed to be incorrectly set to a string
|
||||||
|
|
Loading…
Reference in New Issue