Skip to content

Commit 236bdce

Browse files
igerberclaude
andcommitted
Address PR #376 R10 (2 P3)
R10 P3 #1 (qug_test deprecation warning text): qug_test was using the shared array-in deprecation messages that point users to migrate to `survey_design=` / `make_pweight_design(arr)`, but qug_test permanently rejects ALL survey-aware kwargs (Phase 4.5 C0 deferral). Replaced with qug-specific warning text that says the aliases are deprecated AND that survey-aware QUG remains unsupported, pointing users to `did_had_pretest_workflow(..., survey_design=...)` for the survey-aware linearity family instead. R10 P3 #2 (weights= parity tests on data-in wrappers): the previous round added survey= parity for joint_pretrends_test, joint_homogeneity_test, and did_had_pretest_workflow(aggregate='overall') but left the weights= rebinding paths warning-only with no numerical parity lock. Added 3 new tests: test_legacy_alias_parity_weights (joint_pretrends_test + joint_homogeneity_test) and test_legacy_alias_parity_weights_overall (workflow). Each asserts `weights=np.ones(n)` ≡ `survey_design=SurveyDesign(weights="w")` (uniform 1.0 column) on identical-numerical-output, locking the rebinding contract. 561 tests pass (was 558 + 3 new R10 P3 parity tests). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent b237022 commit 236bdce

2 files changed

Lines changed: 131 additions & 3 deletions

File tree

diff_diff/had_pretests.py

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1307,13 +1307,37 @@ def qug_test(
13071307
)
13081308

13091309
# Soft deprecation: route legacy survey=/weights= aliases through
1310-
# survey_design= for the gated NotImplementedError below.
1310+
# survey_design= for the gated NotImplementedError below. PR #376 R10
1311+
# P3: qug_test-specific deprecation messages — the shared
1312+
# HAD_DEPRECATION_MSG_*_KWARG_ARRAY_IN strings tell users to migrate to
1313+
# `survey_design=` / `make_pweight_design(...)`, but qug_test
1314+
# permanently rejects ALL survey-aware kwargs (Phase 4.5 C0 deferral).
1315+
# Use qug-specific warning text that says the aliases are deprecated
1316+
# but survey-aware QUG remains unsupported, and points users to
1317+
# unweighted `qug_test()` or `did_had_pretest_workflow(...,
1318+
# survey_design=...)` for the survey-aware linearity family.
13111319
if survey is not None:
1312-
warnings.warn(HAD_DEPRECATION_MSG_SURVEY_KWARG, DeprecationWarning, stacklevel=2)
1320+
warnings.warn(
1321+
"`survey=` is deprecated on qug_test (will be removed in the "
1322+
"next minor release). Note that qug_test does NOT support "
1323+
"survey-aware inputs at all (Phase 4.5 C0 permanent deferral; "
1324+
"see the NotImplementedError below). For survey-aware HAD "
1325+
"pretesting, use `did_had_pretest_workflow(..., "
1326+
"survey_design=...)` (the workflow skips the QUG step under "
1327+
"survey/weights and runs the linearity family).",
1328+
DeprecationWarning,
1329+
stacklevel=2,
1330+
)
13131331
survey_design = survey
13141332
elif weights is not None:
13151333
warnings.warn(
1316-
HAD_DEPRECATION_MSG_WEIGHTS_KWARG_ARRAY_IN,
1334+
"`weights=` is deprecated on qug_test (will be removed in the "
1335+
"next minor release). Note that qug_test does NOT support "
1336+
"weighted/survey inputs at all (Phase 4.5 C0 permanent deferral; "
1337+
"see the NotImplementedError below). For survey-aware HAD "
1338+
"pretesting, use `did_had_pretest_workflow(..., "
1339+
"survey_design=...)` (the workflow skips the QUG step under "
1340+
"survey/weights and runs the linearity family).",
13171341
DeprecationWarning,
13181342
stacklevel=2,
13191343
)

tests/test_had_dual_knob_deprecation.py

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,41 @@ def test_legacy_alias_parity_survey(self, event_study_panel):
640640
assert r_legacy.cvm_stat_joint == r_new.cvm_stat_joint
641641
assert r_legacy.p_value == r_new.p_value
642642

