Skip to content

Commit

Permalink
Apply variable expansion to default values (#204)
Browse files Browse the repository at this point in the history
* Apply variable expansion to default values

If a default includes a reference to a variable, expand that reference.
See test_environs.test_default_expands.
Note: type for subs_default is required because of a bug in mypy:
  python/mypy#5423

* Update CHANGELOG

Co-authored-by: Richard Cohn <[email protected]>
Co-authored-by: Steven Loria <[email protected]>
  • Loading branch information
3 people authored Feb 7, 2021
1 parent b95960b commit dad57b7
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 8 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## 9.3.1 (unreleased)

Bug fixes:

- Apply variable expansion to default values ([#204](https://github.com/sloria/environs/pull/204)).
Thanks [rjcohn](https://github.com/rjcohn) for the PR.

## 9.3.0 (2020-12-26)

Deprecations:
Expand Down
14 changes: 6 additions & 8 deletions environs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,19 +72,15 @@ def method(
field = field_or_factory(missing=missing, **kwargs)
else:
field = field_or_factory(subcast=subcast, missing=missing, **kwargs)
parsed_key, raw_value, proxied_key = self._get_from_environ(name, ma.missing)
parsed_key, value, proxied_key = self._get_from_environ(name, field.missing)
self._fields[parsed_key] = field
source_key = proxied_key or parsed_key
if raw_value is ma.missing and field.missing is ma.missing:
if value is ma.missing:
if self.eager:
raise EnvError('Environment variable "{}" not set'.format(proxied_key or parsed_key))
else:
self._errors[parsed_key].append("Environment variable not set.")
return None
if raw_value or raw_value == "":
value = raw_value
else:
value = field.missing if field.missing is not ma.missing else None
if preprocess:
value = preprocess(value, subcast=subcast, **kwargs)
try:
Expand Down Expand Up @@ -438,10 +434,12 @@ def _get_from_environ(
if hasattr(value, "strip"):
expand_match = self.expand_vars and _EXPANDED_VAR_PATTERN.match(value)
if expand_match: # Full match expand_vars - special case keep default
proxied_key = expand_match.groups()[0]
subs_default = expand_match.groups()[1]
proxied_key: _StrType = expand_match.groups()[0]
subs_default: typing.Optional[_StrType] = expand_match.groups()[1]
if subs_default is not None:
default = subs_default[2:]
elif value == default: # if we have used default, don't use it recursively
default = ma.missing
return (key, self._get_from_environ(proxied_key, default, proxied=True)[1], proxied_key)
expand_search = self.expand_vars and _EXPANDED_VAR_PATTERN.search(value)
if expand_search: # Multiple or in text match expand_vars - General case - default lost
Expand Down
15 changes: 15 additions & 0 deletions tests/test_environs.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ def test_call(self, set_env, env):
set_env({"STR": "foo", "INT": "42"})
assert env("STR") == "foo"
assert env("NOT_SET", "mydefault") == "mydefault"
with pytest.raises(environs.EnvError, match='Environment variable "NOT_SET" not set'):
assert env("NOT_SET")

def test_call_with_default(self, env):
assert env("NOT_SET", default="mydefault") == "mydefault"
Expand Down Expand Up @@ -761,6 +763,19 @@ def test_recursive_expands(self, env, set_env):
)
assert env.str("PGURL") == "postgres://gnarvaja:secret@localhost"

def test_default_expands(self, env, set_env):
set_env(
{
"MAIN": "${SUBSTI}",
"SUBSTI": "substivalue",
}
)
assert env.str("NOT_SET", "${SUBSTI}") == "substivalue"
assert env.str("NOT_SET", "${MAIN}") == "substivalue"
assert env.str("NOT_SET", "${NOT_SET2:-set2}") == "set2"
with pytest.raises(environs.EnvError, match='Environment variable "NOT_SET2" not set'):
assert env.str("NOT_SET", "${NOT_SET2}")

def test_escaped_expand(self, env, set_env):
set_env({"ESCAPED_EXPAND": r"\${ESCAPED}", "ESCAPED": "fail"})
assert env.str("ESCAPED_EXPAND") == r"${ESCAPED}"
Expand Down

0 comments on commit dad57b7

Please sign in to comment.