mirror of
https://github.com/jazzband/django-configurations.git
synced 2026-03-16 22:20:27 +00:00
Renamed Settings class to Configuration to better match what it means. Settings is still importable and is marked to be deprecated in 1.0.
This commit is contained in:
parent
aac7af881c
commit
e31adbaeed
10 changed files with 79 additions and 66 deletions
|
|
@ -19,7 +19,7 @@ Install django-configurations:
|
||||||
|
|
||||||
pip install django-configurations
|
pip install django-configurations
|
||||||
|
|
||||||
Then subclass the included ``configurations.Settings`` class in your
|
Then subclass the included ``configurations.Configuration`` class in your
|
||||||
project's **settings.py** or any other module you're using to store the
|
project's **settings.py** or any other module you're using to store the
|
||||||
settings constants, e.g.:
|
settings constants, e.g.:
|
||||||
|
|
||||||
|
|
@ -27,9 +27,9 @@ settings constants, e.g.:
|
||||||
|
|
||||||
# mysite/settings.py
|
# mysite/settings.py
|
||||||
|
|
||||||
from configurations import Settings
|
from configurations import Configuration
|
||||||
|
|
||||||
class Dev(Settings):
|
class Dev(Configuration):
|
||||||
DEBUG = True
|
DEBUG = True
|
||||||
|
|
||||||
Set the ``DJANGO_CONFIGURATION`` environment variable to the name of the class
|
Set the ``DJANGO_CONFIGURATION`` environment variable to the name of the class
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# flake8: noqa
|
# flake8: noqa
|
||||||
from .base import Settings
|
from .base import Settings, Configuration
|
||||||
from .decorators import pristinemethod
|
from .decorators import pristinemethod
|
||||||
|
|
||||||
__version__ = '0.3'
|
__version__ = '0.3'
|
||||||
__all__ = ['Settings', 'pristinemethod']
|
__all__ = ['Configuration', 'pristinemethod']
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
import six
|
import warnings
|
||||||
|
|
||||||
|
from django.utils import six
|
||||||
from django.conf import global_settings
|
from django.conf import global_settings
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
|
|
||||||
from .utils import uppercase_attributes
|
from .utils import uppercase_attributes
|
||||||
|
|
||||||
__all__ = ['Settings']
|
__all__ = ['Configuration']
|
||||||
|
|
||||||
|
|
||||||
install_failure = ("django-configurations settings importer wasn't "
|
install_failure = ("django-configurations settings importer wasn't "
|
||||||
|
|
@ -13,7 +15,7 @@ install_failure = ("django-configurations settings importer wasn't "
|
||||||
"http://django-configurations.readthedocs.org/")
|
"http://django-configurations.readthedocs.org/")
|
||||||
|
|
||||||
|
|
||||||
class SettingsBase(type):
|
class ConfigurationBase(type):
|
||||||
|
|
||||||
def __new__(cls, name, bases, attrs):
|
def __new__(cls, name, bases, attrs):
|
||||||
if bases != (object,) and bases[0].__name__ != 'NewBase':
|
if bases != (object,) and bases[0].__name__ != 'NewBase':
|
||||||
|
|
@ -23,24 +25,26 @@ class SettingsBase(type):
|
||||||
if not importer.installed:
|
if not importer.installed:
|
||||||
raise ImproperlyConfigured(install_failure)
|
raise ImproperlyConfigured(install_failure)
|
||||||
settings_vars = uppercase_attributes(global_settings)
|
settings_vars = uppercase_attributes(global_settings)
|
||||||
parents = [base for base in bases if isinstance(base, SettingsBase)]
|
parents = [base for base in bases if isinstance(base,
|
||||||
|
ConfigurationBase)]
|
||||||
if parents:
|
if parents:
|
||||||
for base in bases[::-1]:
|
for base in bases[::-1]:
|
||||||
settings_vars.update(uppercase_attributes(base))
|
settings_vars.update(uppercase_attributes(base))
|
||||||
attrs = dict(settings_vars, **attrs)
|
attrs = dict(settings_vars, **attrs)
|
||||||
return super(SettingsBase, cls).__new__(cls, name, bases, attrs)
|
return super(ConfigurationBase, cls).__new__(cls, name, bases, attrs)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<Settings '%s.%s'>" % (self.__module__, self.__name__)
|
return "<Configuration '{0}.{1}'>".format(self.__module__,
|
||||||
|
self.__name__)
|
||||||
|
|
||||||
|
|
||||||
class Settings(six.with_metaclass(SettingsBase)):
|
class Configuration(six.with_metaclass(ConfigurationBase)):
|
||||||
"""
|
"""
|
||||||
The base configuration class to inherit from.
|
The base configuration class to inherit from.
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
class Develop(Settings):
|
class Develop(Configuration):
|
||||||
EXTRA_AWESOME = True
|
EXTRA_AWESOME = True
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
@ -65,3 +69,12 @@ class Settings(six.with_metaclass(SettingsBase)):
|
||||||
@classmethod
|
@classmethod
|
||||||
def post_setup(cls):
|
def post_setup(cls):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Settings(Configuration):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def pre_setup(cls):
|
||||||
|
warnings.warn("configurations.Settings was renamed to "
|
||||||
|
"settings.Configuration and will be "
|
||||||
|
"removed in 1.0", PendingDeprecationWarning)
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,9 @@ def pristinemethod(func):
|
||||||
|
|
||||||
Use it like this::
|
Use it like this::
|
||||||
|
|
||||||
from configurations import pristinemethod
|
from configurations import Configuration, pristinemethod
|
||||||
|
|
||||||
class Develop(Settings):
|
class Develop(Configuration):
|
||||||
|
|
||||||
@pristinemethod
|
@pristinemethod
|
||||||
def USER_CHECK(user):
|
def USER_CHECK(user):
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,8 @@ class StdoutWrapper(object):
|
||||||
|
|
||||||
def write(self, msg, *args, **kwargs):
|
def write(self, msg, *args, **kwargs):
|
||||||
if 'Django version' in msg:
|
if 'Django version' in msg:
|
||||||
new_msg_part = (", configuration %r" %
|
new_msg_part = (", configuration {!r}".format(
|
||||||
os.environ.get(CONFIGURATION_ENVIRONMENT_VARIABLE))
|
os.environ.get(CONFIGURATION_ENVIRONMENT_VARIABLE)))
|
||||||
msg_parts = msg.split('\n')
|
msg_parts = msg.split('\n')
|
||||||
modified_msg_parts = []
|
modified_msg_parts = []
|
||||||
for msg_part in msg_parts:
|
for msg_part in msg_parts:
|
||||||
|
|
@ -53,7 +53,7 @@ def patch_inner_run(original):
|
||||||
|
|
||||||
configuration_options = (
|
configuration_options = (
|
||||||
make_option('--configuration',
|
make_option('--configuration',
|
||||||
help='The name of the settings class to load, e.g. '
|
help='The name of the configuration class to load, e.g. '
|
||||||
'"Development". If this isn\'t provided, the '
|
'"Development". If this isn\'t provided, the '
|
||||||
'DJANGO_CONFIGURATION environment variable will '
|
'DJANGO_CONFIGURATION environment variable will '
|
||||||
'be used.'),)
|
'be used.'),)
|
||||||
|
|
@ -69,16 +69,16 @@ def install():
|
||||||
# add the configuration option to all management commands
|
# add the configuration option to all management commands
|
||||||
base.BaseCommand.option_list += configuration_options
|
base.BaseCommand.option_list += configuration_options
|
||||||
|
|
||||||
sys.meta_path.insert(0, SettingsImporter())
|
sys.meta_path.insert(0, ConfigurationImporter())
|
||||||
installed = True
|
installed = True
|
||||||
|
|
||||||
# now patch the active runserver command to show a nicer output
|
# now patch the active runserver command to show a nicer output
|
||||||
commands = management.get_commands()
|
commands = management.get_commands()
|
||||||
runserver_path = commands.get('runserver', None)
|
runserver = commands.get('runserver', None)
|
||||||
if runserver_path is not None:
|
if runserver is not None:
|
||||||
full_path = '%s.management.commands.runserver' % runserver_path
|
path = '{0}.management.commands.runserver'.format(runserver)
|
||||||
try:
|
try:
|
||||||
runserver_module = import_module(full_path)
|
runserver_module = import_module(path)
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
|
@ -91,9 +91,9 @@ def handle_configurations_option(options):
|
||||||
os.environ[CONFIGURATION_ENVIRONMENT_VARIABLE] = options.configuration
|
os.environ[CONFIGURATION_ENVIRONMENT_VARIABLE] = options.configuration
|
||||||
|
|
||||||
|
|
||||||
class SettingsImporter(object):
|
class ConfigurationImporter(object):
|
||||||
error_msg = ("Settings cannot be imported, "
|
error_msg = ("Configuration cannot be imported, "
|
||||||
"environment variable %s is undefined.")
|
"environment variable {0} is undefined.")
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.argv = sys.argv[:]
|
self.argv = sys.argv[:]
|
||||||
|
|
@ -107,7 +107,8 @@ class SettingsImporter(object):
|
||||||
self.validate()
|
self.validate()
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<SettingsImporter for '%s.%s'>" % (self.module, self.name)
|
return "<ConfigurationImporter for '{0}.{1}'>".format(self.module,
|
||||||
|
self.name)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def module(self):
|
def module(self):
|
||||||
|
|
@ -119,16 +120,16 @@ class SettingsImporter(object):
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
if self.name is None:
|
if self.name is None:
|
||||||
raise ImproperlyConfigured(self.error_msg %
|
raise ImproperlyConfigured(self.error_msg.format(
|
||||||
CONFIGURATION_ENVIRONMENT_VARIABLE)
|
CONFIGURATION_ENVIRONMENT_VARIABLE))
|
||||||
if self.module is None:
|
if self.module is None:
|
||||||
raise ImproperlyConfigured(self.error_msg %
|
raise ImproperlyConfigured(self.error_msg.format(
|
||||||
SETTINGS_ENVIRONMENT_VARIABLE)
|
SETTINGS_ENVIRONMENT_VARIABLE))
|
||||||
|
|
||||||
def find_module(self, fullname, path=None):
|
def find_module(self, fullname, path=None):
|
||||||
if fullname is not None and fullname == self.module:
|
if fullname is not None and fullname == self.module:
|
||||||
module = fullname.rsplit('.', 1)[-1]
|
module = fullname.rsplit('.', 1)[-1]
|
||||||
return SettingsLoader(self.name, imp.find_module(module, path))
|
return ConfigurationLoader(self.name, imp.find_module(module, path))
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -148,7 +149,7 @@ def reraise(exc, prefix=None, suffix=None):
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
class SettingsLoader(object):
|
class ConfigurationLoader(object):
|
||||||
|
|
||||||
def __init__(self, name, location):
|
def __init__(self, name, location):
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
@ -159,46 +160,45 @@ class SettingsLoader(object):
|
||||||
mod = sys.modules[fullname] # pragma: no cover
|
mod = sys.modules[fullname] # pragma: no cover
|
||||||
else:
|
else:
|
||||||
mod = imp.load_module(fullname, *self.location)
|
mod = imp.load_module(fullname, *self.location)
|
||||||
cls_path = '%s.%s' % (mod.__name__, self.name)
|
cls_path = '{0}.{1}'.format(mod.__name__, self.name)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cls = getattr(mod, self.name)
|
cls = getattr(mod, self.name)
|
||||||
except AttributeError as err: # pragma: no cover
|
except AttributeError as err: # pragma: no cover
|
||||||
reraise(err,
|
reraise(err, "While trying to find the '{0}' "
|
||||||
"While trying to find the '%s' settings in module '%s'" %
|
"settings in module '{1}'".format(self.name,
|
||||||
(self.name, mod.__package__))
|
mod.__package__))
|
||||||
try:
|
try:
|
||||||
cls.pre_setup()
|
cls.pre_setup()
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
reraise(err, "While calling '%s.pre_setup()'" % cls_path)
|
reraise(err, "While calling '{0}.pre_setup()'".format(cls_path))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
obj = cls()
|
obj = cls()
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
reraise(err,
|
reraise(err, "While initializing the '{0}' "
|
||||||
"While loading the '%s' settings" % cls_path)
|
"configuration".format(cls_path))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
attributes = uppercase_attributes(obj).items()
|
attributes = uppercase_attributes(obj).items()
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
reraise(err,
|
reraise(err, "While getting the items "
|
||||||
"While getting the items of the '%s' settings" %
|
"of the '{0}' configuration".format(cls_path))
|
||||||
cls_path)
|
|
||||||
|
|
||||||
for name, value in attributes:
|
for name, value in attributes:
|
||||||
if callable(value) and not getattr(value, 'pristine', False):
|
if callable(value) and not getattr(value, 'pristine', False):
|
||||||
try:
|
try:
|
||||||
value = value()
|
value = value()
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
reraise(err,
|
reraise(err, "While calling '{0}.{1}'".format(cls_path,
|
||||||
"While calling '%s.%s'" % (cls_path, value))
|
value))
|
||||||
setattr(mod, name, value)
|
setattr(mod, name, value)
|
||||||
|
|
||||||
setattr(mod, 'CONFIGURATION', '%s.%s' % (fullname, self.name))
|
setattr(mod, 'CONFIGURATION', '{0}.{1}'.format(fullname, self.name))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cls.post_setup()
|
cls.post_setup()
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
reraise(err, "While calling '%s.post_setup()'" % cls_path)
|
reraise(err, "While calling '{0}.post_setup()'".format(cls_path))
|
||||||
|
|
||||||
return mod
|
return mod
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
from configurations import Settings
|
from configurations import Configuration
|
||||||
|
|
||||||
|
|
||||||
def test_callback(request):
|
def test_callback(request):
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
||||||
class Base(Settings):
|
class Base(Configuration):
|
||||||
pass
|
pass
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import os
|
import os
|
||||||
import uuid
|
import uuid
|
||||||
from configurations import Settings, pristinemethod
|
from configurations import Configuration, pristinemethod
|
||||||
|
|
||||||
|
|
||||||
class Test(Settings):
|
class Test(Configuration):
|
||||||
DEBUG = True
|
DEBUG = True
|
||||||
|
|
||||||
SITE_ID = 1
|
SITE_ID = 1
|
||||||
|
|
@ -31,7 +31,7 @@ class Test(Settings):
|
||||||
TEST_RUNNER = 'discover_runner.DiscoverRunner'
|
TEST_RUNNER = 'discover_runner.DiscoverRunner'
|
||||||
|
|
||||||
def TEMPLATE_CONTEXT_PROCESSORS(self):
|
def TEMPLATE_CONTEXT_PROCESSORS(self):
|
||||||
return Settings.TEMPLATE_CONTEXT_PROCESSORS + (
|
return Configuration.TEMPLATE_CONTEXT_PROCESSORS + (
|
||||||
'configurations.tests.settings.base.test_callback',)
|
'configurations.tests.settings.base.test_callback',)
|
||||||
|
|
||||||
ATTRIBUTE_SETTING = True
|
ATTRIBUTE_SETTING = True
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from configurations import Settings
|
from configurations import Configuration
|
||||||
|
|
||||||
|
|
||||||
class Mixin1(object):
|
class Mixin1(object):
|
||||||
|
|
@ -17,7 +17,7 @@ class Mixin2(object):
|
||||||
'some_app.context_processors.processor2',)
|
'some_app.context_processors.processor2',)
|
||||||
|
|
||||||
|
|
||||||
class Inheritance(Mixin2, Mixin1, Settings):
|
class Inheritance(Mixin2, Mixin1, Configuration):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def TEMPLATE_CONTEXT_PROCESSORS(self):
|
def TEMPLATE_CONTEXT_PROCESSORS(self):
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ from django.core.exceptions import ImproperlyConfigured
|
||||||
|
|
||||||
from mock import patch
|
from mock import patch
|
||||||
|
|
||||||
from configurations.importer import SettingsImporter
|
from configurations.importer import ConfigurationImporter
|
||||||
|
|
||||||
|
|
||||||
class MainTests(TestCase):
|
class MainTests(TestCase):
|
||||||
|
|
@ -41,39 +41,39 @@ class MainTests(TestCase):
|
||||||
|
|
||||||
@patch.dict(os.environ, clear=True, DJANGO_CONFIGURATION='Test')
|
@patch.dict(os.environ, clear=True, DJANGO_CONFIGURATION='Test')
|
||||||
def test_empty_module_var(self):
|
def test_empty_module_var(self):
|
||||||
self.assertRaises(ImproperlyConfigured, SettingsImporter)
|
self.assertRaises(ImproperlyConfigured, ConfigurationImporter)
|
||||||
|
|
||||||
@patch.dict(os.environ, clear=True,
|
@patch.dict(os.environ, clear=True,
|
||||||
DJANGO_SETTINGS_MODULE='configurations.tests.settings.main')
|
DJANGO_SETTINGS_MODULE='configurations.tests.settings.main')
|
||||||
def test_empty_class_var(self):
|
def test_empty_class_var(self):
|
||||||
self.assertRaises(ImproperlyConfigured, SettingsImporter)
|
self.assertRaises(ImproperlyConfigured, ConfigurationImporter)
|
||||||
|
|
||||||
def test_global_settings(self):
|
def test_global_settings(self):
|
||||||
from configurations.base import Settings
|
from configurations.base import Configuration
|
||||||
self.assertEqual(Settings.LOGGING_CONFIG, 'django.utils.log.dictConfig')
|
self.assertEqual(Configuration.LOGGING_CONFIG, 'django.utils.log.dictConfig')
|
||||||
self.assertEqual(repr(Settings),
|
self.assertEqual(repr(Configuration),
|
||||||
"<Settings 'configurations.base.Settings'>")
|
"<Configuration 'configurations.base.Configuration'>")
|
||||||
|
|
||||||
def test_repr(self):
|
def test_repr(self):
|
||||||
from configurations.tests.settings.main import Test
|
from configurations.tests.settings.main import Test
|
||||||
self.assertEqual(repr(Test),
|
self.assertEqual(repr(Test),
|
||||||
"<Settings 'configurations.tests.settings.main.Test'>")
|
"<Configuration 'configurations.tests.settings.main.Test'>")
|
||||||
|
|
||||||
@patch.dict(os.environ, clear=True,
|
@patch.dict(os.environ, clear=True,
|
||||||
DJANGO_SETTINGS_MODULE='configurations.tests.settings.main',
|
DJANGO_SETTINGS_MODULE='configurations.tests.settings.main',
|
||||||
DJANGO_CONFIGURATION='Test')
|
DJANGO_CONFIGURATION='Test')
|
||||||
def test_initialization(self):
|
def test_initialization(self):
|
||||||
importer = SettingsImporter()
|
importer = ConfigurationImporter()
|
||||||
self.assertEqual(importer.module, 'configurations.tests.settings.main')
|
self.assertEqual(importer.module, 'configurations.tests.settings.main')
|
||||||
self.assertEqual(importer.name, 'Test')
|
self.assertEqual(importer.name, 'Test')
|
||||||
self.assertEqual(repr(importer),
|
self.assertEqual(repr(importer),
|
||||||
"<SettingsImporter for 'configurations.tests.settings.main.Test'>")
|
"<ConfigurationImporter for 'configurations.tests.settings.main.Test'>")
|
||||||
|
|
||||||
@patch.dict(os.environ, clear=True,
|
@patch.dict(os.environ, clear=True,
|
||||||
DJANGO_SETTINGS_MODULE='configurations.tests.settings.inheritance',
|
DJANGO_SETTINGS_MODULE='configurations.tests.settings.inheritance',
|
||||||
DJANGO_CONFIGURATION='Inheritance')
|
DJANGO_CONFIGURATION='Inheritance')
|
||||||
def test_initialization_inheritance(self):
|
def test_initialization_inheritance(self):
|
||||||
importer = SettingsImporter()
|
importer = ConfigurationImporter()
|
||||||
self.assertEqual(importer.module,
|
self.assertEqual(importer.module,
|
||||||
'configurations.tests.settings.inheritance')
|
'configurations.tests.settings.inheritance')
|
||||||
self.assertEqual(importer.name, 'Inheritance')
|
self.assertEqual(importer.name, 'Inheritance')
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ use of the ``from foo import *`` anti-pattern.
|
||||||
Okay, how does it work?
|
Okay, how does it work?
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
Any subclass of the ``configurations.Settings`` class will automatically
|
Any subclass of the ``configurations.Configuration`` class will automatically
|
||||||
use the values of its class and instance attributes (including properties
|
use the values of its class and instance attributes (including properties
|
||||||
and methods) to set module level variables of the same module -- that's
|
and methods) to set module level variables of the same module -- that's
|
||||||
how Django will interface to the django-configurations based settings during
|
how Django will interface to the django-configurations based settings during
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue