diff --git a/pyproject.toml b/pyproject.toml index 1fd0f2b6..2ade6497 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,6 +13,18 @@ additional-compiled-static-assets = [ testpaths = [ "tests" ] +filterwarnings = [ + "error", + 'ignore:Jupyter is migrating its paths to use standard platformdirs:DeprecationWarning', + 'ignore:The frontend\.OptionParser class will be replaced:DeprecationWarning', + 'ignore:The frontend\.Option class will be removed:DeprecationWarning', + 'ignore:nodes\.Node\.traverse\(\) is obsoleted by Node\.findall\(\):PendingDeprecationWarning', + # jupyter-client throws this + 'ignore:datetime\.datetime\.utcfromtimestamp\(\) is deprecated:DeprecationWarning', + 'ignore:datetime\.datetime\.utcnow\(\) is deprecated:DeprecationWarning', + # Sphinx triggers this + '''ignore:'imghdr' is deprecated and slated for removal in Python 3\.13:DeprecationWarning''', +] [project] name = "sphinx-book-theme" diff --git a/src/sphinx_book_theme/__init__.py b/src/sphinx_book_theme/__init__.py index da9e7498..756ab753 100644 --- a/src/sphinx_book_theme/__init__.py +++ b/src/sphinx_book_theme/__init__.py @@ -4,13 +4,13 @@ from pathlib import Path from functools import lru_cache -from docutils.parsers.rst.directives.body import Sidebar from docutils import nodes as docutil_nodes from sphinx.application import Sphinx from sphinx.locale import get_translation from sphinx.util import logging from pydata_sphinx_theme.utils import get_theme_options_dict +from .directives import Margin from .nodes import SideNoteNode from .header_buttons import ( prep_header_buttons, @@ -179,32 +179,9 @@ def check_deprecation_keys(app): ) -class Margin(Sidebar): - """Goes in the margin to the right of the page.""" - - optional_arguments = 1 - required_arguments = 0 - - def run(self): - """Run the directive.""" - if not self.arguments: - self.arguments = [""] - nodes = super().run() - nodes[0].attributes["classes"].append("margin") - - # Remove the "title" node if it is empty - if not self.arguments: - nodes[0].children.pop(0) - return nodes - - def update_general_config(app): theme_dir = get_html_theme_path() - # Update templates for sidebar. Needed for jupyter-book builds as jb - # uses an instance of Sphinx class from sphinx.application to build the app. - # The __init__ function of which calls self.config.init_values() just - # before emitting `config-inited` event. The init_values function overwrites - # templates_path variable. + app.config.templates_path.append(os.path.join(theme_dir, "components")) @@ -245,11 +222,20 @@ def setup(app: Sphinx): app.connect("builder-inited", check_deprecation_keys) app.connect("builder-inited", update_sourcename) app.connect("builder-inited", update_context_with_repository_info) - app.connect("builder-inited", update_general_config) app.connect("html-page-context", add_metadata_to_page) app.connect("html-page-context", hash_html_assets) app.connect("html-page-context", update_templates) + # This extension has both theme-like and extension-like features. + # Themes are initialised immediately before use, thus we cannot + # rely on an event to set the config - the theme config must be + # set in setup(app): + update_general_config(app) + # Meanwhile, extensions are initialised _first_, and any config + # values set during setup() will be overwritten. We must therefore + # register the `config-inited` event to set these config options + app.connect("config-inited", update_general_config) + # Nodes SideNoteNode.add_node(app) @@ -266,10 +252,6 @@ def setup(app: Sphinx): # Post-transforms app.add_post_transform(HandleFootnoteTransform) - # Update templates for sidebar, for builds where config-inited is not called - # (does not work in case of jupyter-book) - app.config.templates_path.append(os.path.join(theme_dir, "components")) - return { "parallel_read_safe": True, "parallel_write_safe": True, diff --git a/src/sphinx_book_theme/directives.py b/src/sphinx_book_theme/directives.py new file mode 100644 index 00000000..adaa004f --- /dev/null +++ b/src/sphinx_book_theme/directives.py @@ -0,0 +1,20 @@ +from docutils.parsers.rst.directives.body import Sidebar + + +class Margin(Sidebar): + """Goes in the margin to the right of the page.""" + + optional_arguments = 1 + required_arguments = 0 + + def run(self): + """Run the directive.""" + if not self.arguments: + self.arguments = [""] + nodes = super().run() + nodes[0].attributes["classes"].append("margin") + + # Remove the "title" node if it is empty + if not self.arguments: + nodes[0].children.pop(0) + return nodes diff --git a/tests/test_build.py b/tests/test_build.py index 70339c6e..77621e5f 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -1,7 +1,6 @@ import os from pathlib import Path from shutil import copytree, rmtree -from subprocess import check_call from importlib.metadata import version from packaging.version import parse @@ -28,9 +27,10 @@ def __init__(self, app: SphinxTestApp, src: Path): f".sphinx{sphinx.version_info[0]}" # software version tracking for fixtures ) - def build(self, assert_pass=True): + def build(self, assert_pass=True, assert_no_warnings=True): self.app.build() - assert self.warnings == "", self.status + if assert_no_warnings: + assert self.warnings == "", self.status return self @property @@ -62,14 +62,12 @@ def _func(src_folder, **kwargs): yield _func -def test_parallel_build(): - # We cannot use the sphinx_build_factory because SpinxTestApp does - # not have a way to pass parallel=2 to the Sphinx constructor - # https://github.com/sphinx-doc/sphinx/blob/d8c006f1c0e612d0dc595ae463b8e4c3ebee5ca4/sphinx/testing/util.py#L101 - check_call( - f"sphinx-build -j 2 -W -b html {path_tests}/sites/parallel-build build", - shell=True, - ) +def test_parallel_build(sphinx_build_factory): + sphinx_build = sphinx_build_factory("parallel-build", parallel=2) # type: SphinxBuild + sphinx_build.build( + assert_pass=True, assert_no_warnings=False + ) # TODO: filter these warnings + assert (sphinx_build.outdir / "index.html").exists(), sphinx_build.outdir.glob("*") def test_build_book(sphinx_build_factory, file_regression): diff --git a/tests/test_build/build__pagetoc--page-onetitlenoheadings.html b/tests/test_build/build__pagetoc--page-onetitlenoheadings.html new file mode 100644 index 00000000..dde1aee4 --- /dev/null +++ b/tests/test_build/build__pagetoc--page-onetitlenoheadings.html @@ -0,0 +1,2 @@ +
+