commit 06498d8b61ad5f01c04c7011c70892a9846d4c27 Author: Damian Johnson atagar@torproject.org Date: Tue Jan 31 07:46:53 2012 -0800
Adding ControlLine peek_key method
Method to allow us to switch on the key/value mapping while parsing a line. This isn't needed yet (the only parsing done at this point is PROTOCOLINFO responses and that only uses positional entries). However, it's crossed my mind a few times that this will be needed later. --- stem/socket.py | 18 ++++++++++++++++++ test/unit/socket/control_line.py | 7 +++++++ 2 files changed, 25 insertions(+), 0 deletions(-)
diff --git a/stem/socket.py b/stem/socket.py index 889713d..1b481ce 100644 --- a/stem/socket.py +++ b/stem/socket.py @@ -28,6 +28,7 @@ ControlLine - String subclass with methods for parsing controller responses. |- is_empty - checks if the remaining content is empty |- is_next_quoted - checks if the next entry is a quoted value |- is_next_mapping - checks if the next entry is a KEY=VALUE mapping + |- peek_key - provides the key of the next entry |- pop - removes and returns the next entry +- pop_mapping - removes and returns the next entry as a KEY=VALUE mapping
@@ -487,6 +488,23 @@ class ControlLine(str): else: return False # doesn't start with a key
+ def peek_key(self): + """ + Provides the key of the next entry, providing None if it isn't a key/value + mapping. + + Returns: + str with the next entry's key + """ + + remainder = self._remainder + key_match = KEY_ARG.match(remainder) + + if key_match: + return key_match.groups()[0] + else: + return None + def pop(self, quoted = False, escaped = False): """ Parses the next space separated entry, removing it and the space from our diff --git a/test/unit/socket/control_line.py b/test/unit/socket/control_line.py index 6e59f43..7752147 100644 --- a/test/unit/socket/control_line.py +++ b/test/unit/socket/control_line.py @@ -52,6 +52,7 @@ class TestControlLine(unittest.TestCase): self.assertFalse(line.is_empty()) self.assertFalse(line.is_next_quoted()) self.assertFalse(line.is_next_mapping()) + self.assertEquals(None, line.peek_key())
self.assertRaises(ValueError, line.pop_mapping) self.assertEquals(line.pop(), 'PROTOCOLINFO') @@ -59,6 +60,7 @@ class TestControlLine(unittest.TestCase): self.assertFalse(line.is_empty()) self.assertFalse(line.is_next_quoted()) self.assertFalse(line.is_next_mapping()) + self.assertEquals(None, line.peek_key())
self.assertRaises(ValueError, line.pop_mapping) self.assertEquals(line.pop(), '1') @@ -66,6 +68,7 @@ class TestControlLine(unittest.TestCase): self.assertTrue(line.is_empty()) self.assertFalse(line.is_next_quoted()) self.assertFalse(line.is_next_mapping()) + self.assertEquals(None, line.peek_key())
self.assertRaises(IndexError, line.pop_mapping) self.assertRaises(IndexError, line.pop) @@ -73,6 +76,7 @@ class TestControlLine(unittest.TestCase): self.assertTrue(line.is_empty()) self.assertFalse(line.is_next_quoted()) self.assertFalse(line.is_next_mapping()) + self.assertEquals(None, line.peek_key())
def test_pop_mapping(self): """ @@ -90,6 +94,7 @@ class TestControlLine(unittest.TestCase): self.assertTrue(line.is_next_mapping(key = "Tor")) self.assertTrue(line.is_next_mapping(key = "Tor", quoted = True)) self.assertTrue(line.is_next_mapping(quoted = True)) + self.assertEquals("Tor", line.peek_key())
# try popping this as a non-quoted mapping self.assertEquals(line.pop_mapping(), ('Tor', '"0.2.1.30')) @@ -98,6 +103,7 @@ class TestControlLine(unittest.TestCase): self.assertFalse(line.is_next_quoted()) self.assertFalse(line.is_next_mapping()) self.assertRaises(ValueError, line.pop_mapping) + self.assertEquals(None, line.peek_key())
# try popping this as a quoted mapping line = stem.socket.ControlLine(version_entry) @@ -106,6 +112,7 @@ class TestControlLine(unittest.TestCase): self.assertTrue(line.is_empty()) self.assertFalse(line.is_next_quoted()) self.assertFalse(line.is_next_mapping()) + self.assertEquals(None, line.peek_key())
def test_escapes(self): """
tor-commits@lists.torproject.org