Skip to content

Fix mypy errors, add notebook CI, clean up TODO#223

Merged
igerber merged 6 commits intomainfrom
tech-debt
Mar 21, 2026
Merged

Fix mypy errors, add notebook CI, clean up TODO#223
igerber merged 6 commits intomainfrom
tech-debt

Conversation

@igerber
Copy link
Copy Markdown
Owner

@igerber igerber commented Mar 21, 2026

Summary

  • Resolve all 9 mypy attr-defined errors by adding TYPE_CHECKING-guarded method stubs to 3 bootstrap mixin classes (staggered_bootstrap.py, two_stage_bootstrap.py, imputation_bootstrap.py)
  • Add GitHub Actions workflow (.github/workflows/notebooks.yml) to execute 15 tutorial notebooks in CI via nbmake, triggered on PR/push to relevant paths and weekly schedule
  • Add nbmake>=1.5 to dev dependencies
  • Clean up TODO.md: remove completed/crossed-out items, correct Sphinx warning diagnosis (376 from manual page autodoc, not ~1,460 from autosummary stubs), mark CallawaySantAnna HonestDiD support as done, add C-LF implementation note

Methodology references (required if estimator / math changes)

  • N/A — changes are type-annotation-only (no methodology or behavioral changes)

Validation

  • Tests added/updated: No test changes (type annotations are zero-runtime-cost; verified all 1885 tests pass)
  • mypy diff_diff reports 0 errors (down from 9)
  • Notebook CI workflow validated locally with DIFF_DIFF_BACKEND=python PYTHONPATH=. pytest --nbmake docs/tutorials/

Security / privacy

  • Confirm no secrets/PII in this PR: Yes

Generated with Claude Code

- Add TYPE_CHECKING-guarded method stubs to 3 bootstrap mixin classes,
  resolving all 9 mypy attr-defined errors (staggered_bootstrap.py,
  two_stage_bootstrap.py, imputation_bootstrap.py)
- Add GitHub Actions workflow to execute 15 tutorial notebooks in CI
  via nbmake (triggered on PR/push/weekly schedule)
- Add nbmake>=1.5 to dev dependencies
- Clean up TODO.md: remove completed/crossed-out items, correct Sphinx
  warning diagnosis (376 from manual pages, not 1460 from stubs), mark
  CallawaySantAnna HonestDiD support as done, add C-LF implementation
  note

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

Overall Assessment
✅ Looks good — no unmitigated P0/P1 findings.

Executive Summary

  • No methodology defects found. The estimator-side edits are TYPE_CHECKING stubs only and do not change weighting, variance, identification assumptions, bootstrap behavior, or defaults in the touched estimators.
  • Cross-checking the Methodology Registry against the touched bootstrap mixins shows no mismatch for Callaway-Sant’Anna, ImputationDiD, or TwoStageDiD.
  • No new edge-case regressions were introduced in the modified estimator files: no new inline inference anti-patterns, NaN/Inf guard regressions, parameter-plumbing gaps, or control-group logic changes.
  • TODO.md cleanup looks consistent with the codebase; it does not appear to hide unresolved correctness issues.
  • Two minor P3 items remain around the new notebook workflow: environment drift risk and an overstated claim about catching external dataset URL breakage.

Methodology

Code Quality

Performance

  • No findings. No estimator hot path changed; the runtime impact is limited to adding a CI notebook job.

Maintainability

Tech Debt

Security

  • No findings. No secrets handling, privilege escalation, or unsafe external-action pattern was introduced in the diff.

Documentation/Tests

  • Severity: P3. Impact: The weekly schedule comment says it “catches external breakage (dataset URLs, etc.)”, but the tutorial dataset loaders fall back to cached or constructed data when downloads fail, so upstream URL breakage may be masked without failing CI. References: .github/workflows/notebooks.yml:19, diff_diff/datasets.py:31, diff_diff/datasets.py:65, diff_diff/datasets.py:218, diff_diff/datasets.py:362. Concrete fix: Either reword the comment to describe a periodic notebook smoke test, or add a separate scheduled dataset-availability smoke test that uses force_download=True and fails on download errors.
  • Validation note: This review was static only. I did not run mypy or execute the notebook workflow locally because the review sandbox does not have the scientific Python dependencies installed (numpy import failed).

igerber and others added 2 commits March 21, 2026 11:32
PYTHONPATH=. only affects the shell, not the Jupyter kernel spawned by
nbmake. Write a .pth file into site-packages so the kernel can import
diff_diff. Also add ipykernel dependency and set DIFF_DIFF_BACKEND via
env block.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Reword schedule comment: "smoke test" instead of overstating
  dataset URL breakage detection (loaders have fallbacks)
- Add "Keep in sync" comment on manual dep list, matching the
  convention in rust-test.yml python-fallback job
- Note why pip install -e . isn't used (requires Rust toolchain)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@igerber
Copy link
Copy Markdown
Owner Author

igerber commented Mar 21, 2026

/ai-review

@github-actions
Copy link
Copy Markdown

🔁 AI review rerun (requested by @igerber)

Head SHA: b731c338420e22eb20c444b44265bfe0d4e26860


Overall Assessment

✅ Looks good — no unmitigated P0/P1 findings.

Executive Summary

Methodology

Code Quality

  • No findings. The stub signatures line up with the concrete helper methods they describe, and the modified bootstrap files do not introduce the prohibited inline inference pattern or partial NaN-guard pattern.

Performance

  • No findings. The estimator hot paths are unchanged; the only runtime addition is notebook execution in CI.

Maintainability

  • P3 Impact: .github/workflows/notebooks.yml:L35-L41 hard-codes a partial dependency set and relies on a handwritten .pth injection, which can drift from the declared dependency surface in pyproject.toml:L46-L63 and make notebook CI exercise a different environment from supported installs. Concrete fix: keep the current “no Rust build” approach if desired, but move notebook-runtime dependencies into a single source of truth such as a dedicated extra or requirements file and install from that, rather than duplicating package names inline in the workflow.

Tech Debt

Security

  • No findings. The new workflow uses the standard pull_request trigger, not pull_request_target, and does not add secrets handling or elevated permissions in .github/workflows/notebooks.yml:L3-L18.

Documentation/Tests

  • No findings. The prior informational concern about overstating scheduled dataset-availability coverage is addressed by rewording the weekly schedule comment to a generic notebook smoke test at .github/workflows/notebooks.yml:L18-L20.

Review basis: static review only. The local environment did not have mypy, numpy, pandas, scipy, pytest, nbmake, or ipykernel, so I did not rerun mypy or execute the notebook workflow.

igerber and others added 3 commits March 21, 2026 12:24
- Increase per-notebook timeout from 300s to 600s (pure Python mode
  without Rust backend is significantly slower for Monte Carlo and
  optimization-heavy notebooks)
- Exclude 10_trop.ipynb (LOOCV grid search exceeds 600s in pure
  Python mode)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The notebook was passing all periods (pre and post) as post_periods
to MultiPeriodDiD, causing HonestDiD to fail with "No pre-period
effects found" since the results had no pre-period classification.

Fix: pass only actual post-treatment periods [5-9] to post_periods.
MultiPeriodDiD automatically estimates pre-period coefficients for
the event study, and HonestDiD can now correctly identify them.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
06_power_analysis.ipynb runs SyntheticDiD simulate_power which is a
Monte Carlo simulation too slow for pure-Python CI without the Rust
backend. Same category as the already-excluded TROP notebook.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@igerber igerber merged commit 6454bd6 into main Mar 21, 2026
14 checks passed
@igerber igerber deleted the tech-debt branch March 21, 2026 19:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant