Skip to content

Commit

Permalink
Make inline comments handling optional and disabled by default
Browse files Browse the repository at this point in the history
  • Loading branch information
sergeyklay committed Sep 8, 2023
1 parent 7b5d7f9 commit 2589221
Showing 1 changed file with 25 additions and 7 deletions.
32 changes: 25 additions & 7 deletions environ/environ.py
Original file line number Diff line number Diff line change
Expand Up @@ -862,8 +862,8 @@ def search_url_config(cls, url, engine=None):
return config

@classmethod
def read_env(cls, env_file=None, overwrite=False, encoding='utf8',
**overrides):
def read_env(cls, env_file=None, overwrite=False, parse_comments=False,
encoding='utf8', **overrides):
r"""Read a .env file into os.environ.
If not given a path to a dotenv path, does filthy magic stack
Expand All @@ -883,6 +883,8 @@ def read_env(cls, env_file=None, overwrite=False, encoding='utf8',
the Django settings module from the Django project root.
:param overwrite: ``overwrite=True`` will force an overwrite of
existing environment variables.
:param parse_comments: Determines whether to recognize and ignore inline
comments in the .env file. Default is False.
:param encoding: The encoding to use when reading the environment file.
:param \**overrides: Any additional keyword arguments provided directly
to read_env will be added to the environment. If the key matches an
Expand Down Expand Up @@ -927,13 +929,29 @@ def _keep_escaped_format_characters(match):
for line in content.splitlines():
m1 = re.match(r'\A(?:export )?([A-Za-z_0-9]+)=(.*)\Z', line)
if m1:

# Example:
#
# line: KEY_499=abc#def
# key: KEY_499
# val: abc#def
key, val = m1.group(1), m1.group(2)
# Look for value in quotes, ignore post-# comments
# (outside quotes)
m2 = re.match(r"\A\s*'(?<!\\)(.*)'\s*(#.*\s*)?\Z", val)
if m2:
val = m2.group(1)

# Look for value in quotes
if parse_comments:
# A.
# Ignore post-# comments (outside quotes):
# The "KEY='val' # comment" line becomes
# "KEY='val'"
m2 = re.match(r"\A\s*'(?<!\\)(.*)'\s*(#.*\s*)?\Z", val)
else:
# B.
# Default behavior: Look for value in quotes
m2 = re.match(r"\A'(.*)'\Z", val)

if m2: # Suitable for A and B
val = m2.group(1)
elif parse_comments: # Only A
# For no quotes, find value, ignore comments
# after the first #
m2a = re.match(r"\A(.*?)(#.*\s*)?\Z", val)
Expand Down

0 comments on commit 2589221

Please sign in to comment.