From 6092931e9de63396f7f135df7b48be64354df9d4 Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Fri, 4 Dec 2009 14:19:32 +0100 Subject: [PATCH] test case for dotted attribute names, some cleanup --- Cython/Compiler/Tests/TestTreePath.py | 5 +++++ Cython/Compiler/TreePath.py | 20 +++++++++++++------- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/Cython/Compiler/Tests/TestTreePath.py b/Cython/Compiler/Tests/TestTreePath.py index fb70bdc3..9b8ca38b 100644 --- a/Cython/Compiler/Tests/TestTreePath.py +++ b/Cython/Compiler/Tests/TestTreePath.py @@ -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"))) diff --git a/Cython/Compiler/TreePath.py b/Cython/Compiler/TreePath.py index fcecf8f6..7d6055e3 100644 --- a/Cython/Compiler/TreePath.py +++ b/Cython/Compiler/TreePath.py @@ -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: -- 2.26.2