From af4c68db08e2ca28801ead5ab70fcae1181d832e Mon Sep 17 00:00:00 2001 From: Mehdy Khoshnoody Date: Wed, 6 Oct 2021 17:02:40 +0330 Subject: [PATCH 1/2] Handle escaped dollar sign in values Signed-off-by: Mehdy Khoshnoody --- CHANGELOG.rst | 2 ++ environ/environ.py | 5 +++++ tests/fixtures.py | 1 + tests/test_env.py | 8 ++++++++ tests/test_env.txt | 1 + 5 files changed, 17 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 47d9673f..b41318e2 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -22,6 +22,8 @@ Fixed +++++ - Keep newline/tab escapes in quoted strings `#296 `_. +- Handle escaped dolloar sign in values + `#271 `_. `v0.7.0`_ - 11-September-2021 diff --git a/environ/environ.py b/environ/environ.py index b678096d..b177784e 100644 --- a/environ/environ.py +++ b/environ/environ.py @@ -160,6 +160,7 @@ class Env: def __init__(self, **scheme): self.smart_cast = True + self.escape_proxy = False self.scheme = scheme def __call__(self, var, cast=None, default=NOTSET, parse_default=False): @@ -365,10 +366,14 @@ def get_value(self, var, cast=None, default=NOTSET, parse_default=False): # Resolve any proxied values prefix = b'$' if isinstance(value, bytes) else '$' + escape = rb'\$' if isinstance(value, bytes) else r'\$' if hasattr(value, 'startswith') and value.startswith(prefix): value = value.lstrip(prefix) value = self.get_value(value, cast=cast, default=default) + if self.escape_proxy and hasattr(value, 'replace'): + value = value.replace(escape, prefix) + # Smart casting if self.smart_cast: if cast is None and default is not None and \ diff --git a/tests/fixtures.py b/tests/fixtures.py index 29b4dc9f..782123df 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -53,6 +53,7 @@ def generate_data(cls): BOOL_FALSE_STRING_LIKE_BOOL='False', BOOL_FALSE_BOOL=False, PROXIED_VAR='$STR_VAR', + ESCAPED_VAR=r'\$baz', INT_LIST='42,33', INT_TUPLE='(42,33)', STR_LIST_WITH_SPACES=' foo, bar', diff --git a/tests/test_env.py b/tests/test_env.py index acd8dc40..e66cf99d 100644 --- a/tests/test_env.py +++ b/tests/test_env.py @@ -126,6 +126,14 @@ def test_bool_true(self, value, variable): def test_proxied_value(self): assert self.env('PROXIED_VAR') == 'bar' + def test_escaped_dollar_sign(self): + self.env.escape_proxy = True + assert self.env('ESCAPED_VAR') == '$baz' + + def test_escaped_dollar_sign_disabled(self): + self.env.escape_proxy = False + assert self.env('ESCAPED_VAR') == r'\$baz' + def test_int_list(self): assert_type_and_value(list, [42, 33], self.env('INT_LIST', cast=[int])) assert_type_and_value(list, [42, 33], self.env.list('INT_LIST', int)) diff --git a/tests/test_env.txt b/tests/test_env.txt index befeed76..fa593d27 100644 --- a/tests/test_env.txt +++ b/tests/test_env.txt @@ -28,6 +28,7 @@ FLOAT_STRANGE_VAR1=123,420,333.3 FLOAT_STRANGE_VAR2=123.420.333,3 FLOAT_NEGATIVE_VAR=-1.0 PROXIED_VAR=$STR_VAR +ESCAPED_VAR=\$baz EMPTY_LIST= INT_VAR=42 STR_LIST_WITH_SPACES= foo, bar From 1b6c4ba7e1fc1548a5b9692c923a6523a11ef4af Mon Sep 17 00:00:00 2001 From: Mehdy Khoshnoody Date: Thu, 7 Oct 2021 17:12:49 +0330 Subject: [PATCH 2/2] Add docs for escape proxy feature Signed-off-by: Mehdy Khoshnoody --- docs/tips.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/tips.rst b/docs/tips.rst index cff0d862..dbb762fb 100644 --- a/docs/tips.rst +++ b/docs/tips.rst @@ -195,6 +195,23 @@ Values that being with a ``$`` may be interpolated. Pass ``interpolate=True`` to FOO +Escape Proxy +============ + +If you're having trouble with values starting with dollar sign ($) without the intention of proxying the value to +another, You should enbale the ``escape_proxy`` and prepend a backslash to it. + +.. code-block:: python + + import environ + + env = environ.Env() + env.escape_proxy = True + + # ESCAPED_VAR=\$baz + env.str('ESCAPED_VAR') # $baz + + Reading env files =================