643+
def test_legacy_alias_parity_weights(self, event_study_panel):
644+
"""PR #376 R10 P3: deprecated `weights=np.ones(n)` ≡ canonical
645+
`survey_design=SurveyDesign(weights="w")` (uniform 1.0 column) on
646+
joint_pretrends_test."""
647+
df = event_study_panel
648+
n = len(df)
649+
with warnings.catch_warnings():
650+
warnings.simplefilter("ignore", DeprecationWarning)
651+
r_legacy = joint_pretrends_test(
652+
df,
653+
"y",
654+
"d",
655+
"time",
656+
"unit",
657+
pre_periods=[0],
658+
base_period=1,
659+
weights=np.ones(n),
660+
n_bootstrap=199,
661+
seed=0,
662+
)
663+
r_new = joint_pretrends_test(
664+
df,
665+
"y",
666+
"d",
667+
"time",
668+
"unit",
669+
pre_periods=[0],
670+
base_period=1,
671+
survey_design=SurveyDesign(weights="w"),
672+
n_bootstrap=199,
673+
seed=0,
674+
)
675+
assert r_legacy.cvm_stat_joint == r_new.cvm_stat_joint
676+
assert r_legacy.p_value == r_new.p_value
677+
643678

644679
class TestJointHomogeneityTestDeprecation:
645680
def test_survey_design_kwarg_smoke(self, event_study_panel):
@@ -725,6 +760,41 @@ def test_legacy_alias_parity_survey(self, event_study_panel):
725760
assert r_legacy.cvm_stat_joint == r_new.cvm_stat_joint
726761
assert r_legacy.p_value == r_new.p_value
727762

763+
def test_legacy_alias_parity_weights(self, event_study_panel):
764+
"""PR #376 R10 P3: deprecated `weights=np.ones(n)` ≡ canonical
765+
`survey_design=SurveyDesign(weights="w")` on
766+
joint_homogeneity_test."""
767+
df = event_study_panel
768+
n = len(df)
769+
with warnings.catch_warnings():
770+
warnings.simplefilter("ignore", DeprecationWarning)
771+
r_legacy = joint_homogeneity_test(
772+
df,
773+
"y",
774+
"d",
775+
"time",
776+
"unit",
777+
post_periods=[2, 3],
778+
base_period=1,
779+
weights=np.ones(n),
780+
n_bootstrap=199,
781+
seed=0,
782+
)
783+
r_new = joint_homogeneity_test(
784+
df,
785+
"y",
786+
"d",
787+
"time",
788+
"unit",
789+
post_periods=[2, 3],
790+
base_period=1,
791+
survey_design=SurveyDesign(weights="w"),
792+
n_bootstrap=199,
793+
seed=0,
794+
)
795+
assert r_legacy.cvm_stat_joint == r_new.cvm_stat_joint
796+
assert r_legacy.p_value == r_new.p_value
797+
728798

729799
class TestHADFitDeprecation:
730800
def test_survey_design_kwarg_smoke(self, two_period_panel):
@@ -967,6 +1037,40 @@ def test_legacy_alias_parity_survey_overall(self, two_period_panel):
9671037
assert r_legacy.stute.p_value == r_new.stute.p_value
9681038
assert r_legacy.yatchew.t_stat_hr == r_new.yatchew.t_stat_hr
9691039

1040+
def test_legacy_alias_parity_weights_overall(self, two_period_panel):
1041+
"""PR #376 R10 P3: deprecated `weights=np.ones(n)` ≡ canonical
1042+
`survey_design=SurveyDesign(weights="w")` on
1043+
did_had_pretest_workflow(aggregate='overall'). Closes the data-in
1044+
rebinding-parity gap on the weights= shortcut path."""
1045+
df = two_period_panel
1046+
n = len(df)
1047+
with warnings.catch_warnings():
1048+
warnings.simplefilter("ignore", UserWarning)
1049+
warnings.simplefilter("ignore", DeprecationWarning)
1050+
r_legacy = did_had_pretest_workflow(
1051+
df,
1052+
"y",
1053+
"d",
1054+
"time",
1055+
"unit",
1056+
weights=np.ones(n),
1057+
n_bootstrap=199,
1058+
seed=0,
1059+
)
1060+
r_new = did_had_pretest_workflow(
1061+
df,
1062+
"y",
1063+
"d",
1064+
"time",
1065+
"unit",
1066+
survey_design=SurveyDesign(weights="w"),
1067+
n_bootstrap=199,
1068+
seed=0,
1069+
)
1070+
assert r_legacy.stute.cvm_stat == r_new.stute.cvm_stat
1071+
assert r_legacy.stute.p_value == r_new.stute.p_value
1072+
assert r_legacy.yatchew.t_stat_hr == r_new.yatchew.t_stat_hr
1073+
9701074

9711075
# =============================================================================
9721076
# 3. PR #376 R2 P1: extended dispatch-matrix coverage on the new front door

0 commit comments

Comments
 (0)