Skip to content
This repository has been archived by the owner on Jan 1, 2020. It is now read-only.

Commit

Permalink
Improved 'from_env' decorator
Browse files Browse the repository at this point in the history
  • Loading branch information
dferens committed Mar 8, 2014
1 parent 34806a0 commit 693dc3c
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 7 deletions.
2 changes: 1 addition & 1 deletion classsettings/__init__.py
@@ -1,4 +1,4 @@
from .settings import Settings, Config
from .env import from_env, get_env_setting

__version__ = '1.0.0'
__version__ = '1.0.1'
16 changes: 10 additions & 6 deletions classsettings/env.py
Expand Up @@ -7,22 +7,26 @@


@defaultargs
def from_env(key=None):
def from_env(key=None, through=None):
"""
Gets environment variable by given key.
If key is not given, uses decorated function's name.
If key is not present within environ, calls given function and raises
:class:`ImproperlyConfigured` if it returns `None`.
:param key: env. variable name, defaults to function's name
:param through: callable should be applied to result
"""
def decorator(func):
@functools.wraps(func)
def decorated(*args, **kwargs):
try:
return get_env_setting(key or func.__name__)
value = get_env_setting(key or func.__name__)
except ImproperlyConfigured as e:
default = func(*args, **kwargs)
if default is not None: return default
raise e
value = func(*args, **kwargs)
if value is None:
raise e

return through(value) if through else value

return decorated
return decorator
Expand Down
23 changes: 23 additions & 0 deletions tests.py
Expand Up @@ -118,6 +118,7 @@ def tearDown(self):

def test_has_default(self):
self.assertEqual(os.environ.get('CLASSSETTINGS_ENV'), None)

@from_env(key='CLASSSETTINGS_ENV')
def getter(): return 'default'

Expand All @@ -127,13 +128,35 @@ def getter(): return 'default'

def test_no_default(self):
self.assertEqual(os.environ.get('CLASSSETTINGS_ENV'), None)

@from_env(key='CLASSSETTINGS_ENV')
def getter(): pass

self.assertRaises(ImproperlyConfigured, getter)
os.environ['CLASSSETTINGS_ENV'] = 'value'
self.assertEqual(getter(), 'value')

def test_through_with_env(self):
self.assertEqual(os.environ.get('CLASSSETTINGS_ENV'), None)

filter_func = lambda val: val.upper()

@from_env(key='CLASSSETTINGS_ENV', through=filter_func)
def getter(): pass

os.environ['CLASSSETTINGS_ENV'] = 'value'
self.assertEqual(getter(), 'VALUE')

def test_through_with_default(self):
self.assertEqual(os.environ.get('CLASSSETTINGS_ENV'), None)

filter_func = lambda val: val.upper()

@from_env(key='CLASSSETTINGS_ENV', through=filter_func)
def getter(): return 'default'

self.assertEqual(getter(), 'DEFAULT')


class UtilsTestCase(unittest.TestCase):

Expand Down

0 comments on commit 693dc3c

Please sign in to comment.