From d03042f70282a65c51d9b472e5e0e417df630558 Mon Sep 17 00:00:00 2001 From: igerber Date: Mon, 10 Aug 2026 06:30:41 -0400 Subject: [PATCH 1/2] Bump version to 3.9.0 Retitles [Unreleased] to [3.9.0] with a release-highlights preamble, syncs the version across pyproject.toml, __init__.py, rust/Cargo.toml, llms-full.txt and CITATION.cff, and records the reader inventories the naming guard's rule-11 Duty C window demands once 3.9 arms the 4.0-scheduled rename rows (M-016 period_effects, M-050..M-058 overall_att) in docs/v4-deprecations.yaml code_refs. --- CHANGELOG.md | 32 +++++++++++++++++++++++++++++++- CITATION.cff | 4 ++-- diff_diff/__init__.py | 2 +- diff_diff/guides/llms-full.txt | 2 +- docs/v4-deprecations.yaml | 20 ++++++++++---------- pyproject.toml | 2 +- rust/Cargo.toml | 2 +- 7 files changed, 47 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b13d0e743..89d57fc09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,36 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## [3.9.0] - 2026-08-10 + +The 3.9 shim release of the 4.0 API-unification program (`docs/v4-design.md`): +every new surface ships additively, and every old spelling keeps working +through 3.9 with a `FutureWarning` steering to its replacement. Highlights: +the three estimator merges (TwoWayFixedEffects absorbs MultiPeriodDiD via +`event_study=True`, TripleDifference absorbs StaggeredTripleDifference, +ChangesInChanges absorbs QDiD via `method=`), post-fit +`results.aggregate(type=...)` across the staggered family, the library-wide +parameter-rename program (uniform `post`/`time`/`unit`/`first_treat`/ +`covariates` vocabulary, `_col` suffixes dropped), the shared `BaseEstimator` +`get_params`/`set_params` mixin with transactional `set_params`, fail-closed +inference-selector validation, deprecation of the module-level estimator +wrapper functions and the `CDiD`/`Stacked`/`Gardner` aliases, and the 4.0 +migration guide (`docs/migration-4.0.md`). Lifecycle authority for every +deprecation: `docs/v4-deprecations.yaml`. Full detail in the entries below. + +### Changed +- **Version 3.9.0 + the armed 4.0 rename window.** Bumping `__version__` to + 3.9 arms the naming guard's next enforcement window (section-8 rule-11 + "Duty C" in `tests/test_naming_guard.py`: a rename's reader inventory is + due when its `deprecated_in` enters the next-release horizon), so this + release records the previously-uninventoried readers of the 4.0-scheduled + old names on their ledger rows' `code_refs`: the `overall_att` field-flip + family [M-050]..[M-058] (producer modules, `diagnostic_report.py`'s + `getattr` fallback chains, `prep_dgp.py`, the staggered-DDD engine and + container, the three bundled AI guides, and the REGISTRY / REPORTING / + continuous-did methodology pages) and [M-016] `period_effects` + (`llms-full.txt`). No status flips and no behavior changes - the 4.0 + removal PRs consult these inventories so no reader is missed. ### Added - **4.0 migration guide** (`docs/migration-4.0.md`, v4 program Phase 4; the @@ -4744,6 +4773,7 @@ for the full feature history leading to this release. [2.1.2]: https://github.com/igerber/diff-diff/compare/v2.1.1...v2.1.2 [2.1.1]: https://github.com/igerber/diff-diff/compare/v2.1.0...v2.1.1 [2.1.0]: https://github.com/igerber/diff-diff/compare/v2.0.3...v2.1.0 +[3.9.0]: https://github.com/igerber/diff-diff/compare/v3.8.0...v3.9.0 [3.8.0]: https://github.com/igerber/diff-diff/compare/v3.7.0...v3.8.0 [3.7.0]: https://github.com/igerber/diff-diff/compare/v3.6.2...v3.7.0 [3.6.2]: https://github.com/igerber/diff-diff/compare/v3.6.1...v3.6.2 diff --git a/CITATION.cff b/CITATION.cff index e5f98a753..342b13d5e 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -7,8 +7,8 @@ authors: family-names: Gerber orcid: "https://orcid.org/0009-0009-3275-5591" license: MIT -version: "3.8.0" -date-released: "2026-07-18" +version: "3.9.0" +date-released: "2026-08-10" doi: "10.5281/zenodo.19646175" url: "https://github.com/igerber/diff-diff" repository-code: "https://github.com/igerber/diff-diff" diff --git a/diff_diff/__init__.py b/diff_diff/__init__.py index 78318ac7e..f73343f83 100644 --- a/diff_diff/__init__.py +++ b/diff_diff/__init__.py @@ -361,7 +361,7 @@ def __getattr__(name: str) -> _Any: raise AttributeError(f"module 'diff_diff' has no attribute {name!r}") -__version__ = "3.8.0" +__version__ = "3.9.0" __all__ = [ # Estimators "DifferenceInDifferences", diff --git a/diff_diff/guides/llms-full.txt b/diff_diff/guides/llms-full.txt index 02789c3ad..921d8e07f 100644 --- a/diff_diff/guides/llms-full.txt +++ b/diff_diff/guides/llms-full.txt @@ -2,7 +2,7 @@ > A Python library for Difference-in-Differences causal inference analysis. Provides sklearn-like estimators with statsmodels-style output for econometric analysis. -- Version: 3.8.0 +- Version: 3.9.0 - Repository: https://github.com/igerber/diff-diff - License: MIT - Dependencies: numpy, pandas, scipy (no statsmodels dependency) diff --git a/docs/v4-deprecations.yaml b/docs/v4-deprecations.yaml index e329246f1..172cee1d6 100644 --- a/docs/v4-deprecations.yaml +++ b/docs/v4-deprecations.yaml @@ -212,8 +212,8 @@ rows: status: planned phase: 5 warning: FutureWarning - code_refs: [diff_diff/results.py, diff_diff/honest_did.py, diff_diff/pretrends.py, diff_diff/visualization/_event_study.py, diff_diff/results_base.py, diff_diff/diagnostic_report.py, diff_diff/estimators.py] - notes: "Period-keyed dict becomes a FutureWarning property VIEW over the unified event-study surface on the successor container at 4.0; removed 5.0. Migrate this locator to the successor class when [M-011] flips (cross-row rule, spec section 11)." + code_refs: [diff_diff/results.py, diff_diff/honest_did.py, diff_diff/pretrends.py, diff_diff/visualization/_event_study.py, diff_diff/results_base.py, diff_diff/diagnostic_report.py, diff_diff/estimators.py, diff_diff/guides/llms-full.txt] + notes: "Period-keyed dict becomes a FutureWarning property VIEW over the unified event-study surface on the successor container at 4.0; removed 5.0. Migrate this locator to the successor class when [M-011] flips (cross-row rule, spec section 11). Reader inventory completed at the 3.9 bump, when the rule-11 Duty C window armed for 4.0-scheduled rows." # ---- fit(aggregate=) -> results.aggregate(type=) ------------------------- - id: M-020 @@ -626,8 +626,8 @@ rows: phase: 5 warning: FutureWarning test_ref: null - code_refs: [diff_diff/staggered_results.py, diff_diff/power.py, diff_diff/practitioner.py, diff_diff/efficient_did.py, diff_diff/wooldridge.py, diff_diff/_reporting_helpers.py] - notes: "Pickle migration via __setstate__ per spec section 5." + code_refs: [diff_diff/staggered_results.py, diff_diff/staggered.py, diff_diff/staggered_aggregation.py, diff_diff/power.py, diff_diff/practitioner.py, diff_diff/efficient_did.py, diff_diff/wooldridge.py, diff_diff/_reporting_helpers.py, diff_diff/diagnostic_report.py, diff_diff/prep_dgp.py, diff_diff/_staggered_triple_diff_engine.py, diff_diff/staggered_triple_diff_results.py, diff_diff/guides/llms-autonomous.txt, diff_diff/guides/llms-full.txt, diff_diff/guides/llms-practitioner.txt, docs/methodology/REGISTRY.md, docs/methodology/REPORTING.md] + notes: "Pickle migration via __setstate__ per spec section 5. This row carries the token family's CROSS-CUTTING consumer inventory (reports, guides, methodology docs, DGP helpers, the un-rowed staggered-DDD engine/container) alongside its own producers; per-class producer files live on their own rows. Inventory completed at the 3.9 bump, when the rule-11 Duty C window armed for 4.0-scheduled rows." - id: M-051 kind: field group: field-flip @@ -652,7 +652,7 @@ rows: status: planned phase: 5 warning: FutureWarning - code_refs: [diff_diff/imputation_results.py] + code_refs: [diff_diff/imputation_results.py, diff_diff/imputation.py] notes: "" - id: M-053 kind: field @@ -665,7 +665,7 @@ rows: status: planned phase: 5 warning: FutureWarning - code_refs: [diff_diff/two_stage_results.py] + code_refs: [diff_diff/two_stage_results.py, diff_diff/two_stage.py] notes: "" - id: M-054 kind: field @@ -678,7 +678,7 @@ rows: status: planned phase: 5 warning: FutureWarning - code_refs: [diff_diff/stacked_did_results.py] + code_refs: [diff_diff/stacked_did_results.py, diff_diff/stacked_did.py] notes: "" - id: M-055 kind: field @@ -691,7 +691,7 @@ rows: status: planned phase: 5 warning: FutureWarning - code_refs: [diff_diff/efficient_did_results.py] + code_refs: [diff_diff/efficient_did_results.py, diff_diff/efficient_did_aggregation.py] notes: "" - id: M-056 kind: field @@ -717,7 +717,7 @@ rows: status: planned phase: 5 warning: FutureWarning - code_refs: [diff_diff/chaisemartin_dhaultfoeuille_results.py] + code_refs: [diff_diff/chaisemartin_dhaultfoeuille_results.py, diff_diff/chaisemartin_dhaultfoeuille.py] notes: "" - id: M-058 kind: field @@ -730,7 +730,7 @@ rows: status: planned phase: 5 warning: FutureWarning - code_refs: [diff_diff/continuous_did_results.py] + code_refs: [diff_diff/continuous_did_results.py, diff_diff/continuous_did.py, docs/methodology/continuous-did.md] notes: "Also flips the deviant overall_att_se/overall_att_p_value/overall_att_conf_int/overall_att_t_stat sibling fields (the trap-catalog outlier)." # ---- Alias table --------------------------------------------------------- diff --git a/pyproject.toml b/pyproject.toml index e78ef4548..b416ef6c4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "diff-diff" -version = "3.8.0" +version = "3.9.0" description = "Difference-in-Differences causal inference with sklearn-like API. Callaway-Sant'Anna, Synthetic DiD, Honest DiD, event studies, parallel trends." readme = "README.md" license = "MIT" diff --git a/rust/Cargo.toml b/rust/Cargo.toml index cfa04e71b..9b40f033b 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "diff_diff_rust" -version = "3.8.0" +version = "3.9.0" edition = "2021" rust-version = "1.85" description = "Rust backend for diff-diff DiD library" From 7ae81c1690cf788c392424972372f21a9dfbb7c9 Mon Sep 17 00:00:00 2001 From: igerber Date: Mon, 10 Aug 2026 06:41:56 -0400 Subject: [PATCH 2/2] Qualify the 3.9 preamble's warning-coverage claim (review P2) "Every old spelling ... with a FutureWarning" overclaimed: a few deprecation windows are deliberately silent and rowed as such - verified by execution that accessing the QDiDResults export alias emits no warning of its own (M-061: the alias is a plain module global whose target class survives; constructing QDiD is what warns). The preamble now says warnings ride the documented shim paths and names the alias as the example. --- CHANGELOG.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 89d57fc09..c7d15dc20 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,8 +8,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [3.9.0] - 2026-08-10 The 3.9 shim release of the 4.0 API-unification program (`docs/v4-design.md`): -every new surface ships additively, and every old spelling keeps working -through 3.9 with a `FutureWarning` steering to its replacement. Highlights: +every new surface ships additively, and every deprecated spelling keeps +working through 3.9, with a `FutureWarning` on its documented shim path +(a few windows are deliberately silent and rowed as such in the ledger - +e.g. the `QDiDResults` export alias, where constructing `QDiD` is what +warns). Highlights: the three estimator merges (TwoWayFixedEffects absorbs MultiPeriodDiD via `event_study=True`, TripleDifference absorbs StaggeredTripleDifference, ChangesInChanges absorbs QDiD via `method=`), post-fit