[Checkins] SVN: zc.zk/trunk/src/zc/zk/ - Rearranged code internally to make certain experiments with the tree

Jim Fulton jim at zope.com
Tue Dec 27 17:48:07 UTC 2011


Log message for revision 123863:
  - Rearranged code internally to make certain experiments with the tree
    representation easier:
  
  - The link-resolution code is ow separated into a separate base
      class so it can be used with parse trees.
  
  - ``parse_tree`` now accepts an optional node class.
  

Changed:
  U   zc.zk/trunk/src/zc/zk/README.txt
  U   zc.zk/trunk/src/zc/zk/__init__.py

-=-
Modified: zc.zk/trunk/src/zc/zk/README.txt
===================================================================
--- zc.zk/trunk/src/zc/zk/README.txt	2011-12-26 23:36:00 UTC (rev 123862)
+++ zc.zk/trunk/src/zc/zk/README.txt	2011-12-27 17:48:04 UTC (rev 123863)
@@ -997,6 +997,14 @@
 
 - Added property links.
 
+- Rearranged code internally to make certain experiments with the tree
+  representation easier:
+
+  - The link-resolution code is ow separated into a separate base
+    class so it can be used with parse trees.
+
+  - ``parse_tree`` now accepts an optional node class.
+
 0.4.0 (2011-12-12)
 ------------------
 

Modified: zc.zk/trunk/src/zc/zk/__init__.py
===================================================================
--- zc.zk/trunk/src/zc/zk/__init__.py	2011-12-26 23:36:00 UTC (rev 123862)
+++ zc.zk/trunk/src/zc/zk/__init__.py	2011-12-27 17:48:04 UTC (rev 123863)
@@ -105,8 +105,47 @@
 class BadPropertyLink(Exception):
     pass
 
-class ZooKeeper:
+class Resolving:
 
+    def resolve(self, path, seen=()):
+        if path.endswith('/.'):
+            return self.resolve(path[:-2])
+        if path.endswith('/..'):
+            base = self.resolve(path[:-3])
+            if '/' in base:
+                return base.rsplit('/', 1)[0]
+            else:
+                raise zookeeper.NoNodeException(path)
+
+        if self.exists(path):
+            return path
+
+        if path in seen:
+            seen += (path,)
+            raise LinkLoop(seen)
+
+        try:
+            base, name = path.rsplit('/', 1)
+            base = self.resolve(base, seen)
+            newpath = base + '/' + name
+            if self.exists(newpath):
+                return newpath
+            props = self.get_properties(base)
+            newpath = props.get(name+' ->')
+            if not newpath:
+                raise zookeeper.NoNodeException()
+
+            if not newpath[0] == '/':
+                newpath = base + '/' + newpath
+
+            seen += (path,)
+            return self.resolve(newpath, seen)
+        except zookeeper.NoNodeException:
+            raise zookeeper.NoNodeException(path)
+
+
+class ZooKeeper(Resolving):
+
     def __init__(self, connection_string="127.0.0.1:2181", session_timeout=None,
                  wait=False):
         self.watches = WatchManager()
@@ -431,42 +470,6 @@
     def print_tree(self, path='/'):
         print self.export_tree(path, True),
 
-    def resolve(self, path, seen=()):
-        if path.endswith('/.'):
-            return self.resolve(path[:-2])
-        if path.endswith('/..'):
-            base = self.resolve(path[:-3])
-            if '/' in base:
-                return base.rsplit('/', 1)[0]
-            else:
-                raise zookeeper.NoNodeException(path)
-
-        if self.exists(path):
-            return path
-
-        if path in seen:
-            seen += (path,)
-            raise LinkLoop(seen)
-
-        try:
-            base, name = path.rsplit('/', 1)
-            base = self.resolve(base, seen)
-            newpath = base + '/' + name
-            if self.exists(newpath):
-                return newpath
-            props = self.get_properties(base)
-            newpath = props.get(name+' ->')
-            if not newpath:
-                raise zookeeper.NoNodeException()
-
-            if not newpath[0] == '/':
-                newpath = base + '/' + newpath
-
-            seen += (path,)
-            return self.resolve(newpath, seen)
-        except zookeeper.NoNodeException:
-            raise zookeeper.NoNodeException(path)
-
     def _set(self, path, data):
         return self.set(path, data)
 
@@ -786,8 +789,17 @@
     '$'
     ).match
 
-def parse_tree(text):
-    root = _Tree()
+class ParseNode:
+
+    def __init__(self, name='', properties=None, **children):
+        self.name = name
+        self.properties = properties or {}
+        self.children = children
+        for name, child in children.iteritems():
+            child.name = name
+
+def parse_tree(text, node_class=ParseNode):
+    root = node_class()
     indents = [(-1, root)] # sorted [(indent, node)]
     lineno = 0
     for line in text.split('\n'):
@@ -826,7 +838,7 @@
         if data is None:
             m = _text_is_node(stripped)
             if m:
-                data = _Tree(m.group('name'))
+                data = node_class(m.group('name'))
                 if m.group('type'):
                     data.properties['type'] = m.group('type')
 
@@ -837,7 +849,7 @@
                 raise ValueError(lineno, stripped, "Unrecognized data")
 
         if indent > indents[-1][0]:
-            if not isinstance(indents[-1][1], _Tree):
+            if not isinstance(indents[-1][1], node_class):
                 raise ValueError(
                     lineno, line,
                     "Can't indent under properties")
@@ -849,7 +861,7 @@
             if indent > indents[-1][0]:
                 raise ValueError(lineno, data, "Invalid indentation")
 
-        if isinstance(data, _Tree):
+        if isinstance(data, node_class):
             children = indents[-2][1].children
             if data.name in children:
                 raise ValueError(lineno, data, 'duplicate node')
@@ -866,16 +878,6 @@
 
     return root
 
-class _Tree:
-    # Internal tree rep for import/export
-
-    def __init__(self, name='', properties=None, **children):
-        self.name = name
-        self.properties = properties or {}
-        self.children = children
-        for name, child in children.iteritems():
-            child.name = name
-
 class RegisteringServer:
     """Event emitted while a server is being registered.
 



More information about the checkins mailing list