1
from __future__ import absolute_import, division, unicode_literals
4
from collections import OrderedDict
7
from ordereddict import OrderedDict
13
from pip._vendor.six import string_types
16
from .._utils import moduleFactoryFactory
18
tag_regexp = re.compile("{([^}]*)}(.*)")
21
def getETreeBuilder(ElementTreeImplementation):
22
ElementTree = ElementTreeImplementation
23
ElementTreeCommentType = ElementTree.Comment("asd").tag
25
class TreeWalker(base.NonRecursiveTreeWalker): # pylint:disable=unused-variable
26
"""Given the particular ElementTree representation, this implementation,
27
to avoid using recursion, returns "nodes" as tuples with the following
30
1. The current element
32
2. The index of the element relative to its parent
34
3. A stack of ancestor elements
36
4. A flag "text", "tail" or None to indicate if the current node is a
37
text node; either the text or tail of the current element (1)
39
def getNodeDetails(self, node):
40
if isinstance(node, tuple): # It might be the root Element
41
elt, _, _, flag = node
42
if flag in ("text", "tail"):
43
return base.TEXT, getattr(elt, flag)
47
if not(hasattr(node, "tag")):
50
if node.tag in ("DOCUMENT_ROOT", "DOCUMENT_FRAGMENT"):
51
return (base.DOCUMENT,)
53
elif node.tag == "<!DOCTYPE>":
54
return (base.DOCTYPE, node.text,
55
node.get("publicId"), node.get("systemId"))
57
elif node.tag == ElementTreeCommentType:
58
return base.COMMENT, node.text
61
assert isinstance(node.tag, string_types), type(node.tag)
62
# This is assumed to be an ordinary element
63
match = tag_regexp.match(node.tag)
65
namespace, tag = match.groups()
70
for name, value in list(node.attrib.items()):
71
match = tag_regexp.match(name)
73
attrs[(match.group(1), match.group(2))] = value
75
attrs[(None, name)] = value
76
return (base.ELEMENT, namespace, tag,
77
attrs, len(node) or node.text)
79
def getFirstChild(self, node):
80
if isinstance(node, tuple):
81
element, key, parents, flag = node
83
element, key, parents, flag = node, None, [], None
85
if flag in ("text", "tail"):
89
return element, key, parents, "text"
91
parents.append(element)
92
return element[0], 0, parents, None
96
def getNextSibling(self, node):
97
if isinstance(node, tuple):
98
element, key, parents, flag = node
104
parents.append(element)
105
return element[0], 0, parents, None
109
if element.tail and flag != "tail":
110
return element, key, parents, "tail"
111
elif key < len(parents[-1]) - 1:
112
return parents[-1][key + 1], key + 1, parents, None
116
def getParentNode(self, node):
117
if isinstance(node, tuple):
118
element, key, parents, flag = node
126
return element, key, parents, None
128
parent = parents.pop()
132
assert list(parents[-1]).count(parent) == 1
133
return parent, list(parents[-1]).index(parent), parents, None
137
getETreeModule = moduleFactoryFactory(getETreeBuilder)