Skip to content

Commit

Permalink
Make ExportedSettings a dict subclass
Browse files Browse the repository at this point in the history
  • Loading branch information
jkbrzt committed Nov 5, 2016
1 parent fef7bcd commit a9ccf05
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 21 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ This document records all notable changes to
This project adheres to `Semantic Versioning <http://semver.org/>`_.


1.2.0-dev (Unreleased)
----------------------

* The exported ``settings`` object is an instance of ``dict`` subclass
to allow iteration, etc.



1.1.0 (2016-03-10)
------------------

Expand Down
19 changes: 18 additions & 1 deletion demo/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,27 @@
TEMPLATE_DEBUG = DEBUG
ROOT_URLCONF = 'demo.urls'
INSTALLED_APPS = ['demo']
TEMPLATE_CONTEXT_PROCESSORS = ['django_settings_export.settings_export']
DATABASES = {'default': {'NAME': 'db.sqlite',
'ENGINE': 'django.db.backends.sqlite3'}}

# Django < 1.8
TEMPLATE_CONTEXT_PROCESSORS = [
'django_settings_export.settings_export'
]
# Django 1.8+
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django_settings_export.settings_export',
],
},
},
]


FOO = 'foo'
BAR = 'bar'
Expand Down
30 changes: 25 additions & 5 deletions demo/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,34 @@
)


# noinspection PyStatementEffect
class TestExportedSettings(TestCase):

def test_exported_settings_wrapper(self):
settings = ExportedSettings({'FOO': 'BAR'})
self.assertEqual(settings.FOO, 'BAR')
def setUp(self):
self.settings = ExportedSettings(FOO='BAR')

def test_attribute_access_ok(self):
self.assertEqual(self.settings['FOO'], 'BAR')

def test_attribute_access_unexported(self):
with self.assertRaises(UnexportedSettingError):
self.settings['XXX']

def test_key_access_ok(self):
self.assertEqual(self.settings.FOO, 'BAR')

def test_key_access_unexported(self):
with self.assertRaises(UnexportedSettingError):
# noinspection PyStatementEffect
settings.XXX
self.settings.XXX

def test_dict_keys(self):
self.assertListEqual(list(self.settings.keys()), ['FOO'])

def test_dict_values(self):
self.assertListEqual(list(self.settings.values()), ['BAR'])

def test_dict_items(self):
self.assertListEqual(list(self.settings.items()), [('FOO', 'BAR')])


class TestSettingsExportContextProcessor(TestCase):
Expand Down
13 changes: 6 additions & 7 deletions demo/urls.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
from django.conf.urls import patterns
from django.conf.urls import url

from . import views


urlpatterns = patterns(
'',
('^$', views.render_ok),
('^rename$', views.render_ok_rename),
('^error$', views.render_error),
)
urlpatterns = [
url('^$', views.render_ok),
url('^rename$', views.render_ok_rename),
url('^error$', views.render_error),
]


21 changes: 13 additions & 8 deletions django_settings_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,19 @@ def settings_export(request):
}


class ExportedSettings(object):
"""A simple wrapper around the exported settings."""
class ExportedSettings(dict):
"""
Allows attribute access (`settings.FOO`) as well as key access
(`settings['FOO']`).
In case of a missing key a custom exception is thrown.
def __init__(self, settings):
self.__dict__ = dict(settings)
"""

def __getattr__(self, item):
def __getitem__(self, item):
"""Fail loudly if accessing a setting that is not exported."""
try:
return self.__dict__[item]
return super(ExportedSettings, self).__getitem__(item)
except KeyError:
raise UnexportedSettingError(
'The `{key}` setting key is not accessible'
Expand All @@ -61,9 +64,11 @@ def __getattr__(self, item):
.format(key=item)
)

__getattr__ = __getitem__


def _get_exported_settings():
exported_settings = {}
exported_settings = ExportedSettings()
for key in getattr(django_settings, 'SETTINGS_EXPORT', []):
try:
value = getattr(django_settings, key)
Expand All @@ -74,5 +79,5 @@ def _get_exported_settings():
% key
)
exported_settings[key] = value
return ExportedSettings(exported_settings)
return exported_settings

0 comments on commit a9ccf05

Please sign in to comment.