Skip to content
This repository has been archived by the owner on Feb 11, 2023. It is now read-only.

Commit

Permalink
Fixes #161 -- is_default and has_value take into consideration value …
Browse files Browse the repository at this point in the history
…override set via environment variables
  • Loading branch information
jbasko committed Jun 25, 2017
1 parent b5c405d commit a4339b0
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 15 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 1.32.0
current_version = 1.32.1
commit = true
tag = false

Expand Down
2 changes: 1 addition & 1 deletion configmanager/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = '1.32.0'
__version__ = '1.32.1'

from .managers import Config
from .items import Item
Expand Down
50 changes: 38 additions & 12 deletions configmanager/items.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,23 +175,38 @@ def default(self, value):
return
self._default = self.type.deserialize(value)

def _get_envvar_value(self):
"""
Internal helper to get item value from an environment variable
if item is controlled by one, and if the variable is set.
Returns not_set otherwise.
"""
envvar_name = None

if self.envvar is True:
envvar_name = self.envvar_name
if envvar_name is None:
envvar_name = '_'.join(self.get_path()).upper()
elif self.envvar:
envvar_name = self.envvar

if envvar_name and envvar_name in os.environ:
return self.type.deserialize(os.environ[envvar_name])
else:
return not_set

def get(self, fallback=not_set):
"""
Returns config value.
See Also:
:meth:`.set` and :attr:`.value`
"""
if self.envvar:
if self.envvar is True:
envvar_name = self.envvar_name
if envvar_name is None:
envvar_name = '_'.join(self.get_path()).upper()
if envvar_name in os.environ:
return self.type.deserialize(os.environ[envvar_name])
else:
if self.envvar in os.environ:
return self.type.deserialize(os.environ[self.envvar])

envvar_value = self._get_envvar_value()
if envvar_value is not not_set:
return envvar_value

if self.has_value:
if self._value is not not_set:
Expand Down Expand Up @@ -268,15 +283,26 @@ def reset(self):
def is_default(self):
"""
``True`` if the item's value is its default value or if no value and no default value are set.
If the item is backed by an environment variable, this will be ``True`` only
if the environment variable is set and is different to the
default value of the item.
"""
return self._value is not_set or self._value == self.default
envvar_value = self._get_envvar_value()
if envvar_value is not not_set:
return envvar_value == self.default
else:
return self._value is not_set or self._value == self.default

@property
def has_value(self):
"""
``True`` if item has a default value or custom value set.
"""
return self.default is not not_set or self._value is not not_set
if self._get_envvar_value() is not not_set:
return True
else:
return self.default is not not_set or self._value is not not_set

@property
def section(self):
Expand Down
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ Similarly to reading, you find the appropriate persistence adapter, and use the
config.json.dump('~/.config/helloworld/config.json', with_defaults=True)
Unless you also pass ``with_defaults=True``, ::dump:: will not include items who don't have a custom value set.
Unless you also pass ``with_defaults=True``, ``dump`` will exclude values for items who have no custom value set.

How do I export all configuration values to a dictionary?
---------------------------------------------------------
Expand Down
19 changes: 19 additions & 0 deletions tests/test_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,17 @@ def test_is_default():
assert e.is_default


def test_is_default_respects_envvar(monkeypatch):
a = Item('a', default=5, envvar=True)
assert a.is_default

monkeypatch.setenv('A', '5')
assert a.is_default

monkeypatch.setenv('A', '6')
assert not a.is_default


def test_has_value_returns_true_if_value_or_default_is_set():
c = Item()
assert not c.has_value
Expand All @@ -277,6 +288,14 @@ def test_has_value_returns_true_if_value_or_default_is_set():
assert not e.has_value


def test_has_value_respects_envvar(monkeypatch):
a = Item('a', envvar=True, type=int)
assert not a.has_value

monkeypatch.setenv('A', '5')
assert a.has_value


def test_type_is_guessed_either_from_default_or_value():
c = Item()
assert c.type is Types.str
Expand Down

0 comments on commit a4339b0

Please sign in to comment.