[py3] Avoid setting attribute on Element instance in wdoc view 3.26
authorDenis Laxalde <denis.laxalde@logilab.fr>
Thu, 28 Jun 2018 11:19:14 +0200
branch3.26
changeset 12336 90ff36da4c8e
parent 12335 ec2ab8dc93a2
child 12337 04ff0d3ef1d3
[py3] Avoid setting attribute on Element instance in wdoc view This change is needed to make "wdoc" view work on Python 3. Indeed, before this patch, we used to set a "parent" attribute on Element instances, which is not permitted since Python 3.3 as xml.etree.ElementTree uses the C implementation by default. To get rid of this "parent" attribute, we rework the XML nodes processing logic to return and retrieve a node along with its parent in several place of the code. Namely, build_toc_index() now accepts the "parent" value for "node" and inserts it in the "index" dict (thus avoid `node.parent = <value>`). Respectively, every query to the "index" dict is updated to also retrieve the "parent" (thus avoiding `<value> = node.parent`). Later in InlineHelpView class, the "index" dict is bound to "tocindex" attribute so we adjust how it is queried in respective methods. Tests cubicweb/web/test/unittest_views_wdoc.py now pass on Python 3.
cubicweb/web/views/wdoc.py
--- a/cubicweb/web/views/wdoc.py	Thu Jun 28 10:07:20 2018 +0200
+++ b/cubicweb/web/views/wdoc.py	Thu Jun 28 11:19:14 2018 +0200
@@ -39,29 +39,26 @@
 # table of content management #################################################
 
 
-def build_toc_index(node, index):
+def build_toc_index(node, parent, index):
     try:
         nodeidx = node.attrib['resource']
         assert nodeidx not in index, nodeidx
-        index[nodeidx] = node
+        index[nodeidx] = node, parent
     except KeyError:
         pass
     for child in node:
-        build_toc_index(child, index)
-        child.parent = node
+        build_toc_index(child, node, index)
 
 
 def get_insertion_point(section, index):
     if section.attrib.get('insertafter'):
-        snode = index[section.attrib['insertafter']]
-        node = snode.parent
+        snode, node = index[section.attrib['insertafter']]
         idx = list(node).index(snode) + 1
     elif section.attrib.get('insertbefore'):
-        snode = index[section.attrib['insertbefore']]
-        node = snode.parent
+        snode, node = index[section.attrib['insertbefore']]
         idx = node.getchildren().index(snode)
     elif 'appendto' in section.attrib:
-        node = index[section.attrib['appendto']]
+        node, _ = index[section.attrib['appendto']]
         idx = None
     else:
         node, idx = None, None
@@ -71,9 +68,8 @@
 def build_toc(config):
     alltocfiles = reversed(tuple(config.locate_all_files('toc.xml')))
     maintoc = parse(next(alltocfiles)).getroot()
-    maintoc.parent = None
     index = {}
-    build_toc_index(maintoc, index)
+    build_toc_index(maintoc, None, index)
     # insert component documentation into the tree according to their toc.xml
     # file
     for fpath in alltocfiles:
@@ -86,8 +82,7 @@
                 node.append(section)
             else:
                 node.insert(idx, section)
-            section.parent = node
-            build_toc_index(section, index)
+            build_toc_index(section, node, index)
     return index
 
 
@@ -126,11 +121,11 @@
             raise NotFound
         self.tocindex = build_toc(vreg.config)
         try:
-            node = self.tocindex[fid]
+            node, parent = self.tocindex[fid]
         except KeyError:
-            node = None
+            node, parent = None, None
         else:
-            self.navigation_links(node)
+            self.navigation_links(node, parent)
             self.w(u'<div class="hr"></div>')
             self.w(u'<h1>%s</h1>' % (title_for_lang(node, self._cw.lang)))
         with io.open(join(resourcedir, rid)) as f:
@@ -138,10 +133,9 @@
         if node is not None:
             self.subsections_links(node)
             self.w(u'<div class="hr"></div>')
-            self.navigation_links(node)
+            self.navigation_links(node, parent)
 
-    def navigation_links(self, node):
-        parent = node.parent
+    def navigation_links(self, node, parent):
         if parent is None:
             return
         brothers = subsections(parent)