Skip to content

Commit b89458e

Browse files
committed
chore: nbdev v3
1 parent 7a33b90 commit b89458e

6 files changed

Lines changed: 21 additions & 9 deletions

File tree

.claude/rules/tooling.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ alwaysApply: true
7575
- The hook runs `.claude/validate.sh` with a 300-second timeout and `asyncRewake: true`.
7676
- Conditional logic in `validate.sh`:
7777
- **Skips entirely** for non-source files (`.md`, `.json`, `.yaml`, `.yml`, `.toml`, `.txt`, `.sh`, `.env`, `.gitignore`, `.dockerignore`).
78-
- **For `.ipynb` files**: runs `nbdev_export` first, then `make lint` and `make test`.
78+
- **For `.ipynb` files**: runs `nbdev-clean` (strip outputs), then `nbdev-export` (sync Python), warns if notebooks still have uncommitted changes, then `make lint` and `make nbdev-test`. This mirrors exactly what CI checks.
7979
- **For `.py` files**: always runs `make lint` and `make test`.
8080
- Exit code 2 on failure wakes the model to address the issue.
8181

.claude/validate.sh

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,25 @@ run() {
4141
fi
4242
}
4343

44-
# For notebook changes, export first
44+
# For notebook changes: clean (strip outputs) then export (sync Python files).
45+
# Mirrors exactly what CI does: nbdev-clean must be a no-op on committed notebooks,
46+
# and nbdev-export must produce no diff vs committed Python files.
4547
if echo "$CHANGED_FILE" | grep -qE "\.ipynb$"; then
46-
echo "--- nbdev_export ---"
48+
echo "--- uv run nbdev-clean ---"
49+
if ! uv run nbdev-clean; then
50+
echo "FAILED: nbdev-clean"
51+
FAILED=1
52+
fi
53+
echo "--- uv run nbdev-export ---"
4754
if ! uv run nbdev-export; then
48-
echo "FAILED: nbdev_export"
55+
echo "FAILED: nbdev-export"
4956
FAILED=1
5057
fi
58+
# Warn if notebooks still differ after clean (outputs were not stripped before save)
59+
DIRTY_NBS=$(git diff --name-only -- "*.ipynb" 2>/dev/null || true)
60+
if [ -n "$DIRTY_NBS" ]; then
61+
echo "WARNING: notebooks have uncommitted changes after nbdev-clean — commit them before pushing or CI will fail"
62+
fi
5163
fi
5264

5365
# Always run lint and notebook tests

nbs/01_deck.ipynb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@
284284
"#| export\n",
285285
"def draw_n(n:int, # number of cards to draw\n",
286286
" replace:bool=True): # whether or not draw with replacement\n",
287-
" \"Draw `n` cards, with replacement iif `replace`\"\n",
287+
" \"Draw `n` cards, with replacement iff `replace`\"\n",
288288
" d = Deck()\n",
289289
" d.shuffle()\n",
290290
" if replace: return [d.cards[random.choice(range(len(d.cards)))] for _ in range(n)]\n",
@@ -330,4 +330,4 @@
330330
},
331331
"nbformat": 4,
332332
"nbformat_minor": 5
333-
}
333+
}

nbs/index.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,4 +135,4 @@
135135
},
136136
"nbformat": 4,
137137
"nbformat_minor": 5
138-
}
138+
}

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ ignore = ["E501", "E402", "E731", "W191", "COM812", "ISC002"]
9898

9999
[tool.ruff.lint.per-file-ignores]
100100
# nbdev-generated files use fastcore star imports and @patch patterns
101-
"python_nbdev_starter/*.py" = ["F403", "F405", "E701", "E302", "E303"]
101+
"python_nbdev_starter/*.py" = ["F403", "F405", "E701", "E302", "E303", "I001"]
102102

103103

104104
# ---- Basedpyright ----

python_nbdev_starter/deck.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def remove(self:Deck,
4040
# %% ../nbs/01_deck.ipynb #c06f233e
4141
def draw_n(n:int, # number of cards to draw
4242
replace:bool=True): # whether or not draw with replacement
43-
"Draw `n` cards, with replacement iif `replace`"
43+
"Draw `n` cards, with replacement iff `replace`"
4444
d = Deck()
4545
d.shuffle()
4646
if replace: return [d.cards[random.choice(range(len(d.cards)))] for _ in range(n)]

0 commit comments

Comments
 (0)