Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #20290 -- Allow override_settings to be nested

Refactored override_settings to store the underlying settings._wrapped
value seen at runtime, not instantiation time.
  • Loading branch information...
commit 552a90b44456f24de228a6c7cd916c040787cf22 1 parent 7314007
Oliver Beattie authored April 19, 2013 claudep committed June 21, 2013
1  AUTHORS
@@ -97,6 +97,7 @@ answer newbie questions, and generally made Django that much better:
97 97
     Ned Batchelder <http://www.nedbatchelder.com/>
98 98
     batiste@dosimple.ch
99 99
     Batman
  100
+    Oliver Beattie <oliver@obeattie.com>
100 101
     Brian Beck <http://blog.brianbeck.com/>
101 102
     Shannon -jj Behrens <http://jjinux.blogspot.com/>
102 103
     Esdras Beleza <linux@esdrasbeleza.com>
3  django/test/utils.py
@@ -207,7 +207,6 @@ class override_settings(object):
207 207
     """
208 208
     def __init__(self, **kwargs):
209 209
         self.options = kwargs
210  
-        self.wrapped = settings._wrapped
211 210
 
212 211
     def __enter__(self):
213 212
         self.enable()
@@ -246,6 +245,7 @@ def enable(self):
246 245
         override = UserSettingsHolder(settings._wrapped)
247 246
         for key, new_value in self.options.items():
248 247
             setattr(override, key, new_value)
  248
+        self.wrapped = settings._wrapped
249 249
         settings._wrapped = override
250 250
         for key, new_value in self.options.items():
251 251
             setting_changed.send(sender=settings._wrapped.__class__,
@@ -253,6 +253,7 @@ def enable(self):
253 253
 
254 254
     def disable(self):
255 255
         settings._wrapped = self.wrapped
  256
+        del self.wrapped
256 257
         for key in self.options:
257 258
             new_value = getattr(settings, key, None)
258 259
             setting_changed.send(sender=settings._wrapped.__class__,
5  tests/servers/tests.py
@@ -96,6 +96,11 @@ def setUpClass(cls):
96 96
             del os.environ['DJANGO_LIVE_TEST_SERVER_ADDRESS']
97 97
 
98 98
     @classmethod
  99
+    def tearDownClass(cls):
  100
+        # skip it, as setUpClass doesn't call its parent either
  101
+        pass
  102
+
  103
+    @classmethod
99 104
     def raises_exception(cls, address, exception):
100 105
         os.environ['DJANGO_LIVE_TEST_SERVER_ADDRESS'] = address
101 106
         try:
27  tests/settings_tests/tests.py
@@ -9,17 +9,19 @@
9 9
 from django.utils import unittest, six
10 10
 
11 11
 
12  
-@override_settings(TEST='override')
  12
+@override_settings(TEST='override', TEST_OUTER='outer')
13 13
 class FullyDecoratedTranTestCase(TransactionTestCase):
14 14
 
15 15
     available_apps = []
16 16
 
17 17
     def test_override(self):
18 18
         self.assertEqual(settings.TEST, 'override')
  19
+        self.assertEqual(settings.TEST_OUTER, 'outer')
19 20
 
20 21
     @override_settings(TEST='override2')
21 22
     def test_method_override(self):
22 23
         self.assertEqual(settings.TEST, 'override2')
  24
+        self.assertEqual(settings.TEST_OUTER, 'outer')
23 25
 
24 26
     def test_decorated_testcase_name(self):
25 27
         self.assertEqual(FullyDecoratedTranTestCase.__name__, 'FullyDecoratedTranTestCase')
@@ -168,6 +170,29 @@ def test_override_settings_delete(self):
168 170
             self.assertRaises(AttributeError, getattr, settings, 'USE_I18N')
169 171
         self.assertEqual(settings.USE_I18N, previous_i18n)
170 172
 
  173
+    def test_override_settings_nested(self):
  174
+        """
  175
+        Test that override_settings uses the actual _wrapped attribute at
  176
+        runtime, not when it was instantiated.
  177
+        """
  178
+
  179
+        self.assertRaises(AttributeError, getattr, settings, 'TEST')
  180
+        self.assertRaises(AttributeError, getattr, settings, 'TEST2')
  181
+
  182
+        inner = override_settings(TEST2='override')
  183
+        with override_settings(TEST='override'):
  184
+            self.assertEqual('override', settings.TEST)
  185
+            with inner:
  186
+                self.assertEqual('override', settings.TEST)
  187
+                self.assertEqual('override', settings.TEST2)
  188
+            # inner's __exit__ should have restored the settings of the outer
  189
+            # context manager, not those when the class was instantiated
  190
+            self.assertEqual('override', settings.TEST)
  191
+            self.assertRaises(AttributeError, getattr, settings, 'TEST2')
  192
+
  193
+        self.assertRaises(AttributeError, getattr, settings, 'TEST')
  194
+        self.assertRaises(AttributeError, getattr, settings, 'TEST2')
  195
+
171 196
     def test_allowed_include_roots_string(self):
172 197
         """
173 198
         ALLOWED_INCLUDE_ROOTS is not allowed to be incorrectly set to a string

0 notes on commit 552a90b

Please sign in to comment.
Something went wrong with that request. Please try again.