Skip to content

Commit b808cda

Browse files
committed
test: forcing function for PartialConversion bridge reabsorption
Per pythia python#79 python#4 [chat L2032] + supervisor [chat L2034] python#4 assignment + theologian [chat L2036] design + generalist take. Closes pythia python#79 python#4 'PartialConversion calcification trigger conditional on external direction' substance: provides a forcing-function (test that fails in the calcification window) instead of an aspirational marker (REABSORB-WHEN comment alone, which depends on a future reader seeing it at the right moment). Lib/test/test_phoenix_partial_conversions.py: Pre-condition + assertion pattern per theologian L2036 spec. test_anycall_reabsorb_when_invokes_converted: Pre-condition: at least one of bool HIRBuilder::emitInvokeFunction / Native / Method remains C++ in builder.cpp → skip (legitimate partial state). Assertion: when all 3 INVOKE_* converted, fail if hir_builder_emit_awaited_call_tail_c bridge call remains in builder.cpp (i.e. emitAnyCall body still partial). Failure msg cites builder_emit_c.c PARTIAL CONVERSION ARTIFACT comment + reabsorb action so future readers locate the decision context. VERIFIED PASS today (INVOKE_* still C++ → test skipped): $ python3 -m unittest Lib.test.test_phoenix_partial_conversions -v test_anycall_reabsorb_when_invokes_converted: skipped Ran 1 test in 0.001s, OK (skipped=1) Pattern docs in module docstring for future PartialConversion authors: 1. Add test_<method>_reabsorb_when_<condition> 2. Encode pre-condition as text-grep on builder.cpp source 3. Encode assertion as bridge-symbol grep with explicit failure msg Forces the calcification check to run in EVERY normal test gate cycle, without requiring CI machinery additions (no lint script, no DCHECK runtime overhead, no comment-only marker reliance). Pattern generalizes: each future PartialConversion gets one test function. Authorization chain: - pythia python#79 python#4 surfaced calcification risk: chat L2032 - supervisor python#4 assignment to theologian (design): chat L2034 - theologian design (option ii test-as-forcing-function): chat L2036 - generalist implementation per scope-for-generalist-if-she-takes-it: chat L2034 ack
1 parent 15de220 commit b808cda

1 file changed

Lines changed: 89 additions & 0 deletions

File tree

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
"""Forcing-function tests for Phoenix JIT PartialConversion bridges.
2+
3+
Each test corresponds to one PartialConversion bridge — a C function
4+
extracted from a C++ method body while the surrounding C++ method body
5+
remains C++ pending a follow-on architectural workstream.
6+
7+
Each test follows the pre-condition + assertion pattern:
8+
9+
PRE-CONDITION (skip path)
10+
Verify the architectural condition that justifies the partial state
11+
still holds (e.g. dependent C++ methods still C++). If true, the
12+
bridge IS legitimately partial — skip the assertion.
13+
14+
ASSERTION (fail path)
15+
When the pre-condition no longer holds (e.g. all dependent methods
16+
converted to C), assert the bridge call has been removed from the
17+
parent method body — i.e. the bridge has been REABSORBED into a
18+
full C body.
19+
20+
This pattern catches the "calcification window" pythia #79 #4 named:
21+
when the dependency converts but the partial-conversion artifact
22+
fails to absorb. The test PASSES today (pre-condition holds), PASSES
23+
post-reabsorption (no bridge call), and FAILS in the calcification
24+
window — providing a forcing function rather than aspirational comment.
25+
26+
Origin: pythia #79 #4 [chat 2026-04-22 18:35Z], theologian design
27+
[chat 2026-04-22 18:36Z], generalist implementation [same chat L2034
28+
+#4 take].
29+
30+
Pattern docs for future PartialConversion authors:
31+
1. Add a test function `test_<method>_reabsorb_when_<condition>`.
32+
2. Encode pre-condition as text-grep on builder.cpp source.
33+
3. Encode assertion as bridge-symbol grep with explicit failure msg
34+
citing the source location of the artifact (so future readers
35+
find the comment + decision context fast).
36+
"""
37+
38+
import pathlib
39+
import unittest
40+
41+
REPO_ROOT = pathlib.Path(__file__).resolve().parents[2]
42+
BUILDER_CPP = REPO_ROOT / "Python" / "jit" / "hir" / "builder.cpp"
43+
44+
45+
class TestPhoenixPartialConversions(unittest.TestCase):
46+
"""Per-bridge forcing function for Phoenix JIT PartialConversion artifacts."""
47+
48+
@classmethod
49+
def setUpClass(cls):
50+
cls.builder_src = BUILDER_CPP.read_text()
51+
52+
def test_anycall_reabsorb_when_invokes_converted(self):
53+
"""emitAnyCall await-tail bridge must reabsorb when all INVOKE_* convert.
54+
55+
Bridge: hir_builder_emit_awaited_call_tail_c
56+
Source artifact: builder_emit_c.c (REABSORB-WHEN comment block)
57+
Pre-condition: at least one of emitInvokeFunction / Native / Method
58+
remains a bool-returning C++ method body in builder.cpp.
59+
Reabsorb-trigger: all 3 INVOKE_* converted → emitAnyCall opcode-switch
60+
can call them via C → emitAnyCall body itself can move to C →
61+
await-tail bridge no longer needed → inline back into full C body.
62+
"""
63+
invokes_still_cpp = (
64+
"bool HIRBuilder::emitInvokeFunction(" in self.builder_src
65+
and "bool HIRBuilder::emitInvokeNative(" in self.builder_src
66+
and "bool HIRBuilder::emitInvokeMethod(" in self.builder_src
67+
)
68+
if invokes_still_cpp:
69+
self.skipTest(
70+
"INVOKE_* (Function/Native/Method) still C++ — "
71+
"PartialConversion bridge is legitimately partial."
72+
)
73+
bridge_called = (
74+
"hir_builder_emit_awaited_call_tail_c" in self.builder_src
75+
)
76+
self.assertFalse(
77+
bridge_called,
78+
"INVOKE_Function/Native/Method are all converted to C, but "
79+
"hir_builder_emit_awaited_call_tail_c bridge call remains in "
80+
"Python/jit/hir/builder.cpp emitAnyCall body. REABSORB now: "
81+
"merge the C body of hir_builder_emit_awaited_call_tail_c "
82+
"(builder_emit_c.c, see 'PARTIAL CONVERSION ARTIFACT' comment "
83+
"block) into emitAnyCall_c. Then delete the bridge function "
84+
"and its extern decl in builder.cpp."
85+
)
86+
87+
88+
if __name__ == "__main__":
89+
unittest.main()

0 commit comments

Comments
 (0)