Skip to content

Commit c3fd1de

Browse files
igerberclaude
andcommitted
spillover-tva: fix CI failure — skip notebook-loading guards when source absent
CI's pure-Python and Rust matrix jobs copy `tests/` to an isolated location (per the "Copy tests to isolated location (Unix)" workflow step) WITHOUT the `docs/` tree, to verify the installed package doesn't depend on the source tree. Two of my new drift tests need to load `docs/tutorials/23_spillover_tva.ipynb` and fail with `FileNotFoundError: '/private/tmp/docs/tutorials/23_spillover_tva.ipynb'` on every non-source-tree job. Failing jobs (from run 26416449494): - Python Tests (macos-latest, py3.11/3.13/3.14) - Python Tests (windows-latest, py3.13) - Python Tests (ubuntu-24.04-arm, py3.14) Fix: both `test_notebook_dgp_constants_match_test_module_constants` and `test_notebook_dgp_ast_matches_test_fixture` now `pytest.skip()` gracefully when the notebook source isn't reachable, with a docstring note explaining that the sync-guard contract is meaningful in local dev (where edits happen) and the nbmake CI job separately verifies the notebook executes end-to-end. This preserves the codex R4/R6 P2 fixes (notebook source IS available in local dev runs and in the iterative codex-review workflow, so the guards still trigger on real edits) while making the suite robust to the project's isolated-tests CI pattern. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent eda04c0 commit c3fd1de

1 file changed

Lines changed: 30 additions & 2 deletions

File tree

tests/test_t23_spillover_tva_drift.py

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -386,12 +386,27 @@ def test_notebook_dgp_constants_match_test_module_constants():
386386
Parses the notebook §2 cell, walks the top-level
387387
``Assign`` nodes, and asserts the value of each expected constant
388388
matches the test module's value. Any notebook-only constant edit
389-
now fails this guard."""
389+
now fails this guard.
390+
391+
**CI isolation note:** the project's pure-Python and Rust CI jobs
392+
copy ``tests/`` to an isolated location WITHOUT the ``docs/``
393+
tree (to verify the installed package doesn't depend on the
394+
source tree). When the notebook source isn't reachable, this
395+
test skips gracefully — the sync-guard contract is meaningful
396+
in local dev (where edits happen) and the nbmake job separately
397+
verifies the notebook executes end-to-end."""
390398
import ast
391399
import json
392400
from pathlib import Path
393401

394402
nb_path = Path(__file__).resolve().parents[1] / "docs" / "tutorials" / "23_spillover_tva.ipynb"
403+
if not nb_path.exists():
404+
pytest.skip(
405+
f"Notebook source not found at {nb_path}; this drift guard "
406+
f"requires source-tree access and is meaningful only in local "
407+
f"dev. The nbmake CI job separately verifies the notebook "
408+
f"executes end-to-end."
409+
)
395410
with nb_path.open() as f:
396411
nb = json.load(f)
397412

@@ -453,13 +468,26 @@ def test_notebook_dgp_ast_matches_test_fixture():
453468
454469
Uses ``ast.dump`` for a whitespace-/comment-agnostic comparison:
455470
semantically identical code matches, cosmetic edits don't trigger
456-
spurious failures."""
471+
spurious failures.
472+
473+
**CI isolation note:** like
474+
``test_notebook_dgp_constants_match_test_module_constants``, this
475+
test skips gracefully when CI's isolated-tests-copy step strips
476+
the ``docs/`` tree. The sync-guard contract is meaningful in
477+
local dev where edits happen."""
457478
import ast
458479
import inspect
459480
import json
460481
from pathlib import Path
461482

462483
nb_path = Path(__file__).resolve().parents[1] / "docs" / "tutorials" / "23_spillover_tva.ipynb"
484+
if not nb_path.exists():
485+
pytest.skip(
486+
f"Notebook source not found at {nb_path}; this drift guard "
487+
f"requires source-tree access and is meaningful only in local "
488+
f"dev. The nbmake CI job separately verifies the notebook "
489+
f"executes end-to-end."
490+
)
463491
with nb_path.open() as f:
464492
nb = json.load(f)
465493

0 commit comments

Comments
 (0)