Skip to content

Commit

Permalink
0.2.3
Browse files Browse the repository at this point in the history
-----

* Now `include` function finds parent `globals()` scope automatically
* added protection against infinite recursion with tests
* added tests for stackable settings definition. Check settings example in tests/settings/stacked/.
  • Loading branch information
phpdude committed Dec 7, 2016
1 parent 4749d2b commit f8864de
Show file tree
Hide file tree
Showing 11 changed files with 91 additions and 4 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.rst
Expand Up @@ -2,6 +2,13 @@
Changelog
=========

0.2.3
-----

* Now `include` function finds parent `globals()` scope automatically
* added protection against infinite recursion with tests
* added tests for stackable settings definition. Check settings example in tests/settings/stacked/.

0.2.2
-----

Expand Down
4 changes: 4 additions & 0 deletions README.rst
Expand Up @@ -100,6 +100,8 @@ to override settings in the local installation:
# local settings (do not commit to version control)
optional(os.path.join(os.getcwd(), 'local_settings.py')),
# starting from version 0.2.3 is not necessary to pass scope.
# it finds parent globals() scope automatically. But it still accepts it.
scope=globals()
)
Expand Down Expand Up @@ -189,6 +191,7 @@ Authors
* `akaihola`_
* `roxeteer`_
* `sobolevn`_
* `phpdude`_


Changelog
Expand All @@ -201,4 +204,5 @@ See `changelog`_ file.
.. _`akaihola`: https://github.com/akaihola
.. _`roxeteer`: https://github.com/roxeteer
.. _`sobolevn`: https://github.com/sobolevn
.. _`phpdude`: https://github.com/phpdude
.. _`changelog`: https://github.com/sobolevn/django-split-settings/blob/master/CHANGELOG.rst
2 changes: 1 addition & 1 deletion split_settings/__init__.py
Expand Up @@ -6,6 +6,6 @@
settings files.
"""

__version__ = '0.2.2'
__version__ = '0.2.3'

__all__ = ['__version__']
16 changes: 15 additions & 1 deletion split_settings/tools.py
Expand Up @@ -8,6 +8,7 @@
"""

import glob
import inspect
import os
import sys
import types
Expand Down Expand Up @@ -64,7 +65,15 @@ def include(*args, **kwargs):
IOError: if a required settings file is not found
"""

scope = kwargs.pop('scope')
if 'scope' not in kwargs:
# we are getting globals() from previous frame globals - it is caller's globals()
scope = inspect.stack()[1][0].f_globals
else:
scope = kwargs.pop('scope')

scope.setdefault('__included_files__', [])
included_files = scope.get('__included_files__')

including_file = scope.get('__included_file__',
scope['__file__'].rstrip('c'))
conf_path = os.path.dirname(including_file)
Expand All @@ -79,6 +88,11 @@ def include(*args, **kwargs):
raise IOError('No such file: %s' % pattern)

for included_file in files_to_include:
if included_file in included_files:
continue

included_files.append(included_file)

scope['__included_file__'] = included_file
with open(included_file, 'rb') as to_compile:
exec(compile(to_compile.read(), included_file, 'exec'), scope)
Expand Down
14 changes: 14 additions & 0 deletions tests/settings/recursion/__init__.py
@@ -0,0 +1,14 @@
# -*- coding: utf-8 -*-

import os

import django

from split_settings.tools import optional, include

# Must bypass this block if another settings module was specified.
if os.environ['DJANGO_SETTINGS_MODULE'] == 'tests.settings':

include(
'*.py'
)
1 change: 1 addition & 0 deletions tests/settings/recursion/ok.py
@@ -0,0 +1 @@
RECURSION_OK = True
5 changes: 5 additions & 0 deletions tests/settings/stacked/__init__.py
@@ -0,0 +1,5 @@
from split_settings.tools import include

include(
'base.py'
)
7 changes: 7 additions & 0 deletions tests/settings/stacked/base.py
@@ -0,0 +1,7 @@
from split_settings.tools import include

STACKED_BASE_LOADED = True

include(
'db/*.py'
)
Empty file.
2 changes: 2 additions & 0 deletions tests/settings/stacked/db/persistent.py
@@ -0,0 +1,2 @@
if STACKED_BASE_LOADED:
STACKED_DB_PERSISTENT = True
37 changes: 35 additions & 2 deletions tests/test_tools.py
Expand Up @@ -36,8 +36,8 @@ def test_keys_count():
scope=scope,
)

# Keys: 'FIXTURE_VALUE', '__file__', '__doc__', '__builtins__'
assert len(scope.keys()) == 4
# Keys: 'FIXTURE_VALUE', '__file__', '__doc__', '__builtins__', '__included_files__'
assert len(scope.keys()) == 5


def test_included_file_scope():
Expand Down Expand Up @@ -87,3 +87,36 @@ def test_unicode_passed():
)

assert 'FIXTURE_VALUE' in scope


def test_caller_scope_automatically():
"""
Tests `include` function for automatic `globals()` extraction from execution stack.
Now you can omit positional argument `scope`.
"""

include(
six.text_type(FIXTURE)
)

assert 'FIXTURE_VALUE' in globals()


def test_recursion_inclusion():
"""
Tests `include` function for inclusion files only once. It protects of infinite recursion.
"""

from tests.settings import recursion

assert hasattr(recursion, 'RECURSION_OK')

def test_stacked_settings():
"""
Tests `include` function for inclusion files only once. It protects of infinite recursion.
"""

from tests.settings import stacked

assert hasattr(stacked, 'STACKED_BASE_LOADED')
assert hasattr(stacked, 'STACKED_DB_PERSISTENT')

0 comments on commit f8864de

Please sign in to comment.