Skip to content

Commit

Permalink
Fix #482 - formatter case insensitive (#527)
Browse files Browse the repository at this point in the history
* Fix #482 - formatter using both upper and lowercase access

Fix #482

* add more testes covering nested formatting
  • Loading branch information
rochacbruno committed Feb 28, 2021
1 parent 1cbc81a commit 5cdc20f
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 0 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ test_examples:
cd example/issues/430_same_name;pwd;python app.py
cd example/issues/443_object_merge;pwd;python app.py
cd example/issues/445_casting;pwd;python app.py
cd example/issues/482_layered_format;pwd;python app.py
cd example/issues/486_title_case_validation;pwd;python app.py
cd example/issues/494_using_pathlib;pwd;python app.py
cd example/issues/519_underscore_in_name;pwd;ATC_BLE__device_id=42 EXPECTED_VALUE=42 python app.py
Expand Down
22 changes: 22 additions & 0 deletions dynaconf/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,28 @@ def __contains__(self, item):
"""Respond to `item in settings`"""
return item.upper() in self.store or item.lower() in self.store

def __getattr__(self, item):
"""This method is called only when the attribute does not exits
usually on access to the direct `Settings` object instead of the
`LazySettings`.
All first level attributes are stored as UPPERCASE, so self.FOO
will always be accessible, however in some cases `self.foo` might
be acessible. This method routes this access to the underlying `_store`
which handles casing and recursive access.
"""
try:
if (
item.islower()
and self._store.get("LOWERCASE_READ_FOR_DYNACONF", empty)
is False
):
raise KeyError
value = self._store[item]
except KeyError:
raise AttributeError(f"Settings has no attribute '{item}'")
else:
return value

def __getitem__(self, item):
"""Allow getting variables as dict keys `settings['KEY']`"""
value = self.get(item, default=empty)
Expand Down
1 change: 1 addition & 0 deletions dynaconf/utils/parse_conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ def evaluate(settings, *args, **kwargs):


converters = {
"@str": str,
"@int": int,
"@float": float,
"@bool": lambda value: str(value).lower() in true_values,
Expand Down
52 changes: 52 additions & 0 deletions example/issues/482_layered_format/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from dynaconf import Dynaconf

settings_files = ["settings.toml", "other.toml"]

settings = Dynaconf(settings_files=settings_files)

expected_value = "s3a://kewl_bucket"

assert settings.s3_url == expected_value
assert settings.s3_url1 == expected_value
assert settings.s3_url2 == expected_value
assert settings.s3_url3 == expected_value

assert settings["s3_url"] == expected_value
assert settings["S3_URL"] == expected_value

assert settings.get("s3_url", default="s3://default") == expected_value
assert settings.get("S3_URL", default="s3://default") == expected_value

assert settings("s3_url", cast="@str") == expected_value
assert settings("S3_URL", cast="@str") == expected_value

expected = {
"first_name": "Bruno",
"morenested": {
"last_name": "Rocha",
"evenmore": {
"full_name": "Bruno Rocha",
"full_name2": "Bruno Rocha",
"full_name3": "Bruno Rocha",
},
},
}

assert (
settings.nested
== settings.NESTED
== settings["nested"]
== settings["NESTED"]
== settings.get("NesTed")
== settings("nested")
)

assert settings.nested.to_dict() == expected, (settings.nested, expected)

print(settings.s3_url)
print(settings.S3_URL)

print(settings["s3_url"])
print(settings["S3_URL"])

print(settings.nested)
1 change: 1 addition & 0 deletions example/issues/482_layered_format/other.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
s3_bucket = 'kewl_bucket'
16 changes: 16 additions & 0 deletions example/issues/482_layered_format/settings.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
s3_protocol = 's3a'
s3_url = '@format {this[s3_protocol]}://{this[s3_bucket]}'
s3_url1 = '@format {this[S3_PROTOCOL]}://{this[S3_BUCKET]}'
s3_url2 = '@format {this.s3_protocol}://{this.s3_bucket}'
s3_url3 = '@format {this.S3_PROTOCOL}://{this.S3_BUCKET}'

[nested]
first_name = 'Bruno'

[nested.morenested]
last_name = 'Rocha'

[nested.morenested.evenmore]
full_name = '@format {this.nested.first_name} {this.nested.morenested.last_name}'
full_name2 = '@format {this.nested[first_name]} {this.nested.morenested[last_name]}'
full_name3 = '@format {this.NESTED[first_name]} {this.nested.morenested[LAST_NAME]}'

0 comments on commit 5cdc20f

Please sign in to comment.