From 46da0846ab5d8ad0b8c9b799d57a863ddf692171 Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Mon, 17 Aug 2026 15:57:04 +0200 Subject: [PATCH 01/17] Remove `check_links` from doc building script --- docs/scripts/build_documentation.py | 29 +++++------------------------ 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/docs/scripts/build_documentation.py b/docs/scripts/build_documentation.py index 756797be50..013b5ad191 100644 --- a/docs/scripts/build_documentation.py +++ b/docs/scripts/build_documentation.py @@ -6,7 +6,6 @@ from subprocess import check_call, run from build_examples import build_examples -from check_links import check_links from utils import adjust_pictures parser = argparse.ArgumentParser() @@ -16,16 +15,10 @@ help="Re-run the examples.", action="store_true", ) -parser.add_argument( - "-l", - "--no_linkcheck", - help="Do not check the links.", - action="store_true", -) parser.add_argument( "-r", "--full-rebuild", - help="Perform a full rebuild, independent of `-e` and `-l` flags.", + help="Perform a full rebuild, independent of `-e` flag.", action="store_true", ) parser.add_argument( @@ -44,7 +37,6 @@ # Parse input arguments args = parser.parse_args() RUN_EXAMPLES = args.run_examples -LINKCHECK = not args.no_linkcheck FULL_REBUILD = args.full_rebuild INCLUDE_WARNINGS = args.include_warnings FORCE = args.force @@ -52,16 +44,15 @@ def build_documentation( run_examples: bool = False, - verify_links: bool = False, full_rebuild: bool = False, force: bool = False, ) -> None: """Build the documentation. A full build of the documentation consists of converting the examples into jupyter - notebooks, executing them, transforming them into markdown files, as well as - checking all links and performing the actual ``sphinx-build``. Such a full build can - be triggered using the ``full_rebuild`` flag. + notebooks, executing them, transforming them into markdown files, and performing + the actual ``sphinx-build``. Such a full build can be triggered using the + ``full_rebuild`` flag. If this flag is not set, this function tries to re-use as much of potentially existing structures like already built examples as possible. This behavior can be changed by using the other flags. @@ -70,18 +61,14 @@ def build_documentation( run_examples: Fully recalculate the examples. If this is ``False`` and no folder containing an already built set of examples is found, dummy files replicating the structure of the examples are created. - verify_links: Check both internal and external links. full_rebuild: Perform a full rebuild of the documentation, including a - recalculation of the examples and checking the links. Note that this option - ignores the choices for ``run_examples`` and ``check_links`` if set to - ``True. + recalculation of the examples. force: Force-build the steps, ignoring any errors or warnings. """ examples_directory = pathlib.Path("docs/examples") examples_exist = examples_directory.is_dir() rerun_examples = run_examples or full_rebuild - perform_linkcheck = verify_links or full_rebuild if rerun_examples: build_examples( @@ -98,9 +85,6 @@ def build_documentation( remove_dir=examples_exist, ) - if perform_linkcheck: - check_links() - # Directory where the documentation is build. build_dir = pathlib.Path("docs/build") @@ -128,11 +112,8 @@ def build_documentation( if not INCLUDE_WARNINGS: os.environ["PYTHONWARNINGS"] = "ignore" - print(f"{LINKCHECK=}") - build_documentation( run_examples=RUN_EXAMPLES, - verify_links=LINKCHECK, full_rebuild=FULL_REBUILD, force=FORCE, ) From f69d091990bc3ebc72aa2c4adc17cbbdb8b9f042 Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Mon, 17 Aug 2026 15:59:01 +0200 Subject: [PATCH 02/17] Make `check_links` executable on its own --- docs/scripts/check_links.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/scripts/check_links.py b/docs/scripts/check_links.py index a2e3b415ac..35114948ce 100644 --- a/docs/scripts/check_links.py +++ b/docs/scripts/check_links.py @@ -1,10 +1,10 @@ -"""Utility for checking the links of the documentation.""" +"""Utility for checking the external links of the documentation.""" from subprocess import check_call def check_links() -> None: - """Check whether the links of the documentation are valid.""" + """Check whether the external links of the documentation are valid.""" link_call = [ "sphinx-build", "-b", @@ -14,3 +14,7 @@ def check_links() -> None: ] check_call(link_call) + + +if __name__ == "__main__": + check_links() From 2a6e8a266d4a5abb6f36ca0f4e1f036e9eab3f75 Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Mon, 17 Aug 2026 16:03:02 +0200 Subject: [PATCH 03/17] Add tox command for linkchecking --- tox.ini | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index 89a820cb60..8dca87833f 100644 --- a/tox.ini +++ b/tox.ini @@ -102,10 +102,19 @@ commands = uv run --locked --extra docs docs/scripts/build_documentation.py {posargs} [testenv:docs-quickbuild] -description = Force-build documentation, ignoring links and examples +description = Force-build documentation, ignoring examples skip_install = True setenv = SMOKE_TEST = true commands = python --version - uv run --locked --extra docs docs/scripts/build_documentation.py -f -l + uv run --locked --extra docs docs/scripts/build_documentation.py -f + +[testenv:linkcheck] +description = Check external links in the documentation +skip_install = True +setenv = + SMOKE_TEST = true +commands = + python --version + uv run --locked --extra docs docs/scripts/check_links.py From d00cf878ad892f6ce39e40aff144ceee424d187d Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Mon, 17 Aug 2026 16:06:43 +0200 Subject: [PATCH 04/17] Run linkcheck in CI pipeline --- .github/workflows/ci.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9b8f40c73e..af22251c4d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -91,6 +91,22 @@ jobs: run: | pip install tox-uv tox -e docs-py310 -- -r + + linkcheck: + name: "Link Check" + runs-on: ubuntu-latest + needs: [lint] + continue-on-error: true + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + with: + persist-credentials: false + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 + with: {python-version: "3.10"} + - name: Check external links + run: | + pip install tox-uv + tox -e linkcheck typecheck: needs: [lint] From 54e6549a91cba86f819aa20d159f538060c730c6 Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Mon, 17 Aug 2026 16:09:31 +0200 Subject: [PATCH 05/17] Fix broken link --- baybe/surrogates/gaussian_process/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/baybe/surrogates/gaussian_process/core.py b/baybe/surrogates/gaussian_process/core.py index 81d7f00c26..dba9ba1cec 100644 --- a/baybe/surrogates/gaussian_process/core.py +++ b/baybe/surrogates/gaussian_process/core.py @@ -306,7 +306,7 @@ def posterior_mean_function( * **Eagerly:** By calling the method and passing the returned module to a GP. * **Lazily:** By passing the bound method itself, without eagerly calling it. This works because the method signature complies with - :class:`~.components.mean.MeanFactoryProtocol`, i.e., the new GP will use it + :obj:`~.components.mean.MeanFactoryProtocol`, i.e., the new GP will use it as a factory and call it automatically at fit time. If the mean-providing GP has not been fitted at call time, its prior mean module From f04d2cec5c24533f10acfa452befca8ebfc13e96 Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Mon, 17 Aug 2026 16:12:36 +0200 Subject: [PATCH 06/17] Remove nitpick ignore regex ignoring everything that does not contain `baybe` This ignore helped in keeping the list of `nitpick_ignore_regex` small, but caused issues as this also means that relative internal links have not been checked, causing a lot of silent errors. --- docs/conf.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index aa0078b88a..4a73d5f9af 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -151,8 +151,6 @@ # Here, we define regex expressions for errors produced by nitpick that we want to # ignore. nitpick_ignore_regex = [ - # Ignore everything that does not include baybe - (r"py:.*", r"^(?!.*baybe).*"), # Ignore errors that are from inherited classes we cannot control (r"py:.*", r".*DTypeFloatONNX.*"), # Ignore the functions that we manually delete from in child classes From ab0f947dd21a256c3a0090498e30bad5a6aa1a00 Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Mon, 17 Aug 2026 16:16:40 +0200 Subject: [PATCH 07/17] Extend `nitpick-ignore-regex` list Since we now no longer simply ignore everything that does not contain `baybe`, the list needs to be extended manually. --- docs/conf.py | 44 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 4a73d5f9af..d4fba491a6 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -151,25 +151,59 @@ # Here, we define regex expressions for errors produced by nitpick that we want to # ignore. nitpick_ignore_regex = [ - # Ignore errors that are from inherited classes we cannot control + ##### External package references ##### + # Qualified references to external packages whose internal module paths cannot be + # resolved via intersphinx (e.g. pandas.core.frame.DataFrame vs pandas.DataFrame). + ( + r"py:.*", + r"(pandas|numpy|torch|botorch|gpytorch|scipy|sklearn|pathlib|polars|attr|joblib|matplotlib|skfp|rdkit|shap|xyzpy|typing)[\._].*", + ), # noqa: E501 + ##### Inherited torch.nn.Module docstring references ##### + # Unqualified names from inherited external docstrings (torch, botorch, sklearn) + # that cannot be resolved outside their original documentation context. + (r"py:class", r"^(Tensor|Module|Parameter|Dropout|BatchNorm)$"), + (r"py:class", r"^(Posterior|MetadataRequest|Ignored)$"), + (r"py:attr", r"^(persistent|grad_input|grad_output|requires_grad)$"), + (r"py:attr", r"^(device|dtype|dst_type|non_blocking)$"), + (r"py:func", r"^(register_module_forward_hook|register_module_forward_pre_hook)$"), + (r"py:func", r"^(register_module_full_backward_hook)$"), + (r"py:func", r"^(register_module_full_backward_pre_hook|load_state_dict)$"), + (r"py:meth", r"^nn\.Module\.load_state_dict$"), + ##### Inherited sklearn/scipy docstring artifacts ##### + # sklearn docstrings use informal type descriptions that Sphinx parses as refs. + (r"py:class", r"^(optional|shape|shape=|n_samples|n_features|n_query)$"), + (r"py:class", r"^(n_features_new|n_outputs|n_indexed|n_clusters)$"), + (r"py:class", r"^(array-like|ndarray|ndarray array|string)$"), + (r"py:class", r"^(estimator instance|sparse matrix\})$"), + (r"py:class", r"^(\{array-like|default=.*|\{\"default\")$"), + (r"py:class", r"^(dtype=np\.int64|if metric == 'precomputed')$"), + ##### Type aliases in TYPE_CHECKING blocks ##### + # These exist only at type-checking time and cannot be resolved by Sphinx. + (r"py:class", r"^(GPComponent|TensorCallable|ConvertibleToFloat)$"), + (r"py:class", r"^(GPyTorchKernel|GPyTorchLikelihood|GPyTorchMean|GPyTorchModel)$"), + (r"py:class", r"^(pd\.DataFrame|pl\.Expr)$"), + (r"py:class", r"^(TypeAliasForwardRef|P)$"), + (r"py:class", r"^\"(pandas|polars)\"\}?$"), + ##### BayBE-specific suppressions ##### + # Inherited classes we cannot control (r"py:.*", r".*DTypeFloatONNX.*"), - # Ignore the functions that we manually delete from in child classes + # Serialization functions manually deleted from child classes (r"py:.*", r".*from_dict.*"), (r"py:.*", r".*from_json.*"), (r"py:.*", r".*to_dict.*"), (r"py:.*", r".*to_json.*"), (r"py:.*", r".*_T.*"), - # Ignore files for which no __init__ is available at all + # Classes for which no __init__ is available at all (r"py:.*", "baybe.constraints.conditions.Condition.__init__"), (r"py:.*", "baybe.serialization.mixin.SerialMixin.__init__"), (r"DeprecationWarning:", ""), - # Ignore the generics/aliases + # Generics/aliases (r"py:class", "baybe.utils.basic._C"), (r"py:class", "baybe.utils.basic._T"), (r"py:class", "baybe.utils.basic._U"), (r"py:class", "baybe.surrogates.composite._SurrogateGetter"), (r"ref:obj", "baybe.surrogates.base.ModelContext"), - # Ignore custom class properties + # Custom class properties (r"py:obj", "baybe.settings._AdoptedRandomSeed.*"), (r"py:obj", "baybe.acquisition.acqfs.*.supports_batching"), (r"py:obj", "baybe.acquisition.acqfs.*.supports_pending_experiments"), From 8a5ef6e2682a8d774ab6fffef9d8b68eed345e6f Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Mon, 17 Aug 2026 16:18:06 +0200 Subject: [PATCH 08/17] Extend suppress_warnings --- docs/conf.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index d4fba491a6..6d67c5efd9 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -240,8 +240,15 @@ ] -# Ignore the warnings that are given by autosectionlabel -suppress_warnings = ["autosectionlabel.*"] +# Ignore certain warning categories +suppress_warnings = [ + "autosectionlabel.*", + # Forward reference and guarded import warnings from sphinx-autodoc-typehints. + # These are unavoidable since heavy deps (torch, botorch, gpytorch) are lazy-loaded + # and only available in TYPE_CHECKING blocks at runtime. + "sphinx_autodoc_typehints.forward_reference", + "sphinx_autodoc_typehints.guarded_import", +] # -- Options for HTML output ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output From b034bba6ccb9a68d3d7d63f47951f19d3ce18282 Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Mon, 17 Aug 2026 16:38:55 +0200 Subject: [PATCH 09/17] Fix broken links --- baybe/recommenders/meta/base.py | 3 ++- baybe/transformations/base.py | 17 +++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/baybe/recommenders/meta/base.py b/baybe/recommenders/meta/base.py index 21b0758843..d44a56bd75 100644 --- a/baybe/recommenders/meta/base.py +++ b/baybe/recommenders/meta/base.py @@ -52,7 +52,8 @@ def get_non_meta_recommender( ) -> RecommenderProtocol: """Follow the meta recommender chain to the selected non-meta recommender. - Recursively calls :meth:`MetaRecommender.select_recommender` until a + Recursively calls + :meth:`~baybe.recommenders.meta.base.MetaRecommender.select_recommender` until a non-meta recommender is encountered, which is then returned. Effectively, this extracts the recommender responsible for generating the recommendations for the specified context. diff --git a/baybe/transformations/base.py b/baybe/transformations/base.py index 4b84620980..2af5963eae 100644 --- a/baybe/transformations/base.py +++ b/baybe/transformations/base.py @@ -43,10 +43,11 @@ def get_codomain(self, interval: Interval | None = None, /) -> Interval: In accordance with the mathematical definition of a function's `codomain `_, we define the codomain of a given :class:`~baybe.utils.interval.Interval` under a certain (assumed continuous) - :class:`~Transformation` to be an :class:`~baybe.utils.interval.Interval` - guaranteed to contain all possible outcomes when the :class:`~Transformation` is - applied to all points in the input :class:`~baybe.utils.interval.Interval`. In - cases where the image cannot exactly be computed, it is often still possible to + :class:`~baybe.transformations.base.Transformation` to be an + :class:`~baybe.utils.interval.Interval` guaranteed to contain all possible + outcomes when the :class:`~baybe.transformations.base.Transformation` is applied + to all points in the input :class:`~baybe.utils.interval.Interval`. In cases + where the image cannot exactly be computed, it is often still possible to compute a codomain. The codomain always contains the image, but might be larger. """ @@ -56,10 +57,10 @@ def get_image(self, interval: Interval | None = None, /) -> Interval: In accordance with the mathematical definition of a function's `image `_, we define the image of a given :class:`~baybe.utils.interval.Interval` under a certain (assumed - continuous) :class:`~Transformation` to be the smallest - :class:`~baybe.utils.interval.Interval` containing all possible outcomes when - the :class:`~Transformation` is applied to all points in the input - :class:`~baybe.utils.interval.Interval`. + continuous) :class:`~baybe.transformations.base.Transformation` to be the + smallest :class:`~baybe.utils.interval.Interval` containing all possible + outcomes when the :class:`~baybe.transformations.base.Transformation` is applied + to all points in the input :class:`~baybe.utils.interval.Interval`. """ # By default, it is assumed that the exact image of an interval cannot be # computed but only the codomain is available (see :meth:`get_codomain`). From 48f57c728d9a0182a67f16cac8019ccf88465430 Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Mon, 17 Aug 2026 16:42:19 +0200 Subject: [PATCH 10/17] Fix admonition --- docs/components/transformations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/components/transformations.md b/docs/components/transformations.md index 5e349cc971..59c3fc0e81 100644 --- a/docs/components/transformations.md +++ b/docs/components/transformations.md @@ -399,7 +399,7 @@ t = CustomTransformation(torch.sin) ``` ````{admonition} Automatic Wrapping -:note: +:class: note When embedding custom transformations into another context, wrapping the `torch` callable into a {class}`~baybe.transformations.basic.CustomTransformation` happens From bd9fc6b7f63480a4755cbe53ef378bce7afaec77 Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Mon, 17 Aug 2026 16:50:54 +0200 Subject: [PATCH 11/17] Ignore kmedoids --- docs/templates/custom-module-template.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/templates/custom-module-template.rst b/docs/templates/custom-module-template.rst index 329973b4b4..fefd08024f 100644 --- a/docs/templates/custom-module-template.rst +++ b/docs/templates/custom-module-template.rst @@ -61,7 +61,7 @@ :template: custom-module-template.rst :recursive: {% for item in modules %} -{% if not item in ("baybe.objectives.deprecation", "baybe.recommenders.pure.bayesian.sequential_greedy") %} +{% if not item in ("baybe.objectives.deprecation", "baybe.recommenders.pure.bayesian.sequential_greedy", "baybe.utils.clustering_algorithms.third_party.kmedoids") %} {{ item }} {%- endif %} {%- endfor %} From 19ddee105559f2d901066095a7688501eec86556 Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Mon, 17 Aug 2026 16:52:56 +0200 Subject: [PATCH 12/17] Remove dead and unused option --- docs/conf.py | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 6d67c5efd9..175668b69e 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -139,7 +139,6 @@ templates_path = ["templates"] # Tell sphinx which files should be excluded exclude_patterns = ["sdk", "AGENTS.md", "CLAUDE.md", "**/AGENTS.md", "**/CLAUDE.md"] -autodoc_exclude_modules = ["baybe.utils.clustering_algorithms.third_party.kmedoids"] # Enable markdown # Note that we do not need additional configuration here. From 21d92b6e96a7ccf50850f44b3a7636b10c1dfc15 Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Mon, 17 Aug 2026 17:00:23 +0200 Subject: [PATCH 13/17] Fix exlcusion of modules in docbuilding --- docs/templates/custom-module-template.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/templates/custom-module-template.rst b/docs/templates/custom-module-template.rst index fefd08024f..becaa9a8ec 100644 --- a/docs/templates/custom-module-template.rst +++ b/docs/templates/custom-module-template.rst @@ -61,7 +61,7 @@ :template: custom-module-template.rst :recursive: {% for item in modules %} -{% if not item in ("baybe.objectives.deprecation", "baybe.recommenders.pure.bayesian.sequential_greedy", "baybe.utils.clustering_algorithms.third_party.kmedoids") %} +{% if not item in ("kmedoids",) %} {{ item }} {%- endif %} {%- endfor %} From ee88a31a20d4fac36d3361baf454bd1381424889 Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Mon, 17 Aug 2026 17:02:00 +0200 Subject: [PATCH 14/17] Remove unused directive --- docs/index.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/index.md b/docs/index.md index 2e94cc9a3b..dbf0348786 100644 --- a/docs/index.md +++ b/docs/index.md @@ -28,7 +28,6 @@ FAQ :toctree: _autosummary :template: custom-module-template.rst :recursive: - :hidden: baybe ``` From f1b3953c7118d64169c9901dd2e2f734f3ff8268 Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Mon, 17 Aug 2026 17:10:50 +0200 Subject: [PATCH 15/17] Move api_reference to dedicate file --- docs/api_reference.md | 17 +++++++++++++++++ docs/index.md | 9 --------- 2 files changed, 17 insertions(+), 9 deletions(-) create mode 100644 docs/api_reference.md diff --git a/docs/api_reference.md b/docs/api_reference.md new file mode 100644 index 0000000000..25d4f200ad --- /dev/null +++ b/docs/api_reference.md @@ -0,0 +1,17 @@ +--- +orphan: true +--- + + + +```{eval-rst} +.. autosummary:: + :toctree: _autosummary + :template: custom-module-template.rst + :recursive: + + baybe +``` diff --git a/docs/index.md b/docs/index.md index dbf0348786..f43b044add 100644 --- a/docs/index.md +++ b/docs/index.md @@ -23,15 +23,6 @@ FAQ :relative-docs: docs/ ``` -```{eval-rst} -.. autosummary:: - :toctree: _autosummary - :template: custom-module-template.rst - :recursive: - - baybe -``` - ```{toctree} :maxdepth: 2 :titlesonly: From 7dd762cb58ab52cbc2f32101c6af1a903fa9fb21 Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Mon, 17 Aug 2026 17:26:50 +0200 Subject: [PATCH 16/17] Move apidoc generation to doc building script --- docs/conf.py | 55 ----------------------------- docs/scripts/build_documentation.py | 30 ++++++++++++++++ 2 files changed, 30 insertions(+), 55 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 175668b69e..2d832c6698 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -4,9 +4,6 @@ # # For the full list of built-in configuration values, see the documentation: # https://www.sphinx-doc.org/en/master/usage/configuration.html -import os -import shutil - from gpytorch.kernels import Kernel as GPyTorchKernel from gpytorch.likelihoods import Likelihood as GPyTorchLikelihood from gpytorch.means import Mean as GPyTorchMean @@ -48,16 +45,6 @@ # >>>>>>>>>> NOTE END <<<<<<<<<< -# -- Path setup -------------------------------------------------------------- - -__location__ = os.path.dirname(__file__) - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# Seems to be not necessary at the moment -# sys.path.insert(0, os.path.join(__location__, "../examples")) - # -- Project information ----------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information @@ -66,48 +53,6 @@ author = "Merck KGaA, Darmstadt, Germany" -# -- Run sphinx-apidoc ------------------------------------------------------- -# This hack is necessary since RTD does not issue `sphinx-apidoc` before running -# `sphinx-build -b html . _build/html`. See Issue: -# https://github.com/readthedocs/readthedocs.org/issues/1139 -# DON'T FORGET: Check the box "Install your project inside a virtualenv using -# setup.py install" in the RTD Advanced Settings. -# Additionally it helps us to avoid running apidoc manually - -try: # for Sphinx >= 1.7 - from sphinx.ext import apidoc -except ImportError: - from sphinx import apidoc - -output_dir = os.path.join(__location__, "sdk") -baybe_module_dir = os.path.join(__location__, "../baybe") -try: - shutil.rmtree(output_dir) -except FileNotFoundError: - pass - -try: - args = [ - "--implicit-namespaces", - "-M", - "-T", - "-e", - "-f", - "-o", - output_dir, - ] - - apidoc.main( - [ - *args, - baybe_module_dir, - baybe_module_dir + "/__init__.py", - ] - ) -except Exception as e: - print(f"Running `sphinx-apidoc` failed!\n{e}") - - # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration diff --git a/docs/scripts/build_documentation.py b/docs/scripts/build_documentation.py index 013b5ad191..c6afa9ab61 100644 --- a/docs/scripts/build_documentation.py +++ b/docs/scripts/build_documentation.py @@ -3,6 +3,7 @@ import argparse import os import pathlib +import shutil from subprocess import check_call, run from build_examples import build_examples @@ -42,6 +43,32 @@ FORCE = args.force +def _run_apidoc() -> None: + """Generate API reference RST stubs via sphinx-apidoc.""" + from sphinx.ext import apidoc + + output_dir = pathlib.Path("docs/sdk") + module_dir = pathlib.Path("baybe") + + # Remove previously generated stubs to ensure a clean state + if output_dir.is_dir(): + shutil.rmtree(output_dir) + + apidoc.main( + [ + "--implicit-namespaces", + "-M", + "-T", + "-e", + "-f", + "-o", + str(output_dir), + str(module_dir), + str(module_dir / "__init__.py"), + ] + ) + + def build_documentation( run_examples: bool = False, full_rebuild: bool = False, @@ -85,6 +112,9 @@ def build_documentation( remove_dir=examples_exist, ) + # Generate the API reference stubs via sphinx-apidoc + _run_apidoc() + # Directory where the documentation is build. build_dir = pathlib.Path("docs/build") From af37ecd22dc4d48fe2f6ceeba281377867d11d4d Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Tue, 18 Aug 2026 10:11:58 +0200 Subject: [PATCH 17/17] Use Python 3.11 instead of 3.10 in the doc builiding This is necessary as we need to update one of the sphinx related packages for suppressing some of the errors that are now surfacing due to the separated build of the doc building and the link checking --- .github/workflows/ci.yml | 6 +++--- .github/workflows/docs.yml | 4 ++-- .github/workflows/regular.yml | 4 ++-- tox.ini | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index af22251c4d..cfb19e9cde 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -86,11 +86,11 @@ jobs: with: persist-credentials: false - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 - with: {python-version: "3.10"} + with: {python-version: "3.11"} - name: Build Docs run: | pip install tox-uv - tox -e docs-py310 -- -r + tox -e docs-py311 -- -r linkcheck: name: "Link Check" @@ -102,7 +102,7 @@ jobs: with: persist-credentials: false - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 - with: {python-version: "3.10"} + with: {python-version: "3.11"} - name: Check external links run: | pip install tox-uv diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 7826a693b0..4663edbc19 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -29,11 +29,11 @@ jobs: ref: ${{ github.ref }} persist-credentials: false - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 - with: {python-version: "3.10"} + with: {python-version: "3.11"} - name: Install tox run: pip install tox-uv - name: Build Docs - run: tox -e docs-py310 -- -r + run: tox -e docs-py311 -- -r - name: Configure sphinx bot for pushing and fetch branches run: | git config --local user.email "sphinx-upload[bot]@users.noreply.github.com" diff --git a/.github/workflows/regular.yml b/.github/workflows/regular.yml index 3ee54738b7..0d2861de3c 100644 --- a/.github/workflows/regular.yml +++ b/.github/workflows/regular.yml @@ -40,11 +40,11 @@ jobs: with: persist-credentials: false - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 - with: {python-version: "3.10"} + with: {python-version: "3.11"} - name: Build Docs run: | pip install tox-uv - tox -e docs-py310 -- -r + tox -e docs-py311 -- -r lint: strategy: diff --git a/tox.ini b/tox.ini index 8dca87833f..a95423cbf3 100644 --- a/tox.ini +++ b/tox.ini @@ -92,7 +92,7 @@ commands = python --version pip-audit {env:EXCLUDES:} -[testenv:docs-py310] +[testenv:docs-py311] description = Build documentation, passing posargs to control what should be built skip_install = True setenv =