Skip to main content

Sphinx supplement

Once upon a time, i was in a team led by a developer who was devoted to introducing modern standards. he didn't have much experience, so i think this devotion was essentially a cloaking device. though we didn't generate documentation, most pull requests elicited a request for a docstring change.

my first post about Holistic Development focused on logging. this one is about generated documentation. though software developers habitually read code, generated documentation can become their primary source of information because it's easier to read. it also assures product owners that features are addressed, and that the design is orderly.

Documentation review

a docstring is just a comment until documentation is generated. at that point, evaluation of docstring quality should be based on the generated documentation. sometimes a word should be formatted differently; sometimes it should be a link. in other words, a docstring's contribution to the generated documentation is more/less appropriate depending on its context.

Documentation conventions

PEP 257 is obsolete because it predates type hints. adopt sensible conventions, enforce them strictly, and configure code quality tools accordingly.

i think generated documentation should avoid implementation details. doing this makes information more accessible for product owners and clients. limiting the scope of this documentation also eliminates protracted discussion about docstring quality. describing interfaces and other externally visible features is so important, we should be reluctant to dilute this information. most importantly, there isn't enough time.

in this approach, private definitions should not have docstrings. thus, exceptions raised by private methods should be described by the corresponding public methods. more generally, emphasizing documentation quality influences visibility. a class/method that should not contribute to documentation should be private!

Sphinx usage

a language implicitly defines conventions, and some of these are de facto standards. for example, repr("spam") returns a string containing single quotation marks. not surprisingly, Python's documentation consistently uses single quotation marks in its examples. Black is better than chaos, but it's a bit boorish.

though Sphinx is the standard documentation generator for Python, i once used Doxygen to generate documentation for a Python SDK. this SDK was delivered with a PHP SDK for the same service, and i wanted to make them as similar as possible. one could flip between corresponding documentation pages by editing the language name in the URL, because the packages used the same namespace, class, and method names.

those documentation pages were a little old-fashioned, but they were neat enough and included inheritance diagrams generated by graphviz. though it may have been fashionable to overuse inheritance long ago, it should be used when appropriate. these diagrams are a good way of introducing the most important parts of a design; each diagram is like a miniature table of contents.

Sphinx integration

selecting an HTML theme and overriding defaults is a chore, but reusing the result is easy. the result (i.e. theme selection and configuration values) is easily updated/reviewed, and propagating documentation upgrades is safe.

the starting point should be a project created by sphinx-quickstart. differences between the generated Makefile and conf.py with the corresponding files in the project should be minimal. as my example illustrates, the difference between a project Makefile and a generated one can be purely additive.

Makefile extensions

any project that includes tests should produce code coverage reports, because they assure product/project managers that the application is maintained conscientiously. it's easy to inject these reports into the HTML build directory.

if your application is a REST API server and you've lost your swagger, add a link to its OpenAPI specification. modifying the Sphinx Makefile to do this requires almost no effort.

Comments

Popular posts from this blog

Hoppin' John

Classic recipes born in poverty can be revised to take advantage of things we take for granted. in particular, many dishes traditionally cooked in one pot benefit from separation. on the other hand, we should respect timeless combinations of flavors and textures. ain't nothing like the real thing. Pork off cuts are authentic because this was a slave's dish, but i prefer bacon. ham hocks can taste a bit coarse and deboning them is a chore. i always have salt pork on hand, but it would require rinsing. in general, do not buy packaged bacon unless it's deeply discounted and reasonably lean. packaged ends/pieces can be easier to use and always cost less than slices. when a butcher displays the lean end of a slab, buy all of it. for this dish, i want bite-sized piec...

Bourne to grep

And now for something completely different: a stupid script trick ... once upon a time, i worked with two software developers who had just started their careers. after giving them a script, one of them complained that it didn't support the --help option. the script was about ten lines including its shebang, without conditional expressions or complexity of any kind. i defended its informality by noting that scripts are text files, so developers can easily discover how to use them. my response had no effect, but i still think scripts written for members of the same development team may be less formal/helpful than usual. since then, i did change my mind about one thing: for a long time, i used Python whenever statements were conditionally executed. i use the Bourne shell more often now.

Wake up and smell the glove

After mistakenly buying a large bag of ground coffee, i decided to learn the cold brew process. in the same way that pickleball is similar to badminton, cold steeping resembles espresso and pour over coffee. even though there are obvious differences, some things never change. Grind grind size usually affects extraction, but it has no effect here. on the other hand, it always affects filtration and i get very different results without reconfiguring my grinder (Orphan Espresso Lido 2). for various reasons, i steep in a medium saucepan. first, i add crumbled star anise (because i own too much of it). then, i grind coffee directly into the saucepan. Pour i pour water around the perimeter of the saucepan to prevent ground cof...