test case for dotted attribute names, some cleanup
authorStefan Behnel <scoder@users.berlios.de>
Fri, 4 Dec 2009 13:19:32 +0000 (14:19 +0100)
committerStefan Behnel <scoder@users.berlios.de>
Fri, 4 Dec 2009 13:19:32 +0000 (14:19 +0100)
Cython/Compiler/Tests/TestTreePath.py
Cython/Compiler/TreePath.py

index fb70bdc32eab8ea78cc12262f62e686fd9f20ca2..9b8ca38bce4a51dbf9c052e6537391397cfd0ed7 100644 (file)
@@ -36,6 +36,11 @@ class TestTreePath(TransformTest):
         self.assertEquals(2, len(find_all(t, "//NameNode/@name")))
         self.assertEquals(['fun', 'decorator'], find_all(t, "//NameNode/@name"))
 
+    def test_node_path_attribute_dotted(self):
+        t = self._build_tree()
+        self.assertEquals(1, len(find_all(t, "//ReturnStatNode/@value.name")))
+        self.assertEquals(['fun'], find_all(t, "//ReturnStatNode/@value.name"))
+
     def test_node_path_child(self):
         t = self._build_tree()
         self.assertEquals(1, len(find_all(t, "//DefNode/ReturnStatNode/NameNode")))
index fcecf8f6adbb5130444935c00e96d3ad5ad9d037..7d6055e3deb51803bf5ac8e6172b480fa35dd1f4 100644 (file)
@@ -7,6 +7,7 @@ specific descendant or a node that holds an attribute.
 """
 
 import re
+import sys
 
 path_tokenizer = re.compile(
     "("
@@ -144,14 +145,21 @@ def handle_attribute(next, token):
     else:
         if token[0] == '=':
             value = parse_path_value(next)
-    name_path = name.split('.')
+    if sys.version_info >= (2,6) or (sys.version_info >= (2,4) and '.' not in name):
+        import operator
+        readattr = operator.attrgetter(name)
+    else:
+        name_path = name.split('.')
+        def readattr(node):
+            attr_value = node
+            for attr in name_path:
+                attr_value = getattr(attr_value, attr)
+            return attr_value
     if value is None:
         def select(result):
             for node in result:
                 try:
-                    attr_value = node
-                    for attr in name_path:
-                        attr_value = getattr(attr_value, attr)
+                    attr_value = readattr(node)
                 except AttributeError:
                     continue
                 if attr_value is not None:
@@ -160,9 +168,7 @@ def handle_attribute(next, token):
         def select(result):
             for node in result:
                 try:
-                    attr_value = node
-                    for attr in name_path:
-                        attr_value = getattr(attr_value, attr)
+                    attr_value = readattr(node)
                 except AttributeError:
                     continue
                 if attr_value == value: