Adds a context manager & decorator to dynamically override settings.

This commit is contained in:
Bertrand Bordage 2014-10-05 03:11:26 +02:00
parent e8cff823d3
commit f1bb3ee001
3 changed files with 58 additions and 9 deletions

View file

@ -53,12 +53,27 @@ Setting Default value Description
.. |CACHES| replace:: ``CACHES``
.. _CACHES: https://docs.djangoproject.com/en/1.7/ref/settings/#std:setting-CACHES
.. note:: Settings can be changed at any moment during runtime like this:
These settings can be changed whenever you want.
You have to use ``cachalot_settings`` as a context manager, a decorator,
or simply by changing its attributes:
.. code:: python
.. code:: python
from cachalot.settings import cachalot_settings
cachalot_settings.CACHALOT_CACHE = 'another_cache'
from cachalot.settings import cachalot_settings
with cachalot_settings(CACHALOT_ENABLED=False):
# SQL queries are not cached in this block
@cachalot_settings(CACHALOT_CACHE='another_cache')
def your_function():
# Whats in this function uses another cache
# Globally disables SQL caching until you set it back to True
cachalot_settings.CACHALOT_ENABLED = False
In tests, you can use
`Djangos testing tools <https://docs.djangoproject.com/en/1.7/topics/testing/tools/#overriding-settings>`_
as well as ``cachalot_settings``. They will both work the same.
Limits

View file

@ -1,6 +1,27 @@
from django.conf import settings
class SettingsOverrider(object):
def __init__(self, settings, overrides):
self.settings = settings
self.overrides = overrides
self.originals = {k: getattr(self.settings, k) for k in self.overrides}
def __enter__(self):
for k, v in self.overrides.items():
setattr(self.settings, k, v)
def __exit__(self, exc_type, exc_val, exc_tb):
for k, v in self.originals.items():
setattr(self.settings, k, v)
def __call__(self, func):
def inner(*args, **kwargs):
with self:
return func(*args, **kwargs)
return inner
class Settings(object):
CACHALOT_ENABLED = True
CACHALOT_CACHE = 'default'
@ -10,5 +31,8 @@ class Settings(object):
return getattr(settings, item)
return super(Settings, self).__getattribute__(item)
def __call__(self, **kwargs):
return SettingsOverrider(self, kwargs)
cachalot_settings = Settings()

View file

@ -1,6 +1,9 @@
# coding: utf-8
from __future__ import unicode_literals
from cachalot.settings import cachalot_settings
try:
from unittest import skip, skipIf
except ImportError: # For Python 2.6
@ -1178,14 +1181,21 @@ class AtomicTestCase(TestCase):
class SettingsTestCase(TestCase):
@cachalot_settings(CACHALOT_ENABLED=False)
def test_decorator(self):
with self.assertNumQueries(1):
list(Test.objects.all())
with self.assertNumQueries(1):
list(Test.objects.all())
def test_enabled(self):
with self.settings(CACHALOT_ENABLED=True):
with cachalot_settings(CACHALOT_ENABLED=True):
with self.assertNumQueries(1):
list(Test.objects.all())
with self.assertNumQueries(0):
list(Test.objects.all())
with self.settings(CACHALOT_ENABLED=False):
with cachalot_settings(CACHALOT_ENABLED=False):
with self.assertNumQueries(1):
list(Test.objects.all())
with self.assertNumQueries(1):
@ -1194,7 +1204,7 @@ class SettingsTestCase(TestCase):
with self.assertNumQueries(0):
list(Test.objects.all())
with self.settings(CACHALOT_ENABLED=False):
with cachalot_settings(CACHALOT_ENABLED=False):
with self.assertNumQueries(1):
t = Test.objects.create(name='test')
with self.assertNumQueries(1):
@ -1204,7 +1214,7 @@ class SettingsTestCase(TestCase):
@skipIf(len(settings.CACHES) == 1,
'We cant change the cache used since theres only one configured')
def test_cache(self):
with self.settings(CACHALOT_CACHE='default'):
with cachalot_settings(CACHALOT_CACHE='default'):
with self.assertNumQueries(1):
list(Test.objects.all())
with self.assertNumQueries(0):
@ -1212,7 +1222,7 @@ class SettingsTestCase(TestCase):
other_cache = [k for k in settings.CACHES if k != 'default'][0]
with self.settings(CACHALOT_CACHE=other_cache):
with cachalot_settings(CACHALOT_CACHE=other_cache):
with self.assertNumQueries(1):
list(Test.objects.all())
with self.assertNumQueries(0):