Merge branch 'release/1.0'
This commit is contained in:
commit
75c8ca4fd6
|
@ -0,0 +1,6 @@
|
|||
[run]
|
||||
source = appconf
|
||||
branch = 1
|
||||
|
||||
[report]
|
||||
omit = *tests*
|
|
@ -5,3 +5,5 @@ MANIFEST
|
|||
*.egg-info
|
||||
*.egg
|
||||
docs/_build/
|
||||
.coverage
|
||||
.tox/
|
61
.travis.yml
61
.travis.yml
|
@ -1,35 +1,30 @@
|
|||
language: python
|
||||
python:
|
||||
- "2.5"
|
||||
- "2.6"
|
||||
- "2.7"
|
||||
- "3.2"
|
||||
before_install:
|
||||
- export PIP_USE_MIRRORS=true
|
||||
- export PIP_INDEX_URL=https://simple.crate.io/
|
||||
- export DJANGO_SETTINGS_MODULE=appconf.test_settings
|
||||
install:
|
||||
- pip install -e .
|
||||
- pip install https://github.com/django/django/archive/${DJANGO}.zip#egg=django
|
||||
- pip install -r requirements/tests.txt
|
||||
before_script:
|
||||
- flake8 appconf --ignore=E501
|
||||
script:
|
||||
- coverage run --branch --source=appconf `which django-admin.py` test appconf
|
||||
- coverage report --omit=appconf/test*
|
||||
env:
|
||||
- DJANGO=1.3.5
|
||||
- DJANGO=1.4.3
|
||||
- DJANGO=1.5b2
|
||||
branches:
|
||||
except:
|
||||
- master
|
||||
|
||||
matrix:
|
||||
exclude:
|
||||
- python: "2.5"
|
||||
env: DJANGO=1.5b2
|
||||
- python: "3.2"
|
||||
env: DJANGO=1.3.5
|
||||
- python: "3.2"
|
||||
env: DJANGO=1.4.3
|
||||
- TOXENV=flake8-py27
|
||||
- TOXENV=flake8-py33
|
||||
- TOXENV=py26-dj14
|
||||
- TOXENV=py27-dj14
|
||||
- TOXENV=py26-dj15
|
||||
- TOXENV=py26-dj16
|
||||
- TOXENV=py27-dj15
|
||||
- TOXENV=py27-dj16
|
||||
- TOXENV=py32-dj15
|
||||
- TOXENV=py32-dj16
|
||||
- TOXENV=py33-dj15
|
||||
- TOXENV=py33-dj16
|
||||
- TOXENV=py27-dj17
|
||||
- TOXENV=py27-dj18
|
||||
- TOXENV=py27-dj19
|
||||
- TOXENV=py32-dj17
|
||||
- TOXENV=py32-dj18
|
||||
- TOXENV=py32-dj19
|
||||
- TOXENV=py33-dj17
|
||||
- TOXENV=py33-dj18
|
||||
- TOXENV=py33-dj19
|
||||
- TOXENV=py34-dj17
|
||||
- TOXENV=py34-dj18
|
||||
- TOXENV=py34-dj19
|
||||
install:
|
||||
- pip install tox
|
||||
script:
|
||||
- tox
|
||||
|
|
3
AUTHORS
3
AUTHORS
|
@ -2,4 +2,5 @@ Christopher Grebs
|
|||
Jannis Leidel
|
||||
Matthew Tretter
|
||||
Rafal Stozek
|
||||
Chris Streeter
|
||||
Chris Streeter
|
||||
Patrick Altman
|
||||
|
|
10
README.rst
10
README.rst
|
@ -8,6 +8,16 @@ django-appconf
|
|||
A helper class for handling configuration defaults of packaged Django
|
||||
apps gracefully.
|
||||
|
||||
.. note::
|
||||
|
||||
This app precedes Django's own AppConfig_ classes that act as
|
||||
"objects [to] store metadata for an application" inside Django's
|
||||
app loading mechanism. In other words, they solve a related but
|
||||
different use case than django-appconf and can't easily be used
|
||||
as a replacement. The similarity in name is purely coincidental.
|
||||
|
||||
.. _AppConfig: https://docs.djangoproject.com/en/stable/ref/applications/#django.apps.AppConfig
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
from __future__ import absolute_import
|
||||
from .base import AppConf # noqa
|
||||
|
||||
# following PEP 386
|
||||
__version__ = "0.6"
|
||||
__version__ = "1.0"
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
from django.core.exceptions import ImproperlyConfigured
|
||||
import sys
|
||||
|
||||
import six
|
||||
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
|
||||
from .utils import import_attribute
|
||||
|
||||
|
||||
|
@ -108,7 +111,6 @@ class AppConf(six.with_metaclass(AppConfMetaClass)):
|
|||
An app setting object to be used for handling app setting defaults
|
||||
gracefully and providing a nice API for them.
|
||||
"""
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
for name, value in six.iteritems(kwargs):
|
||||
setattr(self, name, value)
|
||||
|
@ -142,6 +144,5 @@ class AppConf(six.with_metaclass(AppConfMetaClass)):
|
|||
"""
|
||||
Hook for doing any extra configuration, returning a dictionary
|
||||
containing the configured data.
|
||||
|
||||
"""
|
||||
return self.configured_data
|
||||
|
|
|
@ -2,7 +2,10 @@ import sys
|
|||
|
||||
|
||||
def import_attribute(import_path, exception_handler=None):
|
||||
from django.utils.importlib import import_module
|
||||
try:
|
||||
from importlib import import_module
|
||||
except ImportError:
|
||||
from django.utils.importlib import import_module
|
||||
module_name, object_name = import_path.rsplit('.', 1)
|
||||
try:
|
||||
module = import_module(module_name)
|
||||
|
|
|
@ -1,6 +1,25 @@
|
|||
Changelog
|
||||
=========
|
||||
|
||||
1.0 (2015-02-15)
|
||||
----------------
|
||||
|
||||
.. note::
|
||||
|
||||
This app precedes Django's own AppConfig_ classes that act as
|
||||
"objects [to] store metadata for an application" inside Django's
|
||||
app loading mechanism. In other words, they solve a related but
|
||||
different use case than django-appconf and can't easily be used
|
||||
as a replacement. The similarity in name is purely coincidental.
|
||||
|
||||
* Dropped support of Python 2.5.
|
||||
|
||||
* Added support for Django 1.7 and 1.8.
|
||||
|
||||
* Modernized test setup.
|
||||
|
||||
.. _AppConfig: https://docs.djangoproject.com/en/stable/ref/applications/#django.apps.AppConfig
|
||||
|
||||
0.6 (2013-01-28)
|
||||
----------------
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ simply pass the value when instantiating the ``AppConf`` class::
|
|||
|
||||
myapp_settings = MyAppConf(SETTING_1='something completely different')
|
||||
|
||||
if 'different' in myapp_settings.SETTINGS_1:
|
||||
if 'different' in myapp_settings.SETTING_1:
|
||||
print "yay, I'm different!"
|
||||
|
||||
Custom configuration
|
||||
|
@ -72,7 +72,7 @@ or the override value from the global settings as the only parameter.
|
|||
The method **must return** the value to be use for the setting in
|
||||
question.
|
||||
|
||||
After each of the ``*_configure`` methods have been called, the ``AppConf``
|
||||
After each of the ``configure_*`` methods has been called, the ``AppConf``
|
||||
class will additionally call a main ``configure`` method, which can
|
||||
be used to do any further custom configuration handling, e.g. if multiple
|
||||
settings depend on each other. For that a ``configured_data`` dictionary
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
flake8
|
||||
coverage
|
||||
django-discover-runner==0.3
|
15
setup.py
15
setup.py
|
@ -28,26 +28,23 @@ setup(
|
|||
author_email='jannis@leidel.info',
|
||||
license='BSD',
|
||||
url='http://django-appconf.readthedocs.org/',
|
||||
packages=[
|
||||
'appconf',
|
||||
'appconf.tests',
|
||||
],
|
||||
install_requires=[
|
||||
'six'
|
||||
],
|
||||
packages=['appconf'],
|
||||
install_requires=['six'],
|
||||
classifiers=[
|
||||
'Development Status :: 4 - Beta',
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Environment :: Web Environment',
|
||||
'Framework :: Django',
|
||||
'Intended Audience :: Developers',
|
||||
'License :: OSI Approved :: BSD License',
|
||||
'Operating System :: OS Independent',
|
||||
'Programming Language :: Python',
|
||||
'Programming Language :: Python :: 2.5',
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.6',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.2',
|
||||
'Programming Language :: Python :: 3.3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Topic :: Utilities',
|
||||
],
|
||||
)
|
||||
|
|
|
@ -61,5 +61,6 @@ class CustomHolderConf(AppConf):
|
|||
SIMPLE_VALUE = True
|
||||
|
||||
class Meta:
|
||||
holder = 'appconf.tests.models.custom_holder' # instead of django.conf.settings
|
||||
# instead of django.conf.settings
|
||||
holder = 'tests.models.custom_holder'
|
||||
prefix = 'custom_holder'
|
|
@ -1,3 +1,5 @@
|
|||
import django
|
||||
|
||||
SITE_ID = 1
|
||||
|
||||
DATABASES = {
|
||||
|
@ -12,8 +14,10 @@ INSTALLED_APPS = [
|
|||
'django.contrib.sites',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.admin',
|
||||
'appconf.tests',
|
||||
'tests',
|
||||
]
|
||||
|
||||
TEST_RUNNER = 'discover_runner.DiscoverRunner'
|
||||
if django.VERSION[:2] < (1, 6):
|
||||
TEST_RUNNER = 'discover_runner.DiscoverRunner'
|
||||
|
||||
SECRET_KEY = 'local'
|
|
@ -3,49 +3,51 @@ from django.conf import settings
|
|||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.test import TestCase
|
||||
|
||||
from appconf.tests.models import (AppConf, TestConf, PrefixConf,
|
||||
YetAnotherPrefixConf, SeparateConf, ProxyConf,
|
||||
CustomHolderConf, custom_holder)
|
||||
from .models import (AppConf, TestConf, PrefixConf,
|
||||
YetAnotherPrefixConf, SeparateConf,
|
||||
ProxyConf, CustomHolderConf, custom_holder)
|
||||
|
||||
|
||||
class TestConfTests(TestCase):
|
||||
|
||||
def test_basic(self):
|
||||
self.assertEquals(TestConf._meta.prefix, 'tests')
|
||||
self.assertEqual(TestConf._meta.prefix, 'tests')
|
||||
|
||||
def test_simple(self):
|
||||
self.assertTrue(hasattr(settings, 'TESTS_SIMPLE_VALUE'))
|
||||
self.assertEquals(settings.TESTS_SIMPLE_VALUE, True)
|
||||
self.assertEqual(settings.TESTS_SIMPLE_VALUE, True)
|
||||
|
||||
def test_configured(self):
|
||||
self.assertTrue(hasattr(settings, 'TESTS_CONFIGURED_VALUE'))
|
||||
self.assertEquals(settings.TESTS_CONFIGURED_VALUE, 'correct')
|
||||
self.assertEqual(settings.TESTS_CONFIGURED_VALUE, 'correct')
|
||||
|
||||
def test_configure_method(self):
|
||||
self.assertTrue(hasattr(settings, 'TESTS_CONFIGURE_METHOD_VALUE'))
|
||||
self.assertEquals(settings.TESTS_CONFIGURE_METHOD_VALUE, True)
|
||||
self.assertEqual(settings.TESTS_CONFIGURE_METHOD_VALUE, True)
|
||||
|
||||
def test_init_kwargs(self):
|
||||
custom_conf = TestConf(CUSTOM_VALUE='custom')
|
||||
self.assertEquals(custom_conf.CUSTOM_VALUE, 'custom')
|
||||
self.assertEquals(settings.TESTS_CUSTOM_VALUE, 'custom')
|
||||
self.assertRaises(AttributeError, lambda: custom_conf.TESTS_CUSTOM_VALUE)
|
||||
self.assertEqual(custom_conf.CUSTOM_VALUE, 'custom')
|
||||
self.assertEqual(settings.TESTS_CUSTOM_VALUE, 'custom')
|
||||
self.assertRaises(AttributeError,
|
||||
lambda: custom_conf.TESTS_CUSTOM_VALUE)
|
||||
custom_conf.CUSTOM_VALUE_SETATTR = 'custom'
|
||||
self.assertEquals(settings.TESTS_CUSTOM_VALUE_SETATTR, 'custom')
|
||||
self.assertEqual(settings.TESTS_CUSTOM_VALUE_SETATTR, 'custom')
|
||||
custom_conf.custom_value_lowercase = 'custom'
|
||||
self.assertRaises(AttributeError, lambda: settings.custom_value_lowercase)
|
||||
self.assertRaises(AttributeError,
|
||||
lambda: settings.custom_value_lowercase)
|
||||
|
||||
def test_init_kwargs_with_prefix(self):
|
||||
custom_conf = TestConf(TESTS_CUSTOM_VALUE2='custom2')
|
||||
self.assertEquals(custom_conf.TESTS_CUSTOM_VALUE2, 'custom2')
|
||||
self.assertEquals(settings.TESTS_CUSTOM_VALUE2, 'custom2')
|
||||
self.assertEqual(custom_conf.TESTS_CUSTOM_VALUE2, 'custom2')
|
||||
self.assertEqual(settings.TESTS_CUSTOM_VALUE2, 'custom2')
|
||||
|
||||
def test_proxy(self):
|
||||
custom_conf = ProxyConf(CUSTOM_VALUE3='custom3')
|
||||
self.assertEquals(custom_conf.CUSTOM_VALUE3, 'custom3')
|
||||
self.assertEquals(settings.TESTS_CUSTOM_VALUE3, 'custom3')
|
||||
self.assertEquals(custom_conf.TESTS_CUSTOM_VALUE3, 'custom3')
|
||||
self.assertTrue('appconf.tests' in custom_conf.INSTALLED_APPS)
|
||||
self.assertEqual(custom_conf.CUSTOM_VALUE3, 'custom3')
|
||||
self.assertEqual(settings.TESTS_CUSTOM_VALUE3, 'custom3')
|
||||
self.assertEqual(custom_conf.TESTS_CUSTOM_VALUE3, 'custom3')
|
||||
self.assertTrue('tests' in custom_conf.INSTALLED_APPS)
|
||||
|
||||
def test_dir_members(self):
|
||||
custom_conf = TestConf()
|
||||
|
@ -60,63 +62,63 @@ class TestConfTests(TestCase):
|
|||
def test_custom_holder(self):
|
||||
CustomHolderConf()
|
||||
self.assertTrue(hasattr(custom_holder, 'CUSTOM_HOLDER_SIMPLE_VALUE'))
|
||||
self.assertEquals(custom_holder.CUSTOM_HOLDER_SIMPLE_VALUE, True)
|
||||
self.assertEqual(custom_holder.CUSTOM_HOLDER_SIMPLE_VALUE, True)
|
||||
|
||||
def test_subclass_configured_data(self):
|
||||
self.assertTrue('TESTS_CONFIGURE_METHOD_VALUE2' in dir(settings))
|
||||
self.assertEquals(settings.TESTS_CONFIGURE_METHOD_VALUE2, False)
|
||||
self.assertEqual(settings.TESTS_CONFIGURE_METHOD_VALUE2, False)
|
||||
|
||||
|
||||
class PrefixConfTests(TestCase):
|
||||
|
||||
def test_prefix(self):
|
||||
self.assertEquals(PrefixConf._meta.prefix, 'prefix')
|
||||
self.assertEqual(PrefixConf._meta.prefix, 'prefix')
|
||||
|
||||
def test_simple(self):
|
||||
self.assertTrue(hasattr(settings, 'PREFIX_SIMPLE_VALUE'))
|
||||
self.assertEquals(settings.PREFIX_SIMPLE_VALUE, True)
|
||||
self.assertEqual(settings.PREFIX_SIMPLE_VALUE, True)
|
||||
|
||||
def test_configured(self):
|
||||
self.assertTrue(hasattr(settings, 'PREFIX_CONFIGURED_VALUE'))
|
||||
self.assertEquals(settings.PREFIX_CONFIGURED_VALUE, 'correct')
|
||||
self.assertEqual(settings.PREFIX_CONFIGURED_VALUE, 'correct')
|
||||
|
||||
def test_configure_method(self):
|
||||
self.assertTrue(hasattr(settings, 'PREFIX_CONFIGURE_METHOD_VALUE'))
|
||||
self.assertEquals(settings.PREFIX_CONFIGURE_METHOD_VALUE, True)
|
||||
self.assertEqual(settings.PREFIX_CONFIGURE_METHOD_VALUE, True)
|
||||
|
||||
|
||||
class YetAnotherPrefixConfTests(TestCase):
|
||||
|
||||
def test_prefix(self):
|
||||
self.assertEquals(YetAnotherPrefixConf._meta.prefix,
|
||||
'yetanother_prefix')
|
||||
self.assertEqual(YetAnotherPrefixConf._meta.prefix,
|
||||
'yetanother_prefix')
|
||||
|
||||
def test_simple(self):
|
||||
self.assertTrue(hasattr(settings,
|
||||
'YETANOTHER_PREFIX_SIMPLE_VALUE'))
|
||||
self.assertEquals(settings.YETANOTHER_PREFIX_SIMPLE_VALUE, False)
|
||||
self.assertEqual(settings.YETANOTHER_PREFIX_SIMPLE_VALUE, False)
|
||||
|
||||
def test_configured(self):
|
||||
self.assertTrue(hasattr(settings,
|
||||
'YETANOTHER_PREFIX_CONFIGURED_VALUE'))
|
||||
self.assertEquals(settings.YETANOTHER_PREFIX_CONFIGURED_VALUE,
|
||||
'correct')
|
||||
self.assertEqual(settings.YETANOTHER_PREFIX_CONFIGURED_VALUE,
|
||||
'correct')
|
||||
|
||||
def test_configure_method(self):
|
||||
self.assertTrue(hasattr(settings,
|
||||
'YETANOTHER_PREFIX_CONFIGURE_METHOD_VALUE'))
|
||||
self.assertEquals(settings.YETANOTHER_PREFIX_CONFIGURE_METHOD_VALUE,
|
||||
True)
|
||||
self.assertEqual(settings.YETANOTHER_PREFIX_CONFIGURE_METHOD_VALUE,
|
||||
True)
|
||||
|
||||
|
||||
class SeparateConfTests(TestCase):
|
||||
|
||||
def test_prefix(self):
|
||||
self.assertEquals(SeparateConf._meta.prefix, 'prefix')
|
||||
self.assertEqual(SeparateConf._meta.prefix, 'prefix')
|
||||
|
||||
def test_simple(self):
|
||||
self.assertTrue(hasattr(settings, 'PREFIX_SEPARATE_VALUE'))
|
||||
self.assertEquals(settings.PREFIX_SEPARATE_VALUE, True)
|
||||
self.assertEqual(settings.PREFIX_SEPARATE_VALUE, True)
|
||||
|
||||
|
||||
class RequiredSettingsTests(TestCase):
|
||||
|
@ -129,7 +131,7 @@ class RequiredSettingsTests(TestCase):
|
|||
def test_value_is_defined(self):
|
||||
class RequirementConf(AppConf):
|
||||
class Meta:
|
||||
holder = 'appconf.tests.models.custom_holder'
|
||||
holder = 'tests.models.custom_holder'
|
||||
prefix = 'holder'
|
||||
required = ['VALUE']
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
[tox]
|
||||
skipsdist = True
|
||||
usedevelop = True
|
||||
minversion = 1.8
|
||||
envlist =
|
||||
flake8-py27,
|
||||
flake8-py33,
|
||||
py{26,27}-dj14,
|
||||
py{26,27,32,33}-dj{15,16},
|
||||
py{27,32,33,34}-dj{17,18,19},
|
||||
|
||||
[testenv]
|
||||
basepython =
|
||||
py26: python2.6
|
||||
py27: python2.7
|
||||
py32: python3.2
|
||||
py33: python3.3
|
||||
py34: python3.4
|
||||
pypy: pypy
|
||||
usedevelop = true
|
||||
setenv =
|
||||
PYTHONPATH = {toxinidir}
|
||||
DJANGO_SETTINGS_MODULE=tests.test_settings
|
||||
deps =
|
||||
flake8
|
||||
coverage
|
||||
django-discover-runner
|
||||
dj13: https://github.com/django/django/archive/stable/1.3.x.zip#egg=django
|
||||
dj14: https://github.com/django/django/archive/stable/1.4.x.zip#egg=django
|
||||
dj15: https://github.com/django/django/archive/stable/1.5.x.zip#egg=django
|
||||
dj16: https://github.com/django/django/archive/stable/1.6.x.zip#egg=django
|
||||
dj17: https://github.com/django/django/archive/stable/1.7.x.zip#egg=django
|
||||
dj18: https://github.com/django/django/archive/stable/1.8.x.zip#egg=django
|
||||
dj19: https://github.com/django/django/archive/master.zip#egg=django
|
||||
|
||||
commands =
|
||||
coverage run {envbindir}/django-admin.py test -v2 {posargs:tests}
|
||||
coverage report
|
||||
|
||||
[testenv:flake8-py27]
|
||||
commands = flake8 appconf
|
||||
deps = flake8
|
||||
|
||||
[testenv:flake8-py33]
|
||||
commands = flake8 appconf
|
||||
deps = flake8
|
||||
|
||||
[flake8]
|
||||
exclude = .tox
|
||||
ignore = E501
|
Loading…
Reference in New Issue