Debugging Sphinx extensions#

Developing extensions for Sphinx documentation projects can easily grow into a big Python project. Debugging with print() quickly becomes a no-go. Let’s have a look how to debug Sphinx extension of any size.

I developed or maintain a few of Sphinx extensions. Small as sphinx-reredirects or big as sphinx-constdata. No matter of their size, I need to debug them with comfort as any other serious Python project. Let me to show you how in VS Code (generally in any IDE) and without an IDE.

Host Sphinx project#

You can’t develop Sphinx extension on its own. It needs a Sphinx project that uses it and test it by building a project. I call it a host Sphinx project. It means we will be actually debugging Sphinx build itself.

Debug in Visual Studio Code#

We will debug familiar Python script sphinx-build that you are using to build the docs. This script will bootstrap Sphinx with our extension.

Note

The principe of debugging Sphinx extensions based on debugging a sphinx-build is not exclude to VSCode and will work also in other Python IDEs like PyCharm.

I suppose you have already installed Python extension that turns your VSCode into Python IDE.

  1. Go to Run / Open Configurations if it is enabled. Otherwise, create a one with Run / Add Configurations… and choose Python as environment and Python File as configuration.

  2. VSCode opens .vscode/launch.json for you. Important is configurations list.

    {
        "version": "0.2.0",
        "configurations": [
            {
                // ...
            },
            {
                // ...
            },
        ]
    }
    
  3. Add configuration similar to the following:

    {
       "name": "my_extension",
       "type": "python",
       "request": "launch",
       "program": "venv/bin/sphinx-build",
       "args": ["-b", "html", "source", "source/_build/html", "-T", "-a", "-E"],
       "console": "integratedTerminal",
    }
    

    where

    • name is a name you will see in VSCode

    • program is a path to sphinx-build script. I installed Sphinx into virtual env, so path is to my venv

    • args are args passed to sphinx-build. I recommend -T to show full traceback in case of exception, and -a with -E to perform a fresh build. See sphinx-build man page for other parameters.

    Tip

    To ensure 100% clean build I recommend to delete output directory. We will need to create task to delete output directory and call it before launch configuration.

    In .vscode/tasks.json add a task that deletes Sphinx output directory:

    {
       "version": "2.0.0",
       "tasks": [
          {
                "label": "cleanSphinxOutDir",
                "type": "shell",
                "command": "rm -rf source/_build"
          }
       ]
    }
    

    We will call the cleanSphinxOutDir task from launch configuration by adding "preLaunchTask": "cleanSphinxOutDir":

    {
       "name": "my_extension",
       "type": "python",
       "request": "launch",
       "program": "venv/bin/sphinx-build",
       "args": ["-b", "html", "source", "source/_build/html", "-T", "-a", "-E"],
       "console": "integratedTerminal",
       "preLaunchTask": "cleanSphinxOutDir"
    }
    
  4. Place a breakpoint anywhere in your Sphinx extension, choose the configuration in Debug side panel and start the debugging.

Without IDE#

As an alternative to debug Sphinx extension from within IDE like VSCode, sphinx-build offer -P parameter that will run the builtin Python debugger, pdb, if an unhandled exception occurs while building.

  1. Somewhere in your Sphinx extension add pdb “breakpoint”:

    
    def setup(app: Sphinx):
       """
       Extension setup, called by Sphinx
       """
       app.connect("build-finished", init)
       app.add_config_value(OPTION_REDIRECTS, OPTION_REDIRECTS_DEFAULT, "env")
    
       import pdb; pdb.set_trace()   # <<--- stop here
    
  2. Launch sphinx-build with -P:

    sphinx-build -b html source source/_build/html -T -a -E -P
    

Comments

comments powered by Disqus