Skip to content

Commit

Permalink
Redo "Parse env configuration in posix mode"
Browse files Browse the repository at this point in the history
Fixes Supervisor#328

This allows (escaped) quotes in the values as well as empty
values.

This was done in pull request Supervisor#329 but removed as it
broke parsing empty quotes (Supervisor#873) due to a bug in shlex
(http://bugs.python.org/issue21999). This bug is fixed
so posix mode can be used.

Brings back Supervisor#329
Partially reverts Supervisor#880
  • Loading branch information
sfriesel authored and vereszol committed Dec 8, 2023
1 parent ff5356f commit 1d91ccf
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 2 deletions.
3 changes: 3 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
the ``[supervisorctl]`` section or ``[ctlplugin:x]`` sections to be in
included files. Patch by François Granade.

- Parsing ``environment=`` has been improved to allow escaped quotes
inside quotes and quoted empty values. Patch by Stefan Friesel.

4.2.5 (2022-12-23)
------------------

Expand Down
4 changes: 2 additions & 2 deletions supervisor/datatypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def dict_of_key_value_pairs(arg):
""" parse KEY=val,KEY2=val2 into {'KEY':'val', 'KEY2':'val2'}
Quotes can be used to allow commas in the value
"""
lexer = shlex.shlex(str(arg))
lexer = shlex.shlex(str(arg), posix=True)
lexer.wordchars += '/.+-():'

tokens = list(lexer)
Expand All @@ -81,7 +81,7 @@ def dict_of_key_value_pairs(arg):
if len(k_eq_v) != 3 or k_eq_v[1] != '=':
raise ValueError(
"Unexpected end of key/value pairs in value '%s'" % arg)
D[k_eq_v[0]] = k_eq_v[2].strip('\'"')
D[k_eq_v[0]] = k_eq_v[2]
i += 4
return D

Expand Down
5 changes: 5 additions & 0 deletions supervisor/tests/test_datatypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,11 @@ def test_handles_newlines_inside_quotes(self):
expected = {'foo': 'a\nb\nc'}
self.assertEqual(actual, expected)

def test_handles_quotes_inside_quotes(self):
actual = datatypes.dict_of_key_value_pairs('foo="\'\\""')
expected = {'foo': '\'"'}
self.assertEqual(actual, expected)

def test_handles_empty_inside_quotes(self):
actual = datatypes.dict_of_key_value_pairs('foo=""')
expected = {'foo': ''}
Expand Down

0 comments on commit 1d91ccf

Please sign in to comment.