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…).
- First we add a new environment variable in Sphinx’s Makefile
- 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.