joke2k / django-environ

Django-environ allows you to utilize 12factor inspired environment variables to configure your Django application.
https://django-environ.rtfd.org
MIT License
3.01k stars 318 forks source link

Does the option to disable interpolation even work? #525

Open amatmv opened 3 months ago

amatmv commented 3 months ago

I want to turn off the interpolation feature because I don't use it, but instead, take the raw value of the variable. The solution to disable interpolation in the docs doesn't seem to work.

Here are two examples of getting the raw value of a variable FOO that starts with $, using the latest version 0.11.2

Defining the variable in the .env

``` # .env file FOO="$BAR" ``` ```py # python In [1]: import environ In [2]: env = environ.Env(interpolate=False) In [3]: env('FOO') --------------------------------------------------------------------------- KeyError Traceback (most recent call last) File /usr/local/lib/python3.9/site-packages/environ/environ.py:388, in Env.get_value(self, var, cast, default, parse_default) 387 try: --> 388 value = self.ENVIRON[var_name] 389 except KeyError as exc: File /usr/local/lib/python3.9/os.py:679, in _Environ.__getitem__(self, key) 677 except KeyError: 678 # raise KeyError with the original key value --> 679 raise KeyError(key) from None 680 return self.decodevalue(value) KeyError: 'BAR' The above exception was the direct cause of the following exception: ImproperlyConfigured Traceback (most recent call last) Cell In[2], line 3 1 import environ 2 env = environ.Env(interpolate=False) ----> 3 env('FOO') File /usr/local/lib/python3.9/site-packages/environ/environ.py:199, in Env.__call__(self, var, cast, default, parse_default) 198 def __call__(self, var, cast=None, default=NOTSET, parse_default=False): --> 199 return self.get_value( 200 var, 201 cast=cast, 202 default=default, 203 parse_default=parse_default 204 ) File /usr/local/lib/python3.9/site-packages/environ/environ.py:401, in Env.get_value(self, var, cast, default, parse_default) 399 if hasattr(value, 'startswith') and value.startswith(prefix): 400 value = value.lstrip(prefix) --> 401 value = self.get_value(value, cast=cast, default=default) 403 if self.escape_proxy and hasattr(value, 'replace'): 404 value = value.replace(escape, prefix) File /usr/local/lib/python3.9/site-packages/environ/environ.py:392, in Env.get_value(self, var, cast, default, parse_default) 390 if default is self.NOTSET: 391 error_msg = f'Set the {var} environment variable' --> 392 raise ImproperlyConfigured(error_msg) from exc 394 value = default 396 # Resolve any proxied values ImproperlyConfigured: Set the BAR environment variable ```

Same use case but populating from default values

```pytb In [1]: import environ In [2]: env = environ.Env(interpolate=False, FOO=('str', '$BAR')) In [3]: env('FOO') --------------------------------------------------------------------------- RecursionError Traceback (most recent call last) Cell In[17], line 1 ----> 1 env('FOO') File /usr/local/lib/python3.9/site-packages/environ/environ.py:199, in Env.__call__(self, var, cast, default, parse_default) 198 def __call__(self, var, cast=None, default=NOTSET, parse_default=False): --> 199 return self.get_value( 200 var, 201 cast=cast, 202 default=default, 203 parse_default=parse_default 204 ) File /usr/local/lib/python3.9/site-packages/environ/environ.py:401, in Env.get_value(self, var, cast, default, parse_default) 399 if hasattr(value, 'startswith') and value.startswith(prefix): 400 value = value.lstrip(prefix) --> 401 value = self.get_value(value, cast=cast, default=default) 403 if self.escape_proxy and hasattr(value, 'replace'): 404 value = value.replace(escape, prefix) File /usr/local/lib/python3.9/site-packages/environ/environ.py:401, in Env.get_value(self, var, cast, default, parse_default) 399 if hasattr(value, 'startswith') and value.startswith(prefix): 400 value = value.lstrip(prefix) --> 401 value = self.get_value(value, cast=cast, default=default) 403 if self.escape_proxy and hasattr(value, 'replace'): 404 value = value.replace(escape, prefix) [... skipping similar frames: Env.get_value at line 401 (2977 times)] File /usr/local/lib/python3.9/site-packages/environ/environ.py:401, in Env.get_value(self, var, cast, default, parse_default) 399 if hasattr(value, 'startswith') and value.startswith(prefix): 400 value = value.lstrip(prefix) --> 401 value = self.get_value(value, cast=cast, default=default) 403 if self.escape_proxy and hasattr(value, 'replace'): 404 value = value.replace(escape, prefix) File /usr/local/lib/python3.9/site-packages/environ/environ.py:388, in Env.get_value(self, var, cast, default, parse_default) 385 cast = var_info 387 try: --> 388 value = self.ENVIRON[var_name] 389 except KeyError as exc: 390 if default is self.NOTSET: File /usr/local/lib/python3.9/os.py:676, in _Environ.__getitem__(self, key) 674 def __getitem__(self, key): 675 try: --> 676 value = self._data[self.encodekey(key)] 677 except KeyError: 678 # raise KeyError with the original key value 679 raise KeyError(key) from None File /usr/local/lib/python3.9/os.py:755, in _createenviron..encode(value) 754 def encode(value): --> 755 if not isinstance(value, str): 756 raise TypeError("str expected, not %s" % type(value).__name__) 757 return value.encode(encoding, 'surrogateescape') RecursionError: maximum recursion depth exceeded while calling a Python object ```