From dfe71cae0f34f503deff1b57fa4193a0c5c84ede Mon Sep 17 00:00:00 2001 From: Antti Hautaniemi Date: Fri, 17 Jan 2025 09:00:19 +0200 Subject: [PATCH] Make config and repositories iterable --- decouple.py | 27 +++++++++++++++++++++++++-- tests/test_env.py | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/decouple.py b/decouple.py index 9873fc9..384eb88 100644 --- a/decouple.py +++ b/decouple.py @@ -106,6 +106,9 @@ def __call__(self, *args, **kwargs): """ return self.get(*args, **kwargs) + def __iter__(self): + return iter(self.repository) + class RepositoryEmpty(object): def __init__(self, source='', encoding=DEFAULT_ENCODING): @@ -117,6 +120,9 @@ def __contains__(self, key): def __getitem__(self, key): return None + def __iter__(self): + return iter(()) + class RepositoryIni(RepositoryEmpty): """ @@ -139,6 +145,9 @@ def __getitem__(self, key): except NoOptionError: raise KeyError(key) + def __iter__(self): + return iter(self.parser[self.SECTION]) + class RepositoryEnv(RepositoryEmpty): """ @@ -165,6 +174,9 @@ def __contains__(self, key): def __getitem__(self, key): return self.data[key] + def __iter__(self): + return iter(self.data) + class RepositorySecret(RepositoryEmpty): """ @@ -187,6 +199,9 @@ def __contains__(self, key): def __getitem__(self, key): return self.data[key] + def __iter__(self): + return iter(self.data) + class AutoConfig(object): """ @@ -225,7 +240,9 @@ def _find_file(self, path): # reached root without finding any files. return '' - def _load(self, path): + def _load(self, path=None): + path = path or self.search_path or self._caller_path() + # Avoid unintended permission errors try: filename = self._find_file(os.path.abspath(path)) @@ -241,9 +258,15 @@ def _caller_path(self): path = os.path.dirname(frame.f_back.f_back.f_code.co_filename) return path + def __iter__(self): + if not self.config: + self._load() + + return iter(self.config) + def __call__(self, *args, **kwargs): if not self.config: - self._load(self.search_path or self._caller_path()) + self._load() return self.config(*args, **kwargs) diff --git a/tests/test_env.py b/tests/test_env.py index a91c95c..845fd17 100644 --- a/tests/test_env.py +++ b/tests/test_env.py @@ -140,3 +140,37 @@ def test_env_with_quote(config): def test_env_repo_keyerror(config): with pytest.raises(KeyError): config.repository['UndefinedKey'] + +def test_env_iter(config): + assert [ + 'KeyTrue', + 'KeyOne', + 'KeyYes', + 'KeyOn', + 'KeyY', + 'KeyFalse', + 'KeyZero', + 'KeyNo', + 'KeyN', + 'KeyOff', + 'KeyEmpty', + 'PercentNotEscaped', + 'NoInterpolation', + 'IgnoreSpace', + 'RespectSingleQuoteSpace', + 'RespectDoubleQuoteSpace', + 'KeyOverrideByEnv', + + 'KeyWithSingleQuoteEnd', + 'KeyWithSingleQuoteMid', + 'KeyWithSingleQuoteBegin', + 'KeyWithDoubleQuoteEnd', + 'KeyWithDoubleQuoteMid', + 'KeyWithDoubleQuoteBegin', + 'KeyIsSingleQuote', + 'KeyIsDoubleQuote', + 'KeyHasTwoSingleQuote', + 'KeyHasTwoDoubleQuote', + 'KeyHasMixedQuotesAsData1', + 'KeyHasMixedQuotesAsData2', + ] == list(config)