[Supervisor-checkins] r902 - in supervisor/trunk: . src/supervisor src/supervisor/tests
Mike Naberezny
mike at maintainable.com
Sat Oct 24 20:06:11 EDT 2009
Author: Mike Naberezny <mike at maintainable.com>
Date: Sat Oct 24 20:06:10 2009
New Revision: 902
Log:
- Fixed a bug introduced in 3.0a7 where parsing a string of key/value
pairs failed on Python 2.3 due to use of regular expression syntax
introduced in Python 2.4.
Modified:
supervisor/trunk/CHANGES.txt
supervisor/trunk/src/supervisor/datatypes.py
supervisor/trunk/src/supervisor/tests/test_datatypes.py
Modified: supervisor/trunk/CHANGES.txt
==============================================================================
--- supervisor/trunk/CHANGES.txt (original)
+++ supervisor/trunk/CHANGES.txt Sat Oct 24 20:06:10 2009
@@ -9,6 +9,10 @@
- Fixed a bug introduced in 3.0a7 where setup.py would not detect the
Python version correctly. Patch by Daniele Paolella.
+ - Fixed a bug introduced in 3.0a7 where parsing a string of key/value
+ pairs failed on Python 2.3 due to use of regular expression syntax
+ introduced in Python 2.4.
+
- Removed the test suite for the ``memmon`` console script, which was
moved to the Superlance package in 3.0a7.
Modified: supervisor/trunk/src/supervisor/datatypes.py
==============================================================================
--- supervisor/trunk/src/supervisor/datatypes.py (original)
+++ supervisor/trunk/src/supervisor/datatypes.py Sat Oct 24 20:06:10 2009
@@ -16,6 +16,7 @@
import re
import sys
import socket
+import shlex
from supervisor.loggers import getLevelNumByDescription
# I dont know why we bother, this doesn't run on Windows, but just
@@ -79,30 +80,21 @@
except:
raise ValueError("not a valid list of exit codes: " + repr(arg))
-# Regular expression to match key=value, key='value' or key="value" strings
-# Quoted values can allow commas, unquoted will not
-DICT_OF_KVP_REGEXP = re.compile(r"[ \t]*(?P<key>\w+)[ \t]*=[ \t]"
- r"*(?P<quote>['\"])?"
- r"(?P<value>.*?)(?(quote)['\"])[,$]")
-
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
"""
- D = {}
-
- if len(arg):
- # Work-around non-greedy value match won't let the regexp parse
- # the last key=value pair if value is not quoted
- if arg[-1] != ',':
- arg += ','
-
- for key, quote, value in DICT_OF_KVP_REGEXP.findall(arg):
- D[key] = value.strip()
-
- if D == {}:
- raise ValueError("not a list of key/value pairs: " + repr(arg))
+ tokens = list(shlex.shlex(arg))
+ tokens_len = len(tokens)
+ D = {}
+ i = 0
+ while i in range(0, tokens_len):
+ k_eq_v = tokens[i:i+3]
+ if len(k_eq_v) != 3:
+ raise ValueError, "Unexpected end of key/value pairs"
+ D[k_eq_v[0]] = k_eq_v[2].strip('\'"')
+ i += 4
return D
class Automatic:
Modified: supervisor/trunk/src/supervisor/tests/test_datatypes.py
==============================================================================
--- supervisor/trunk/src/supervisor/tests/test_datatypes.py (original)
+++ supervisor/trunk/src/supervisor/tests/test_datatypes.py Sat Oct 24 20:06:10 2009
@@ -100,6 +100,11 @@
expected = {'foo': 'bar', 'baz': 'qux'}
self.assertEqual(actual, expected)
+ def test_dict_of_key_value_pairs_returns_dict_even_if_newlines(self):
+ actual = datatypes.dict_of_key_value_pairs('foo\n=\nbar\n,\nbaz\n=\nqux')
+ expected = {'foo': 'bar', 'baz': 'qux'}
+ self.assertEqual(actual, expected)
+
def test_dict_of_key_value_pairs_handles_commas_inside_apostrophes(self):
actual = datatypes.dict_of_key_value_pairs("foo='bar,baz',baz='q,ux'")
expected = {'foo': 'bar,baz', 'baz': 'q,ux'}
@@ -110,9 +115,20 @@
expected = {'foo': 'bar,baz', 'baz': 'q,ux'}
self.assertEqual(actual, expected)
- def test_dict_of_key_value_pairs_raises_value_error_on_weird_input(self):
+ def test_dict_of_key_value_pairs_allows_trailing_comma(self):
+ actual = datatypes.dict_of_key_value_pairs('foo=bar,')
+ expected = {'foo': 'bar'}
+ self.assertEqual(actual, expected)
+
+ def test_dict_of_key_value_pairs_raises_value_error_on_too_short(self):
self.assertRaises(ValueError,
datatypes.dict_of_key_value_pairs, 'foo')
+ self.assertRaises(ValueError,
+ datatypes.dict_of_key_value_pairs, 'foo=')
+ self.assertRaises(ValueError,
+ datatypes.dict_of_key_value_pairs, 'foo=bar,baz')
+ self.assertRaises(ValueError,
+ datatypes.dict_of_key_value_pairs, 'foo=bar,baz=')
def test_logfile_name_returns_none_for_none_values(self):
for thing in datatypes.LOGFILE_NONES:
More information about the Supervisor-checkins
mailing list