[PATCH 8 of 9 3.26] [py3] Avoid setting attribute on Element instance in wdoc view

Denis Laxalde denis.laxalde at logilab.fr
Thu Jun 28 12:28:35 CEST 2018


# HG changeset patch
# User Denis Laxalde <denis.laxalde at logilab.fr>
# Date 1530177554 -7200
#      Thu Jun 28 11:19:14 2018 +0200
# Branch 3.26
# Node ID 90ff36da4c8eab66b6d15792ad8489bbfdfa904a
# Parent  ec2ab8dc93a218da89481b32986617a623851528
# Available At https://hg.logilab.org/review/cubicweb
#              hg pull https://hg.logilab.org/review/cubicweb -r 90ff36da4c8e
# EXP-Topic py3
[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.

diff --git a/cubicweb/web/views/wdoc.py b/cubicweb/web/views/wdoc.py
--- a/cubicweb/web/views/wdoc.py
+++ b/cubicweb/web/views/wdoc.py
@@ -39,29 +39,26 @@ from cubicweb import _
 # 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 get_insertion_point(section, index):
 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 @@ def build_toc(config):
                 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 @@ class InlineHelpView(StartupView):
             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 @@ class InlineHelpView(StartupView):
         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)


More information about the cubicweb-devel mailing list