Sphinx, Py.Test Plugins and Decorators

In Self-Documenting Python Stuff I showed how to use Sphinx to generate information (for management and organizational sake) about your scripts and modules and such. And that works great — unless you are using py.test plugins. Or at least ones that decorate methods. Like my marks one.

import pytest

class CheckMonkies(object):
    """
    Monkey Checks
    """
    @pytest.marks('shallow', 'minions')
    def test_flying_monkies(self):
        """
        Monkies with wings should be able to fly
        """
        m = Monkies(wings=True)
        assert(m.can_fly)

This code will run properly, but bail out at the decorator when being run in the context of Sphinx for the documentation. The root of the problem is how plugins are loaded in py.test which is at runtime through the use of special hooks and command-line flags. Which is magic to Sphinx and so it blows up (rightfully) saying that it knows nothing of pytest.marks.

The solution to this feels rather hacky, but works is better than pretty is most cases. (And it is actually not that bad…).

  1. First we add a new environment variable in Sphinx’s Makefile
    export DOCGENERATION=true

    or make.bat

    set DOCGENERATION=true
  2. Next we check whether the variable is set, and if so we import the annotation and monkey patch it onto the pytest module.
    import os
    if "DOCGENERATION" in os.environ:
        from marks import MarksDecorator
        pytest.marks = MarksDecorator

We need the environment check in there otherwise we could run afoul of the py.test import magic.

Post a Comment

Your email is never published nor shared. Required fields are marked *