From e806e40920cb77c3a03c7072a8bc6a09054c8040 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Braun Date: Sun, 10 May 2026 00:41:19 +0200 Subject: [PATCH] Fix broken VAE notebook link in README.rst MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The BaseVAE notebook URL in README.rst pointed at `docs/notebooks/DiCE_getting_started_feasible.ipynb`, but the actual on-disk path is `docs/source/notebooks/DiCE_getting_started_feasible.ipynb`. The link has 404'd for users following the README ever since the `docs/source/` reorganisation. Adds `tests/test_readme_links.py` which scans every `https://github.com/interpretml/DiCE/blob//.ipynb` URL in README.rst and asserts it resolves to a real file in the repo. Only checks in-repo paths — no network access. This prevents future README/folder-rename drift from re-introducing 404 links. Closes #308. Signed-off-by: Jean-Baptiste Braun --- README.rst | 2 +- tests/test_readme_links.py | 49 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 tests/test_readme_links.py diff --git a/README.rst b/README.rst index ac5e4091..1ce6be3e 100644 --- a/README.rst +++ b/README.rst @@ -162,7 +162,7 @@ See `model-agnostic notebook **Gradient-based methods** * An explicit loss-based method described in `Mothilal et al. (2020) `_ (Default for deep learning models). -* A Variational AutoEncoder (VAE)-based method described in `Mahajan et al. (2019) `_ (see the BaseVAE `notebook `_). +* A Variational AutoEncoder (VAE)-based method described in `Mahajan et al. (2019) `_ (see the BaseVAE `notebook `_). The last two methods require a differentiable model, such as a neural network. If you are interested in a specific method, do raise an issue `here `_. diff --git a/tests/test_readme_links.py b/tests/test_readme_links.py new file mode 100644 index 00000000..eb7119e1 --- /dev/null +++ b/tests/test_readme_links.py @@ -0,0 +1,49 @@ +"""Lightweight regression test for README notebook links. + +Issue #308 reported that the BaseVAE notebook link in README.rst pointed +at `docs/notebooks/...` instead of the actual `docs/source/notebooks/...` +path. The link had been broken for years because nothing in CI checked +that in-repo notebook references resolve to real files. + +This test scans README.rst for any `https://github.com/interpretml/DiCE/ +blob//docs/...notebook.ipynb` URL and asserts each one resolves to +a file under the working tree. It only validates *in-repo* links — it +does not hit the network. +""" +from __future__ import annotations + +import os +import re + +REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)) +README_PATH = os.path.join(REPO_ROOT, "README.rst") + +# Match `https://github.com/interpretml/DiCE/blob//.ipynb`. +_NOTEBOOK_RE = re.compile( + r"https://github\.com/interpretml/DiCE/blob/[^/]+/(?P[^>\s)]+\.ipynb)" +) + + +def _readme_notebook_paths(): + with open(README_PATH, "r", encoding="utf-8") as fh: + text = fh.read() + return list({m.group("path") for m in _NOTEBOOK_RE.finditer(text)}) + + +def test_readme_lists_at_least_one_notebook_link(): + # Sanity: if this drops to 0 the regex got broken or README was rewritten. + assert _readme_notebook_paths(), "README must list at least one notebook" + + +def test_readme_notebook_links_resolve(): + """Every notebook URL in README.rst must point to a file in the repo.""" + missing = [ + path + for path in _readme_notebook_paths() + if not os.path.isfile(os.path.join(REPO_ROOT, path)) + ] + assert not missing, ( + "README.rst links to notebooks that do not exist in the repo: " + f"{missing}. See issue #308 — make sure the URL path matches the " + "actual on-disk path under docs/source/notebooks/." + )