From 0f7d6ccd71cff036d647de0a2334b88f1a050ed6 Mon Sep 17 00:00:00 2001 From: Matt McKay Date: Mon, 20 Jul 2026 10:43:15 +1000 Subject: [PATCH 1/3] FIX: execution and doc failures from the Anaconda 2026.07 cache build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves the four failures reported in #182. All four are target-side defects; the English source is healthy in every case. likelihood_bayes — the font block called `mpl.font_manager.fontManager` and `plt.rcParams` before `import matplotlib.pyplot as plt`. Newer matplotlib no longer imports `font_manager` as a side effect of `import matplotlib`, so this raised AttributeError (and would have raised NameError on `plt`). Moved the pyplot import above both uses. An audit of the font block across all 69 lectures found this the only file with either ordering hazard. kalman_2 — a `.text()` annotation drew the covariance matrix with `\begin{bmatrix}`, which matplotlib mathtext cannot render (it supports no LaTeX environments). Rewritten as `\left[ \substack{...} \right]`, which renders an equivalent bracketed 2x2 matrix under mathtext, using `\;` as the column separator rather than `&`. This keeps the drop-usetex standard from #22 intact with no loss of information. The lecture's other `\begin{bmatrix}` uses are inside `{math}` blocks, rendered by MathJax, and are unaffected. sir_model — the header directive had lost its argument: `{raw}` instead of `{raw} jupyter`. The other 50 lectures carrying this directive kept theirs. ak_aiyagari — the file carried a stray fence at line 38 followed by a duplicated copy of the original frontmatter, and a doubled closing fence at EOF. The stray opener ran to line 56, swallowing both the H1 title and the `_admonition/gpu.md` include, which is what produced the 13 "headings start at H2" warnings. Removed both strays; the file's fence structure now matches the English source exactly (122). The `translation.title` field was also corrupt ("V, σ, μ") and has been set to the lecture title. An edition-wide sweep found no other file with unbalanced fences. The last two are content corruption introduced in translation and warrant engine issues against action-translation; they are not covered by the existing #107/#115/#116/#117 set. Co-Authored-By: Claude Opus 4.8 (1M context) --- lectures/ak_aiyagari.md | 18 +----------------- lectures/kalman_2.md | 4 ++-- lectures/likelihood_bayes.md | 2 +- lectures/sir_model.md | 2 +- 4 files changed, 5 insertions(+), 21 deletions(-) diff --git a/lectures/ak_aiyagari.md b/lectures/ak_aiyagari.md index 15dbf88..fc246e9 100644 --- a/lectures/ak_aiyagari.md +++ b/lectures/ak_aiyagari.md @@ -10,7 +10,7 @@ kernelspec: language: python name: python3 translation: - title: V, σ, μ + title: 长寿、异质性个体、世代交叠模型 headings: Overview: 概述 Environment: 经济环境 @@ -35,21 +35,6 @@ translation: 'Experiment 2: Preannounced tax cut': 实验2:预先宣布的减税 --- -``` ---- -jupytext: - text_representation: - extension: .md - format_name: myst - format_version: 0.13 - jupytext_version: 1.17.3 -kernelspec: - display_name: Python 3 (ipykernel) - language: python - name: python3 ---- - - # 长寿、异质性个体、世代交叠模型 ```{include} _admonition/gpu.md @@ -1477,4 +1462,3 @@ ax2.set_ylabel(r"j") plt.show() ``` -``` diff --git a/lectures/kalman_2.md b/lectures/kalman_2.md index ea01799..bdbf164 100644 --- a/lectures/kalman_2.md +++ b/lectures/kalman_2.md @@ -352,8 +352,8 @@ for i, t in enumerate(np.linspace(0, T-1, 3, dtype=int)): axs[i].set_ylabel(r'$u_{{{}}}$'.format(str(t))) cov_latex = ( - r'$\Sigma_{{{}}}= \begin{{bmatrix}} {:.2f} & {:.2f} \\ ' - r'{:.2f} & {:.2f} \end{{bmatrix}}$' + r'$\Sigma_{{{}}}= \left[ \substack{{{:.2f} \; {:.2f} \\ ' + r'{:.2f} \; {:.2f}}} \right]$' ).format(t, cov[0, 0], cov[0, 1], cov[1, 0], cov[1, 1]) axs[i].text(0.33, -0.15, cov_latex, transform=axs[i].transAxes) diff --git a/lectures/likelihood_bayes.md b/lectures/likelihood_bayes.md index 1400176..bcaffe5 100644 --- a/lectures/likelihood_bayes.md +++ b/lectures/likelihood_bayes.md @@ -62,10 +62,10 @@ translation: FONTPATH = "fonts/SourceHanSerifSC-SemiBold.otf" import matplotlib as mpl +import matplotlib.pyplot as plt mpl.font_manager.fontManager.addfont(FONTPATH) plt.rcParams['font.family'] = ['Source Han Serif SC'] -import matplotlib.pyplot as plt import numpy as np from numba import vectorize, jit, prange from math import gamma diff --git a/lectures/sir_model.md b/lectures/sir_model.md index 1f0daa7..6898ad8 100644 --- a/lectures/sir_model.md +++ b/lectures/sir_model.md @@ -21,7 +21,7 @@ translation: Ending Lockdown: 解除封锁 --- -```{raw} +```{raw} jupyter
QuantEcon From f0b2a46896277c72425f7e63aea12e01397a38ed Mon Sep 17 00:00:00 2001 From: Matt McKay Date: Mon, 20 Jul 2026 12:53:42 +1000 Subject: [PATCH 2/3] CI: align build safety with the English source repo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves #184. Brings ci.yml's execution safety in line with lecture-python.myst, which is the standard the fleet builds to. - `-n -W --keep-going` on the sphinx-tojupyter build. Previously this step ran with no flags, so a notebook whose cells raised still exited zero and the job went green. That is how the two execution breaks in #182 (likelihood_bayes, kalman_2) reached main with passing CI. - Upload Execution Reports (Download Notebooks), so a failure in that step leaves a traceback artifact. Previously there was none, which is why #182 had to be diagnosed from the weekly Build Cache workflow's artifact rather than from CI directly. - Clear stale Sphinx environment (`rm -rf _build/.doctrees`) before the builds, matching the source repo. The equivalent was present here only as a commented-out note. The HTML artifact is renamed `execution-reports` -> `execution-reports-html`. This is required, not cosmetic: upload-artifact@v7 runs with `overwrite: false`, so adding a second upload under the same name would collide when both steps fail in one run. The new names match the source repo's convention (-notebooks / -latex / -html). The PDF/LaTeX build is left commented out — see the issue for why that one needs a human decision rather than mechanical alignment. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/ci.yml | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2136dd4..a832970 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,6 +47,9 @@ jobs: branch: main name: build-cache path: _build + - name: Clear stale Sphinx environment + shell: bash -l {0} + run: rm -rf _build/.doctrees # # Build Assets (Download Notebooks and PDF via LaTeX) # - name: Build PDF from LaTeX # shell: bash -l {0} @@ -63,13 +66,16 @@ jobs: - name: Build Download Notebooks (sphinx-tojupyter) shell: bash -l {0} run: | - jb build lectures --path-output ./ --builder=custom --custom-builder=jupyter + jb build lectures -n -W --keep-going --path-output ./ --builder=custom --custom-builder=jupyter mkdir -p _build/html/_notebooks cp -u _build/jupyter/*.ipynb _build/html/_notebooks + - name: Upload Execution Reports (Download Notebooks) + uses: actions/upload-artifact@v7 + if: failure() + with: + name: execution-reports-notebooks + path: _build/jupyter/reports # Build HTML (Website) - # BUG: rm .doctress to remove `sphinx` rendering issues for ipywidget mimetypes - # and clear the sphinx cache for building final HTML documents. - # rm -r _build/.doctrees - name: Build HTML shell: bash -l {0} run: | @@ -78,7 +84,7 @@ jobs: uses: actions/upload-artifact@v7 if: failure() with: - name: execution-reports + name: execution-reports-html path: _build/html/reports - name: Preview Deploy to Netlify uses: nwtgck/actions-netlify@v4.0 From 31c808258d952d01e97c2a2fab16af6c91f33338 Mon Sep 17 00:00:00 2001 From: Matt McKay Date: Mon, 20 Jul 2026 13:42:22 +1000 Subject: [PATCH 3/3] CI: set -eo pipefail on the sphinx-tojupyter step MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses Copilot review feedback on #185. `shell: bash -l {0}` is a custom shell spec, so GitHub does not inject `-eo pipefail` — it only does that for the bare `shell: bash` shorthand, which expands to `bash --noprofile --norc -eo pipefail {0}`. Without it, this step's exit code is that of the trailing `cp`, so a failing `jb build` was masked. `--keep-going` made that worse rather than better: it forces Sphinx to emit output despite the errors, so the .ipynb files exist, `cp` succeeds, and the step goes green. The flag added in this PR to surface failures was producing the artifacts that hid them. Scope is exactly one step — an audit of ci.yml shows every other step is either single-command (its exit code is the command's) or uses the default shell, which does carry `-e`. Note the English source repo lecture-python.myst has the byte-identical pattern, so this is inherited from the standard rather than introduced here, and it deviates from the strict parity this PR set out to establish. Reported upstream so the standard can catch up. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a832970..a21c6dc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -66,6 +66,12 @@ jobs: - name: Build Download Notebooks (sphinx-tojupyter) shell: bash -l {0} run: | + # `shell: bash -l {0}` is a custom shell spec, so GitHub does not inject + # `-eo pipefail` (it only does that for the bare `shell: bash` shorthand). + # Without this, a failing `jb build` would be masked by the trailing + # mkdir/cp, whose exit code becomes the step's — and `--keep-going` + # guarantees the .ipynb files exist for `cp` to succeed on. + set -eo pipefail jb build lectures -n -W --keep-going --path-output ./ --builder=custom --custom-builder=jupyter mkdir -p _build/html/_notebooks cp -u _build/jupyter/*.ipynb _build/html/_notebooks