May 172014

I like the idea of listing changes to my distribution in the long_desciption in So a release a go, I started appending docs/changes.rst to my README.rst file that I am using for pypi. It was a simple doc with bulleted lists. The world was good.

    with open('README.rst') as h_rst:
    with open('docs/changes.rst') as h_rst:

However, I grew unsatisified with my changes.rst file and wanted it to link, ala cross-references to the documentation, so when reading the docs a user could quickly go see the docs for that item. For example:

* added “preserve_mtime“ parameter to :meth:`.put`, optionally updates the remote file’s st_mtime to match the local file.

Sphinx liked it, I liked it.
However, python check --restructuredtext --strict gagged when it saw it, so would PyPi.

Harumph! I mutter to myself. I want it all, I want Don’t Repeat Yourself(DRY), I want my change log to display on PyPi, I want cross-references in my docs. However, cross-references don’t make sense in the long_description, what they link to isn’t there. I do not want to update changes in two different places, I am already vexed with making sure that just the one document is updated. After all, who likes writing docs more than writing code?

Well, how do I get the cross-references scrubbed out for the long_description? Here is what I coded up:

with open('README.rst') as h_rst:

with open('docs/changes.rst') as h_rst:
    BUF =
    BUF = BUF.replace('``', '$')        # protect existing code markers
    for xref in [':meth:', ':attr:', ':class:', ':func:']:
        BUF = BUF.replace(xref, '')     # remove xrefs
    BUF = BUF.replace('`', '``')        # replace refs with code markers
    BUF = BUF.replace('$', '``')        # restore existing code markers

It is a Decorate, Scrub, Transform, Undecorate kind of pattern. Stripping out the :roles: tags left the single ` markers. So, if I wanted to change those to ``, I have to hide all of the existing ``, scrub, transform, and then unhide the original ``. And so that is what I did.

I imagine a determined individual could create a regex to cover the entire breadth of sphinx directives and make a sphinx_to_pypi converter. But for me, my itch is scratched. Maybe it will help someone else too.

Here is the resulting long_description on pypi and the changes doc on

Who else is wrangling long_description from RestructuredText documentation? What are you doing?

 Posted by at 1:04 pm

Sorry, the comment form is closed at this time.