mirror of
https://github.com/jazzband/django-configurations.git
synced 2026-03-16 22:20:27 +00:00
Changed the default of the Value's environ option to True.
This commit is contained in:
parent
5f4229057d
commit
927c052be5
4 changed files with 88 additions and 61 deletions
|
|
@ -30,22 +30,22 @@ class FailingCasterValue(CastingMixin, Value):
|
|||
class ValueTests(TestCase):
|
||||
|
||||
def test_value(self):
|
||||
value = Value('default')
|
||||
value = Value('default', environ=False)
|
||||
self.assertEqual(value.setup('TEST'), 'default')
|
||||
with env(DJANGO_TEST='override'):
|
||||
self.assertEqual(value.setup('TEST'), 'default')
|
||||
|
||||
@patch.dict(os.environ, clear=True, DJANGO_TEST='override')
|
||||
def test_env_var(self):
|
||||
value = Value('default', environ=True)
|
||||
value = Value('default')
|
||||
self.assertEqual(value.setup('TEST'), 'override')
|
||||
self.assertNotEqual(value.setup('TEST'), value.default)
|
||||
self.assertEqual(value.to_python(os.environ['DJANGO_TEST']),
|
||||
value.setup('TEST'))
|
||||
|
||||
def test_value_reuse(self):
|
||||
value1 = Value('default', environ=True)
|
||||
value2 = Value(value1, environ=True)
|
||||
value1 = Value('default')
|
||||
value2 = Value(value1)
|
||||
self.assertEqual(value1.setup('TEST1'), 'default')
|
||||
self.assertEqual(value2.setup('TEST2'), 'default')
|
||||
with env(DJANGO_TEST1='override1', DJANGO_TEST2='override2'):
|
||||
|
|
@ -54,15 +54,15 @@ class ValueTests(TestCase):
|
|||
|
||||
def test_env_var_prefix(self):
|
||||
with patch.dict(os.environ, clear=True, ACME_TEST='override'):
|
||||
value = Value('default', environ=True, environ_prefix='ACME')
|
||||
value = Value('default', environ_prefix='ACME')
|
||||
self.assertEqual(value.setup('TEST'), 'override')
|
||||
|
||||
with patch.dict(os.environ, clear=True, TEST='override'):
|
||||
value = Value('default', environ=True, environ_prefix='')
|
||||
value = Value('default', environ_prefix='')
|
||||
self.assertEqual(value.setup('TEST'), 'override')
|
||||
|
||||
def test_boolean_values_true(self):
|
||||
value = BooleanValue(False, environ=True)
|
||||
value = BooleanValue(False)
|
||||
for truthy in value.true_values:
|
||||
with env(DJANGO_TEST=truthy):
|
||||
self.assertTrue(value.setup('TEST'))
|
||||
|
|
@ -71,32 +71,32 @@ class ValueTests(TestCase):
|
|||
self.assertRaises(ImproperlyConfigured, BooleanValue, 'false')
|
||||
|
||||
def test_boolean_values_false(self):
|
||||
value = BooleanValue(True, environ=True)
|
||||
value = BooleanValue(True)
|
||||
for falsy in value.false_values:
|
||||
with env(DJANGO_TEST=falsy):
|
||||
self.assertFalse(value.setup('TEST'))
|
||||
|
||||
def test_boolean_values_nonboolean(self):
|
||||
value = BooleanValue(True, environ=True)
|
||||
value = BooleanValue(True)
|
||||
with env(DJANGO_TEST='nonboolean'):
|
||||
self.assertRaises(ImproperlyConfigured, value.setup, 'TEST')
|
||||
|
||||
def test_integer_values(self):
|
||||
value = IntegerValue(1, environ=True)
|
||||
value = IntegerValue(1)
|
||||
with env(DJANGO_TEST='2'):
|
||||
self.assertEqual(value.setup('TEST'), 2)
|
||||
with env(DJANGO_TEST='noninteger'):
|
||||
self.assertRaises(ImproperlyConfigured, value.setup, 'TEST')
|
||||
|
||||
def test_float_values(self):
|
||||
value = FloatValue(1.0, environ=True)
|
||||
value = FloatValue(1.0)
|
||||
with env(DJANGO_TEST='2.0'):
|
||||
self.assertEqual(value.setup('TEST'), 2.0)
|
||||
with env(DJANGO_TEST='noninteger'):
|
||||
self.assertRaises(ImproperlyConfigured, value.setup, 'TEST')
|
||||
|
||||
def test_decimal_values(self):
|
||||
value = DecimalValue(decimal.Decimal(1), environ=True)
|
||||
value = DecimalValue(decimal.Decimal(1))
|
||||
with env(DJANGO_TEST='2'):
|
||||
self.assertEqual(value.setup('TEST'), decimal.Decimal(2))
|
||||
with env(DJANGO_TEST='nondecimal'):
|
||||
|
|
@ -106,7 +106,7 @@ class ValueTests(TestCase):
|
|||
self.assertRaises(ImproperlyConfigured, FailingCasterValue)
|
||||
|
||||
def test_list_values_default(self):
|
||||
value = ListValue(environ=True)
|
||||
value = ListValue()
|
||||
with env(DJANGO_TEST='2,2'):
|
||||
self.assertEqual(value.setup('TEST'), ['2', '2'])
|
||||
with env(DJANGO_TEST='2, 2 ,'):
|
||||
|
|
@ -115,32 +115,32 @@ class ValueTests(TestCase):
|
|||
self.assertEqual(value.setup('TEST'), [])
|
||||
|
||||
def test_list_values_separator(self):
|
||||
value = ListValue(environ=True, separator=':')
|
||||
value = ListValue(separator=':')
|
||||
with env(DJANGO_TEST='/usr/bin:/usr/sbin:/usr/local/bin'):
|
||||
self.assertEqual(value.setup('TEST'),
|
||||
['/usr/bin', '/usr/sbin', '/usr/local/bin'])
|
||||
|
||||
def test_List_values_converter(self):
|
||||
value = ListValue(environ=True, converter=int)
|
||||
value = ListValue(converter=int)
|
||||
with env(DJANGO_TEST='2,2'):
|
||||
self.assertEqual(value.setup('TEST'), [2, 2])
|
||||
|
||||
value = ListValue(environ=True, converter=float)
|
||||
value = ListValue(converter=float)
|
||||
with env(DJANGO_TEST='2,2'):
|
||||
self.assertEqual(value.setup('TEST'), [2.0, 2.0])
|
||||
|
||||
def test_list_values_custom_converter(self):
|
||||
value = ListValue(environ=True, converter=lambda x: x * 2)
|
||||
value = ListValue(converter=lambda x: x * 2)
|
||||
with env(DJANGO_TEST='2,2'):
|
||||
self.assertEqual(value.setup('TEST'), ['22', '22'])
|
||||
|
||||
def test_list_values_converter_exception(self):
|
||||
value = ListValue(environ=True, converter=int)
|
||||
value = ListValue(converter=int)
|
||||
with env(DJANGO_TEST='2,b'):
|
||||
self.assertRaises(ImproperlyConfigured, value.setup, 'TEST')
|
||||
|
||||
def test_tuple_values_default(self):
|
||||
value = TupleValue(environ=True)
|
||||
value = TupleValue()
|
||||
with env(DJANGO_TEST='2,2'):
|
||||
self.assertEqual(value.setup('TEST'), ('2', '2'))
|
||||
with env(DJANGO_TEST='2, 2 ,'):
|
||||
|
|
@ -149,7 +149,7 @@ class ValueTests(TestCase):
|
|||
self.assertEqual(value.setup('TEST'), ())
|
||||
|
||||
def test_set_values_default(self):
|
||||
value = SetValue(environ=True)
|
||||
value = SetValue()
|
||||
with env(DJANGO_TEST='2,2'):
|
||||
self.assertEqual(value.setup('TEST'), set(['2', '2']))
|
||||
with env(DJANGO_TEST='2, 2 ,'):
|
||||
|
|
@ -158,7 +158,7 @@ class ValueTests(TestCase):
|
|||
self.assertEqual(value.setup('TEST'), set())
|
||||
|
||||
def test_dict_values_default(self):
|
||||
value = DictValue(environ=True)
|
||||
value = DictValue()
|
||||
with env(DJANGO_TEST='{2: 2}'):
|
||||
self.assertEqual(value.setup('TEST'), {2: 2})
|
||||
expected = {2: 2, '3': '3', '4': [1, 2, 3]}
|
||||
|
|
@ -176,21 +176,21 @@ class ValueTests(TestCase):
|
|||
self.assertRaises(ImproperlyConfigured, value.setup, 'TEST')
|
||||
|
||||
def test_email_values(self):
|
||||
value = EmailValue('spam@eg.gs', environ=True)
|
||||
value = EmailValue('spam@eg.gs')
|
||||
with env(DJANGO_TEST='spam@sp.am'):
|
||||
self.assertEqual(value.setup('TEST'), 'spam@sp.am')
|
||||
with env(DJANGO_TEST='spam'):
|
||||
self.assertRaises(ImproperlyConfigured, value.setup, 'TEST')
|
||||
|
||||
def test_url_values(self):
|
||||
value = URLValue('http://eggs.spam', environ=True)
|
||||
value = URLValue('http://eggs.spam')
|
||||
with env(DJANGO_TEST='http://spam.eggs'):
|
||||
self.assertEqual(value.setup('TEST'), 'http://spam.eggs')
|
||||
with env(DJANGO_TEST='httb://spam.eggs'):
|
||||
self.assertRaises(ImproperlyConfigured, value.setup, 'TEST')
|
||||
|
||||
def test_ip_values(self):
|
||||
value = IPValue('0.0.0.0', environ=True)
|
||||
value = IPValue('0.0.0.0')
|
||||
with env(DJANGO_TEST='127.0.0.1'):
|
||||
self.assertEqual(value.setup('TEST'), '127.0.0.1')
|
||||
with env(DJANGO_TEST='::1'):
|
||||
|
|
@ -199,14 +199,14 @@ class ValueTests(TestCase):
|
|||
self.assertRaises(ImproperlyConfigured, value.setup, 'TEST')
|
||||
|
||||
def test_regex_values(self):
|
||||
value = RegexValue('000--000', environ=True, regex=r'\d+--\d+')
|
||||
value = RegexValue('000--000', regex=r'\d+--\d+')
|
||||
with env(DJANGO_TEST='123--456'):
|
||||
self.assertEqual(value.setup('TEST'), '123--456')
|
||||
with env(DJANGO_TEST='123456'):
|
||||
self.assertRaises(ImproperlyConfigured, value.setup, 'TEST')
|
||||
|
||||
def test_path_values_with_check(self):
|
||||
value = PathValue(environ=True)
|
||||
value = PathValue()
|
||||
with env(DJANGO_TEST='/'):
|
||||
self.assertEqual(value.setup('TEST'), '/')
|
||||
with env(DJANGO_TEST='~/'):
|
||||
|
|
@ -215,7 +215,7 @@ class ValueTests(TestCase):
|
|||
self.assertRaises(ImproperlyConfigured, value.setup, 'TEST')
|
||||
|
||||
def test_path_values_no_check(self):
|
||||
value = PathValue(environ=True, check_exists=False)
|
||||
value = PathValue(check_exists=False)
|
||||
with env(DJANGO_TEST='/'):
|
||||
self.assertEqual(value.setup('TEST'), '/')
|
||||
with env(DJANGO_TEST='~/spam/eggs'):
|
||||
|
|
@ -233,7 +233,7 @@ class ValueTests(TestCase):
|
|||
self.assertEqual(value.setup('SECRET_KEY'), '123')
|
||||
|
||||
def test_database_url_value(self):
|
||||
value = DatabaseURLValue(environ=True)
|
||||
value = DatabaseURLValue()
|
||||
self.assertEqual(value.default, {})
|
||||
with env(DATABASE_URL='sqlite://'):
|
||||
self.assertEqual(value.setup('DATABASE_URL'), {
|
||||
|
|
@ -247,7 +247,7 @@ class ValueTests(TestCase):
|
|||
}})
|
||||
|
||||
def test_email_url_value(self):
|
||||
value = EmailURLValue(environ=True)
|
||||
value = EmailURLValue()
|
||||
self.assertEqual(value.default, {})
|
||||
with env(EMAIL_URL='smtps://user@domain.com:password@smtp.example.com:587'):
|
||||
self.assertEqual(value.setup('EMAIL_URL'), {
|
||||
|
|
@ -271,7 +271,7 @@ class ValueTests(TestCase):
|
|||
self.assertRaises(ImproperlyConfigured, value.setup, 'TEST')
|
||||
|
||||
def test_cache_url_value(self):
|
||||
value = CacheURLValue(environ=True)
|
||||
value = CacheURLValue()
|
||||
self.assertEqual(value.default, {})
|
||||
with env(CACHE_URL='redis://user@host:port/1'):
|
||||
self.assertEqual(value.setup('CACHE_URL'), {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class Value(object):
|
|||
"""
|
||||
multiple = False
|
||||
|
||||
def __init__(self, default=None, environ=False, environ_name=None,
|
||||
def __init__(self, default=None, environ=True, environ_name=None,
|
||||
environ_prefix='DJANGO', *args, **kwargs):
|
||||
if isinstance(default, Value):
|
||||
self.default = copy.copy(default.default)
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ Here is an example (from a **settings.py**)::
|
|||
DEBUG = values.BooleanValue(True)
|
||||
|
||||
As you can see all you have to do is to wrap your settings value in a call
|
||||
to one of the included settings classes. When Django's process starts up
|
||||
it will automatically make sure the passed in value validates correctly --
|
||||
to one of the included values classes. When Django's process starts up
|
||||
it will automatically make sure the passed-in value validates correctly --
|
||||
in the above case checks if the value is really a boolean.
|
||||
|
||||
You can safely use other :class:`~Value` instances as the default setting
|
||||
|
|
@ -47,39 +47,67 @@ settings system Django uses.
|
|||
Luckily django-configurations' :class:`~Value` subclasses have the ability
|
||||
to handle environment variables for the most common use cases.
|
||||
|
||||
For example, imagine you'd like to override the ``TEMPLATE_DEBUG`` setting
|
||||
on your staging server to be able to debug a problem with your in-development
|
||||
code. You're using a web server that passes the environment variables from
|
||||
the shell it was started in to your Django WSGI process.
|
||||
Default behavior
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
First make sure you set the ``environ`` option of the :class:`~Value` instance
|
||||
to ``True``::
|
||||
For example, imagine you'd like to override the ``ROOT_URLCONF`` setting
|
||||
on your staging server to be able to debug a problem with your in-development
|
||||
code. You're also using a web server that passes the environment variables from
|
||||
the shell it was started from into your Django WSGI process.
|
||||
|
||||
Each :class:`~Value` class instance has an ``environ`` option, that when set to
|
||||
``True`` (default) django-configurations will look for an uppercase
|
||||
environment variable named like the :class:`~Value` instance's name, prefixed
|
||||
with ``DJANGO_``. So imagine the following example::
|
||||
|
||||
from configurations import values
|
||||
|
||||
# ..
|
||||
TEMPLATE_DEBUG = values.BooleanValue(True, environ=True)
|
||||
ROOT_URLCONF = values.Value('mysite.urls')
|
||||
|
||||
That will tell django-configurations to look for a environment variable
|
||||
named ``DJANGO_TEMPLATE_DEBUG`` when deciding which value of the ``DEBUG``
|
||||
setting to actually enable.
|
||||
django-configurations will try to read the ``DJANGO_ROOT_URLCONF`` environment
|
||||
variable when deciding which value the ``ROOT_URLCONF`` setting should have.
|
||||
|
||||
When you run your web server simply specify that environment variable
|
||||
(e.g. in your init script)::
|
||||
|
||||
DJANGO_TEMPLATE_DEBUG=true gunicorn mysite.wsgi:application
|
||||
DJANGO_ROOT_URLCONF=mysite.debugging_urls gunicorn mysite.wsgi:application
|
||||
|
||||
Since environment variables are string based the ``BooleanValue`` supports
|
||||
a series of possible formats for a boolean value (``true``, ``yes``,
|
||||
``y`` and ``1``, all in capital and lower case, and ``false``, ``no``,
|
||||
``n`` and ``0`` of course). So for example this will work, too::
|
||||
Disabling environment variables
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
DJANGO_TEMPLATE_DEBUG=no ./manage.py runserver
|
||||
To disable django-configurations' automatic use of environment variables,
|
||||
you can specify the ``environ`` parameter of the :class:`~Value` class.
|
||||
For example this would disable it for the ``TIME_ZONE`` setting value::
|
||||
|
||||
TIME_ZONE = values.Value('UTC', environ=False)
|
||||
|
||||
Custom environment variable names
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
To support legacy systems, integrate with other parts of your sofware stack or
|
||||
simply better match your taste in naming public configuration variables,
|
||||
django-configurations allows you to use the ``environ_name`` parameter of the
|
||||
:class:`~Value` class to change the name of the environment variable it looks
|
||||
for. For example this would enforce a specific environment variable name
|
||||
instead of using the name of the :class:`~Value` instance.::
|
||||
|
||||
TIME_ZONE = values.Value('UTC', environ_name='MYSITE_TZ')
|
||||
|
||||
Custom environment variable prefixes
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In case you just want to change the default environment variable name prefix
|
||||
of ``DJANGO`` to something to your likening, use the ``environ_prefix``
|
||||
parameter of the :class:`~Value` instance. Here it'll look for the
|
||||
``MYSITE_TIME_ZONE`` environment variable (instead of ``DJANGO_TIME_ZONE``)::
|
||||
|
||||
TIME_ZONE = values.Value('UTC', environ_prefix='MYSITE')
|
||||
|
||||
``Value`` class
|
||||
---------------
|
||||
|
||||
.. class:: Value(default, [environ=False, environ_name=None, environ_prefix='DJANGO'])
|
||||
.. class:: Value(default, [environ=True, environ_name=None, environ_prefix='DJANGO'])
|
||||
|
||||
The ``Value`` class takes one required and several optional parameters.
|
||||
|
||||
|
|
@ -114,10 +142,10 @@ a series of possible formats for a boolean value (``true``, ``yes``,
|
|||
environment
|
||||
|
||||
The ``to_python`` method is only used when the ``environ`` parameter
|
||||
of the :class:`~Value` class is set to ``True`` and an environment
|
||||
variable with the appropriate name was found. It will be used to handle
|
||||
the string based environment variable values and returns the "ready"
|
||||
value to be returned by the ``setup`` method.
|
||||
of the :class:`~Value` class is set to ``True`` (the default) and an
|
||||
environment variable with the appropriate name was found. It will be
|
||||
used to handle the string based environment variable values and returns
|
||||
the "ready" value to be returned by the ``setup`` method.
|
||||
|
||||
Built-ins
|
||||
---------
|
||||
|
|
@ -185,8 +213,7 @@ Type values
|
|||
return person
|
||||
|
||||
MONTY_PYTHONS = ListValue(['John Cleese', 'Eric Idle'],
|
||||
converter=check_monty_python,
|
||||
environ=True)
|
||||
converter=check_monty_python)
|
||||
|
||||
You can override this list with an environment variable like this::
|
||||
|
||||
|
|
@ -194,8 +221,7 @@ Type values
|
|||
|
||||
Use a custom separator::
|
||||
|
||||
EMERGENCY_EMAILS = ListValue(['admin@mysite.net'],
|
||||
separator=';', environ=True)
|
||||
EMERGENCY_EMAILS = ListValue(['admin@mysite.net'], separator=';')
|
||||
|
||||
And override it::
|
||||
|
||||
|
|
@ -253,7 +279,7 @@ Validator values
|
|||
|
||||
LOADBALANCER_IP = values.IPValue('127.0.0.1')
|
||||
|
||||
.. class:: RegexValue(default, regex, [environ=False, environ_name=None, environ_prefix='DJANGO'])
|
||||
.. class:: RegexValue(default, regex, [environ=True, environ_name=None, environ_prefix='DJANGO'])
|
||||
|
||||
A :class:`~Value` subclass that validates according a regular expression
|
||||
and uses the :class:`django:django.core.validators.RegexValidator`.
|
||||
|
|
@ -264,7 +290,7 @@ Validator values
|
|||
|
||||
DEFAULT_SKU = values.RegexValue('000-000-00', regex=r'\d{3}-\d{3}-\d{2}')
|
||||
|
||||
.. class:: PathValue(default, [check_exists=True, environ=False, environ_name=None, environ_prefix='DJANGO'])
|
||||
.. class:: PathValue(default, [check_exists=True, environ=True, environ_name=None, environ_prefix='DJANGO'])
|
||||
|
||||
A :class:`~Value` subclass that normalizes the given path using
|
||||
:func:`os.path.expanduser` and validates if it exists on the file system.
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@ import os
|
|||
import sys
|
||||
|
||||
if __name__ == "__main__":
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'configurations.tests.settings.main')
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE',
|
||||
'configurations.tests.settings.main')
|
||||
os.environ.setdefault('DJANGO_CONFIGURATION', 'Test')
|
||||
|
||||
from configurations.management import execute_from_command_line
|
||||
|
|
|
|||
Loading…
Reference in a new issue