While this doesn't seem to be documented, it seemed safe to assume that the document attribute on docutils nodes would hold a reference to the document node at the top of the document tree. However, this doesn't seem to be the case for several nodes, e.g. the figure and table nodes. Child nodes of these neither have their document attribute set.
It is possible to reach the document node by recursively following the parent attribute up to the top of the tree. However, it would be better if the document attribute could be depended on.
While it might be sensible to assume the existence of some undocumented features, this is never safe -- especially in parts that are explicitely specified like the Docutils Document Tree. There is no "document" attribute in the doctree specification (docs/ref/doctree.txt, docs/ref/docutils.dtd). OTOH, most node-processing classes (like
WriterandTransformand their descendents) as well asstates.Inlinerstore a reference to the document beeing processed in a "document" attribute.IMO, traveling up to find the top node is not so costly that it merits a permanent link to the top of the tree from every node.
If there is a convincing use case, please reopen as an enhancement request.
Thanks for your quick reply, Günther.
I haven't been able to find explicit documentation on this. The Docutils Document Tree document is labeled as incomplete and it doesn't mention the parent attribute either. So should that attribute also be assumed unsafe, even though it's extensively used in the docutils code itself?
The only documentation I could find on these attributes was in the docutils/nodes.py source file, in the docstrings of the Node class definition. These do not make any distinction between the safeness of the document and parent attributes:
Do you know of any other documentation resource I could reference?
Last edit: Brecht Machiels 2020-12-02
Thank you for the follow up. Now I understand the reason for the mixup.
docutils.nodes.Nodeclass instances are used to represent Doctree elements. Both have attributes but these are completely different categories:Node instances have class attributes.¹ They are documented in docstrings in the Python source. Your report was about the class attribute
docutils.Node.document, right?Doctree elements have element attributes that are described in doctree.html and docutils.dtd² . These element attributes are stored in
Element.attributesand accessed as via class methods likeElement.attlist()or aselement[att].|¹ Instances of the "Node" subclass "Element" have, amongst others, the class attribute "attributes" containing the element attributes.
|² While descriptions in "doctree.html" are incomplete, all elements and attributes at least have a stub entry, "docutils.dtd" should be complete.
With the cited docstring in docutils/nodes.py, the "document" class attribute becomes part of the API.
The "document" class attribute in any
nodes.figureornodes.tableinstance in a Docutils-generated document tree should be set to the document node. If this is not the case, this is a bug.Unfortunately, the "document" class attribute is only auto-set for instances of
nodes.document(). It is passed on for nodes generated with the "correct" helpers likenodes.Node.setup_child()ornodes.Node.copy().This inheritance chain is easily broken.
In order to fix the bug we would need a "minimal working example",
because observations of
<node_instance>.document == Nonedo not depend on the node type but rather on how/where this instance is generated.(It is also worth checking whether the error is with a 3rd-party extension.)
OTOH, the
Node.documentattribute seems not to be used in Docutils and maintaining its proper state adds complexity and is error prone.I wonder whether it may be an improvement to either
@property-decorated method that recurses upself.parentto fetch anodes.documentinstance.Last edit: Günter Milde 2020-12-04
Yes, my report is about the Node class (well, instance) attribute.
Since the parent instance attribute seems to be consistently set on all nodes, perhaps it's a good idea to go for the @property-based solution. This is easy to implement and adds useful functionality.
This issue reminds me fact that the source and line instance attributes that are missing (= None) in many nodes. I remember that that would require a lot of work to fix. Thankfully, that doesn't seem to be the case here.
Fixed in r8589. Please test and close this bug if it solves the issue.
This is an ongoing effort.
Feel free to report concrete cases (with MWE, preferabely to the docutils-devel list).
Yes, this seems to work as intended! Thanks, Günter.
Fixed in [r8589]
Related
Commit: [r8589]
Fixed in Docutils 0.17.
Thanks again for the report.