sphinx-doc / sphinx

The Sphinx documentation generator
https://www.sphinx-doc.org/
Other
6.59k stars 2.12k forks source link

Have one clear API for calling `Sphinx` without unintended side-effects (deprecate `SphinxTestApp`?) #12130

Open chrisjsewell opened 8 months ago

chrisjsewell commented 8 months ago

Currenty, there is no clearly documented way to "properly" use Sphinx programatically. By "properly", I mean in a way that could be called multiple times within the same Python interpretor, without any unexpected polluting of the global state, and thus act exactly the same as if each call had been made in a separate Python interpretor

At present, there are diverging ways to do this, for the main CLI and for test cases:

with patch_docutils(confdir), docutils_namespace():
    app = Sphinx(...)
    app.build(...)
app = SphinxTestApp(...)
app.build(...)
app.cleanup()

Its not really clear from first appearance, but these actually almost achieve the same thing:

However, there are also clear differences:

I feel this divergence is unecessary, and ideally there would be one clear way to call sphinx as an API, perhaps something like:

with Sphinx.restore_global_state(confdir):
    app = Sphinx(...)
    app.build(...)

cc @picnixz and @jayaddison for discussion, as it relates to #12093 etc


An additional note (as I just mentioned in https://github.com/sphinx-doc/sphinx/pull/12089#issuecomment-2004551050) is that it is not currently possible to temporarily turn-off colored logging output. This is annoying for if you want to assert the content of the warning stream

In the CLI it can be turned off, but is then never reset to its previous state: https://github.com/chrisjsewell/sphinx/blob/fa290049515c38e68edda7e8c17be69b8793bb84/sphinx/cmd/build.py#L327

pauleveritt commented 5 months ago

I'll add something that I'm interested in: multiple calls to build, passing in filenames.

Use case: a high-performance reloading server that is very different to the sphinx-autobuild approach. Currently, calling build repeatedly on the same sphinx.application.Sphinx instance has globals etc. as mentioned in this ticket.

webknjaz commented 4 months ago

In the context of testing, it'd also be nice if Sphinx exposed a pytest fixture for this.