Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 34 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,39 @@ 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 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
`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
Expand Down Expand Up @@ -4744,6 +4776,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
Expand Down
4 changes: 2 additions & 2 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion diff_diff/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion diff_diff/guides/llms-full.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
20 changes: 10 additions & 10 deletions docs/v4-deprecations.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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 ---------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
Loading