From 04e4bada19af99499a4efd42f662cbee0c5b5eeb Mon Sep 17 00:00:00 2001 From: David Monks Date: Mon, 4 Apr 2022 12:22:05 +0100 Subject: [PATCH] Allow env file to override environment Prior to this change, the environment always took precedence when there was a value specified in both the env file and the environment. This was not suitable to all use-cases (such as those in Kubernetes, where environment variables are commonly much less controlled and, so, much more vulnerable to malicious value injection). This change allows the developer to choose which takes precedence, the environment or the env file (with the current behaviour remaining the default). --- envparse.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/envparse.py b/envparse.py index e13b584..9aa3822 100644 --- a/envparse.py +++ b/envparse.py @@ -164,13 +164,16 @@ def cast(cls, value, cast=str, subcast=None): url = shortcut(urlparse.urlparse) @staticmethod - def read_envfile(path=None, **overrides): + def read_envfile(path=None, override=False, **overrides): """ Read a .env file (line delimited KEY=VALUE) into os.environ. If not given a path to the file, recurses up the directory tree until found. + If `override=True`, override the values in the environment. Defaults to + `False`, prioritising values in the environment over those in the file. + Uses code from Honcho (github.com/nickstenning/honcho) for parsing the file. """ @@ -208,10 +211,16 @@ def read_envfile(path=None, **overrides): if not re.match(r'[A-Za-z_][A-Za-z_0-9]*', name): continue value = value.replace(r'\n', '\n').replace(r'\t', '\t') - os.environ.setdefault(name, value) + if override: + os.environ[name] = value + else: + os.environ.setdefault(name, value) for name, value in overrides.items(): - os.environ.setdefault(name, value) + if override: + os.environ[name] = value + else: + os.environ.setdefault(name, value) # Convenience object if no schema is required. env = Env()