Sunday, April 29, 2018

Yesterday and today I explored and fixed a seemingly trivial failure of job 690 in the book project on Travis. It took me a whole weekend and a series of changes in Atelier, including one backwards-incompatible change to the tasks.py file of every project, but I fixed it!

Original problem: The big test suite passes, but then inv bd fails because it cannot find a reference to eidreader. That’s strange because eidreader is correctly being included when calling the interproject.configure function from conf.py file of the book.

The reason was a mixture of design flaws and side effects in Atelier.

Internal changes in Atelier

Here are some of the changes I did this week-end. I plan to release them as version 1.1.0 soon. See Changes in atelier, rstgen and sphinxfeed.

The interproject.configure function has become more severe in order to have better error message when intersphinx mappings don’t work as expected.

I added a warning “No objects.inv for {} of {}” to that function. BTW the new Sphinx logging API is cool!

This of course causes the whole thing to be more nitpicky, more severe and more fragile. Remember that most projects have tolerate_sphinx_warnings set to False.

Running pp inv bd now fails e.g. in my cd project (commondata) because that project has no docs folder. Or in the sr project which contains a Nikola (not a Sphinx) website.

It was not possible to change the value of doc_trees in a project that defines a namespace module. The default value for doc_trees is ['docs'], and in order to change it, we usually simply set it on the main module. Except when there is no main module (e.g. in docs-only projects) or when the main module is a namesapace module (TIL that you cannot set attributes on a namespace module). In these cases we define doc_trees in the tasks.py of the commondata project. But that was being ignored until now, just nobody noticed. Now the doc_trees specified in the tasks.py is used as the default value for the optional attribute on the main module.

New rules : the default value for doc_trees is ['docs'] only for projects without a main module. When a project has a main package, it is no longer allowed to define a doc_trees configuration value.

A special feature of interproject.configure is that it adds all projects of the atelier (as defined in The config.py file) to the intersphinx_mapping. As a corollaire of our change, this feature fails for the projects that come after this project in the atelier project’s list. So now we add only those the projects come before the current project. Which is a normal requirement: the sequence order of the atelier project’s list must honor intersphinx dependencies. A similar case is the welfare project which has more than one doc_trees (['docs', 'docs_de', 'docs_fr'] to be precise): the first doctree cannot expect the following ones to be built, so it cannot add intersphinx mappings from docs to docs_de.

There was a global instance of a Collection in atelier.invlib.ns being reused for all projects. Which caused side effects. To fix this, I had to impose a backwards-incompatible change to the tasks.py file:

from atelier.invlib.ns import ns
ns.setup_from_tasks(globals(), ...)

must change to:

from atelier.invlib import setup_from_tasks
ns = setup_from_tasks(globals(), ...)