Skip to content

Commit 33e9c67

Browse files
igerberclaude
andcommitted
Fix CI review R5: persist pre/post_periods_used on HonestDiDResults
- Add pre_periods_used and post_periods_used fields to HonestDiDResults so the retained horizon set is always available on the results object - HonestDiD.fit() populates both fields from the extracted period lists - Summary renders retained horizons below the target label - Add test_honest_did_retains_period_metadata asserting fields populated and summary shows "Post horizons used:" Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 419d872 commit 33e9c67

3 files changed

Lines changed: 34 additions & 0 deletions

File tree

diff_diff/chaisemartin_dhaultfoeuille_results.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -988,6 +988,18 @@ def _render_honest_did_section(
988988
thin,
989989
f"{'Method:':<35} {method_label} (M={_fmt_float(m_val)})",
990990
f"{'Target:':<35} {hd.target_label}",
991+
]
992+
)
993+
if hd.post_periods_used is not None:
994+
lines.append(
995+
f"{'Post horizons used:':<35} {hd.post_periods_used}"
996+
)
997+
if hd.pre_periods_used is not None:
998+
lines.append(
999+
f"{'Pre horizons used:':<35} {hd.pre_periods_used}"
1000+
)
1001+
lines.extend(
1002+
[
9911003
f"{'Original estimate:':<35} {_fmt_float(hd.original_estimate):>10}",
9921004
f"{'Identified set:':<35} "
9931005
f"[{_fmt_float(hd.lb)}, {_fmt_float(hd.ub)}]",

diff_diff/honest_did.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,8 @@ class HonestDiDResults:
192192
alpha: float = 0.05
193193
ci_method: str = "FLCI"
194194
target_label: str = "Equal-weight avg over post horizons"
195+
pre_periods_used: Optional[List[Any]] = field(default=None, repr=False)
196+
post_periods_used: Optional[List[Any]] = field(default=None, repr=False)
195197
original_results: Optional[Any] = field(default=None, repr=False)
196198
# Event study bounds (optional)
197199
event_study_bounds: Optional[Dict[Any, Dict[str, float]]] = field(default=None, repr=False)
@@ -2330,6 +2332,8 @@ def fit(
23302332
alpha=self.alpha,
23312333
ci_method=ci_method,
23322334
target_label=target_label,
2335+
pre_periods_used=list(pre_periods),
2336+
post_periods_used=list(post_periods),
23332337
original_results=results,
23342338
survey_metadata=survey_metadata,
23352339
df_survey=df_survey,

tests/test_chaisemartin_dhaultfoeuille.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3404,6 +3404,24 @@ def test_honest_did_custom_l_vec_on_impact(self):
34043404
rtol=1e-10,
34053405
)
34063406

3407+
def test_honest_did_retains_period_metadata(self):
3408+
"""HonestDiDResults stores pre_periods_used and post_periods_used."""
3409+
df = self._make_data()
3410+
with warnings.catch_warnings():
3411+
warnings.simplefilter("ignore")
3412+
r = ChaisemartinDHaultfoeuille(seed=1).fit(
3413+
df, "outcome", "group", "period", "treatment",
3414+
L_max=2, honest_did=True,
3415+
)
3416+
hd = r.honest_did_results
3417+
assert hd.pre_periods_used is not None
3418+
assert hd.post_periods_used is not None
3419+
assert all(p < 0 for p in hd.pre_periods_used)
3420+
assert all(p > 0 for p in hd.post_periods_used)
3421+
# Summary renders the retained horizons
3422+
text = r.summary()
3423+
assert "Post horizons used:" in text
3424+
34073425
def test_honest_did_custom_l_vec_summary_label(self):
34083426
"""summary() renders custom target label when l_vec is overridden."""
34093427
from diff_diff.honest_did import compute_honest_did

0 commit comments

Comments
 (0)