Skip to content

bpo-29403: Fix mock's broken autospec behavior on method-bound builtin functions - #3

Merged
berkerpeksag merged 3 commits into
python:masterfrom
habnabit:fix-mock-builtin-methods-for-cython
Jul 20, 2017
Merged

bpo-29403: Fix mock's broken autospec behavior on method-bound builtin functions#3
berkerpeksag merged 3 commits into
python:masterfrom
habnabit:fix-mock-builtin-methods-for-cython

Conversation

@habnabit

Copy link
Copy Markdown
Contributor

http://bugs.python.org/issue29403

Cython will, in the right circumstances, offer a MethodType instance
where im_func is a builtin function. Any instance of MethodType is
automatically assumed to be a python-defined function (more
specifically, a function that has an inspectable signature), but
_set_signature was still conservative in its assumptions. As a result
_set_signature would return early with None instead of a mock since the
im_func had no inspectable signature. This causes problems deeper inside
mock, as _set_signature is assumed to always return a mock, and
nothing checked its return value.

In similar corner cases, autospec will simply not check the spec of the
function, so _set_signature is amended to now return early with the
original, not-wrapped mock object.

@the-knights-who-say-ni

Copy link
Copy Markdown

Hello, and thanks for your contribution!

I'm a bot set up to make sure that the project can legally accept your contribution by verifying you have signed the PSF contributor agreement (CLA).

Unfortunately we couldn't find an account corresponding to your GitHub username on bugs.python.org (b.p.o) to verify you have signed the CLA. This is necessary for legal reasons before we can look at your contribution. Please follow these steps to help rectify the issue:

  1. If you don't have an account on b.p.o, please create one
  2. Make sure your GitHub username is listed in "Your Details" at b.p.o
  3. If you have not already done so, please sign the PSF contributor agreement
  4. If you just signed the CLA, please wait at least a day and then check "Your Details" on bugs.python.org to see if your account has been marked as having signed the CLA (the delay is due to a person having to manually check your signed CLA)
  5. Reply here saying you have completed the above steps

Thanks again to your contribution and we look forward to looking at it!

@habnabit

Copy link
Copy Markdown
Contributor Author

I signed the CLA when I opened the bug on bpo last week, but my account doesn't say received still: http://bugs.python.org/user25445

@ShalbafZadeh

Copy link
Copy Markdown

@habnabit
have you added you github username to your bpo account?
i can't see it
https://bugs.python.org/user6636

@habnabit

Copy link
Copy Markdown
Contributor Author

@ShalbafZadeh that was an old account; I made a new one last week from a newer openid provider. http://bugs.python.org/user25445 is the new one, which I'm logged into now.

@ShalbafZadeh

Copy link
Copy Markdown

@habnabit seems odd

@habnabit
habnabit force-pushed the fix-mock-builtin-methods-for-cython branch from c8bc9c9 to 9148028 Compare February 11, 2017 01:47
@habnabit

Copy link
Copy Markdown
Contributor Author

Rebased and pushed, including a test fix. The third-party mock used six, and the stdlib does not include six.

@habnabit
habnabit force-pushed the fix-mock-builtin-methods-for-cython branch 2 times, most recently from e12a088 to 97bb733 Compare February 11, 2017 06:25
@habnabit

Copy link
Copy Markdown
Contributor Author

Rebased again!

@codecov

codecov Bot commented Feb 11, 2017

Copy link
Copy Markdown

Codecov Report

Merging #3 into master will increase coverage by <.01%.

@@            Coverage Diff             @@
##           master       #3      +/-   ##
==========================================
+ Coverage   82.37%   82.37%   +<.01%     
==========================================
  Files        1427     1427              
  Lines      350948   350959      +11     
==========================================
+ Hits       289088   289104      +16     
+ Misses      61860    61855       -5

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update e7ffb99...97bb733. Read the comment docs.

@berkerpeksag berkerpeksag left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't had a time to dive into the whole life cycle of _set_signature() yet, but from a quick glance it looks good to me.

@berkerpeksag

Copy link
Copy Markdown
Member

Please add an entry to Misc/NEWS. It should be in the "Library" section.

@habnabit
habnabit force-pushed the fix-mock-builtin-methods-for-cython branch from 97bb733 to c5b3653 Compare February 23, 2017 22:40
@habnabit

Copy link
Copy Markdown
Contributor Author

Okay, rebased and added a NEWS entry.

@Yhg1s

Yhg1s commented May 22, 2017

Copy link
Copy Markdown
Member

This change looks good to me: returning None does not make sense in the one place where _set_signature is called, and I don't think there's a better solution here. If the code wants to try harder and figure out what signature to use, that would be a change to _get_signature, not _set_signature, and this change would still make sense.

@voidspace, do you want to take a look, or can we merge?

@buhtz

buhtz commented Jul 19, 2017

Copy link
Copy Markdown

Can we merge this?

habnabit and others added 2 commits July 20, 2017 02:33
Cython will, in the right circumstances, offer a MethodType instance
where im_func is a builtin function. Any instance of MethodType is
automatically assumed to be a python-defined function (more
specifically, a function that has an inspectable signature), but
_set_signature was still conservative in its assumptions. As a result
_set_signature would return early with None instead of a mock since the
im_func had no inspectable signature. This causes problems deeper inside
mock, as _set_signature is assumed to _always_ return a mock, and
nothing checked its return value.

In similar corner cases, autospec will simply not check the spec of the
function, so _set_signature is amended to now return early with the
original, not-wrapped mock object.
@berkerpeksag
berkerpeksag force-pushed the fix-mock-builtin-methods-for-cython branch from 75ad0f4 to 989e99a Compare July 19, 2017 23:35
@berkerpeksag
berkerpeksag merged commit 856cbcc into python:master Jul 20, 2017
SonicField added a commit to SonicField/cpython that referenced this pull request Apr 22, 2026
Per pythia python#79 python#3 [chat L2032] + supervisor [chat L2034] assignment:
the brace-counted scan methodology that produced 100/123 = 81.3%
Tier 5 close ratio existed only in chat history (D-1776880902). Anyone
re-grepping in two weeks reproduces the same /144-class lapse.

This script anchors the methodology in repo:
  - Brace-balanced extraction of HIRBuilder::emit* method definitions
    (multi-line signatures + any return type + balanced { } body)
  - Categorization: stub (≤8 body lines + has hir_builder_emit_*_c call) /
    partial (>8 body lines + has C call) / pure C++ (no C call)
  - Output: counts + exhaustive pure-C++ + partial method lists

Reference values verified at HEAD a642405 (post-Tier-5-close, push 62):
  TOTAL: 123
  STUBS: 93
  PARTIAL: 7
  PURE C++: 23
  RATIO: 100/123 = 81.3%

Closes pythia python#79 python#3 'methodology not committed to repo' substance.
Anyone running scripts/count_emit_methods.sh reproduces the canonical
baseline without needing chat-search or external memory.

Origin lessons embedded in script header:
  - /144 propagated 2026-04-21 (commit 7783df7) → 2026-04-22 Tier 5 close
  - Real denominator at HEAD a642405 was 123 (pythia python#78 python#1 catch)
  - Methodology lives in repo, not chat

Authorization chain:
  - pythia python#79 python#3 surfaced gap: chat L2032
  - supervisor python#3 assignment: chat L2034
SonicField added a commit to SonicField/cpython that referenced this pull request Apr 22, 2026
Per W25 spec §3 Step B + theologian L2189 4-class taxonomy. B-1 batch
(~10 lint-pattern externs across 3 small TUs) per spec §3 sequencing
(B-0 cfg.cpp d0e8031 validated Class C2 pattern; B-1 scales to
Class A + Class C2 mix).

PER-TU CLASS CLASSIFICATION + CLEANUP:

  ssaify_c.c (1 lint extern):
    hir_func_alloc_register → Class A (hir_c_api.h:52)
    Fix: add #include hir_c_api.h, delete local extern.
    Kept non-lint externs (hir_reflow_types, hir_phi_elimination_run)
    as out-of-W25-scope; tracked separately.

  licm_c.c (3 lint externs):
    hir_func_cfg_ptr → Class C2 (hir_instr_c.h:232 static inline,
      already included via hir_instr_c.h)
    hir_instr_unlink → Class A (hir_c_api.h)
    hir_c_insert_before → Class A (hir_c_api.h:726)
    Fix: add #include hir_c_api.h, delete 3 lint externs.
    Kept hir_reg_instr (non-lint) as out-of-scope.

  resolve_kwargs_c.c (5 lint externs):
    hir_func_cfg_ptr → Class C2 (already accessible)
    hir_instr_replace_with → Class A
    hir_c_create_vectorcall_reg → Class A
    hir_c_create_call_method_reg → Class A
    hir_c_copy_frame_state → Class A
    Fix: add #include hir_c_api.h, delete 5 lint externs + duplicate
    typedef HirFunction (already in hir_c_api.h).
    Kept hir_register_type (non-lint) as out-of-scope.

DIFF: +7/-13 across 3 files (lint extern reduction without API expansion).

DEFERRED to B-2: hir_basic_block_c.c (Class C1 — hir_bb_destroy not
in any header). Needs API-expansion decision before deletion.

PER GATEITEM python#3 HARDENING (post L2174 lapse):
  testkeeper to verify post-commit, working tree clean. Both HEAD-match
  AND tree-clean must hold for valid PASS report.

Authorization chain:
  - W25 spec §3 + 4-class taxonomy: theologian L2017 + L2189
  - B-1 sequencing per supervisor [chat L2179]
  - QUERY-BEFORE-PIVOT discipline applied to scope decisions
SonicField added a commit to SonicField/cpython that referenced this pull request Apr 22, 2026
Per theologian L2430 INVOKE_* Phase 2 spec.

Changes:
  - Python/jit/hir/builder_emit_c.c: new C body
    hir_builder_emit_invoke_function_c (~115 lines). Mirrors C++
    emitInvokeFunction with three paths (A/B/C):
    - Path A: container_is_immutable + is_function + is_statically_typed
      → direct InvokeStaticFunction emit (no VectorCall fallback)
    - Path B: container_is_immutable + is_builtin → tryEmitDirectMethodCall
      fast path
    - Path C: VectorCall fallback (or patchable LoadFunctionIndirect path)

    PY_VERSION_HEX >= 0x030C0000 conditional for __static__.rand
    special-case folded into hir_builder_is_static_rand_and_try_emit_c
    bridge (version-guarded inside the bridge, no #if in C body).

  - Python/jit/hir/builder.cpp: HIRBuilder::emitInvokeFunction becomes
    a 7-line delegation stub. Adds 4 NEW C bridges (function-target
    variants of python#2 bridges, since invokeFunctionTarget != invokeMethodTarget):
    - hir_builder_invoke_function_target_c: 8-field InvokeTarget query
      (container_is_immutable, is_function, is_statically_typed, is_builtin,
      callable, func, indirect_ptr, return_type)
    - hir_builder_try_emit_direct_method_call_for_function_c: path B fast path
    - hir_builder_setup_static_args_for_function_c: arg_regs via VLA
    - hir_builder_is_static_rand_and_try_emit_c: PY_VERSION_HEX folded

  - Python/jit/hir/builder.h: extern "C" forward decls + 4 new friend
    declarations granting bridges access to private members.

C body uses C99 VLA (void *arg_regs[nargs]). CallFlags::Static = 1<<2
hardcoded as 4u (matches hir.h:881-886). Direct C calls to
hir_c_create_invoke_static_function_reg + hir_c_create_load_function_indirect_reg
+ hir_c_create_load_const + hir_c_create_vectorcall_reg (all already exist
in hir_c_api.h, no new factories needed). hir_type_from_object handles
Type::fromObject conversion in C.

Verification: cmake --build target jit/phoenix_jit clean (BUILD_EXIT=0).
Sole-path validation pending — INVOKE_FUNCTION only emitted in __static__
modules, standard test suite does not exercise.
SonicField added a commit to SonicField/cpython that referenced this pull request Apr 23, 2026
PRIMITIVE_BINARY_OP (Static Python) opcode handler. Per W27a Step A scope.

C body: hir_builder_emit_primitive_binary_op_c (~75 lines incl static
helpers inlined). Inlines get_primitive_bin_op_kind (PRIM_OP_* → HIR_BOP_*
mapping) + is_double_binop (DBL variant detection) directly into a single
switch statement.

PHX_PRIM_OP_* values hard-coded to mirror cinderx/StaticPython/classloader.h:
70-90 — same pattern as builder_emit_c.c:2862 avoidance of classloader.h
in C TU (header pulls in extensive C++-cinderx surface). Static Python ABI
is stable; values unchanged across releases.

C primitives used: hir_c_create_int_binary_op + hir_c_create_double_binary_op
+ hir_builder_temps_alloc_stack (all existing).

C++ HIRBuilder::emitPrimitiveBinaryOp → 3-line delegation stub.

Verification: cmake --build target jit/phoenix_jit clean (BUILD_EXIT=0).
Sole-path validation: PRIMITIVE_BINARY_OP only in __static__ modules
(emitInvokeNative precedent caveat acknowledged).
SonicField added a commit to SonicField/cpython that referenced this pull request Apr 23, 2026
PRIMITIVE_COMPARE_OP (Static Python) opcode handler. Per W27a Step A scope.

C body: hir_builder_emit_primitive_compare_c (~50 lines). Inlines the
PRIM_OP_* → HIR_PCMP_* mapping switch directly. Reuses PHX_PRIM_OP_*
defines from python#3 (emitPrimitiveBinaryOp).

C primitives used: hir_c_create_primitive_compare + hir_builder_temps_alloc_stack
(both existing).

C++ HIRBuilder::emitPrimitiveCompare → 3-line delegation stub.

Verification: cmake --build target jit/phoenix_jit clean (BUILD_EXIT=0).
SonicField added a commit to SonicField/cpython that referenced this pull request Apr 23, 2026
BUILD_CHECKED_LIST (Static Python) opcode handler. Per W27b Step A scope.

C body: hir_builder_emit_build_checked_list_c (~25 lines). Pops descr +
list_size from const_arg tuple, queries preloader type+py_type via
existing bridges, emits make_checked_list_reg, fills operands right-to-left
from stack.

Includes added: cinderx/StaticPython/checked_list.h (Ci_CheckedList_TypeCheck).
Header verified C-safe: Ci_CHECKED_LIST_H guard (unique), no Py_OPCODE_H
collision (theologian L2515 caveat satisfied).

C primitives used: hir_builder_preloader_type + hir_builder_preloader_py_type
+ hir_c_create_make_checked_list_reg + hir_c_set_operand
+ hir_builder_temps_alloc_stack (all existing).

C++ HIRBuilder::emitBuildCheckedList → 3-line delegation stub.

Verification: cmake --build target jit/phoenix_jit clean (BUILD_EXIT=0).
SonicField added a commit to SonicField/cpython that referenced this pull request Apr 23, 2026
Helper for emitSetupWith + emitBeforeWith. Per W27c Step A scope.

C body: hir_builder_emit_setup_with_common_c (~45 lines). Pops manager,
allocates enter+exit, emits load_attr_special_reg for both, pushes exit,
allocates enter_result, emits vectorcall_reg with CallFlags::None=0u,
sets enter as operand 0, sets frame state, emits.

PY_VERSION_HEX conditional (_Py_Identifier vs PyObject*) folded into C++
stub: ids are passed as opaque void* downward. is_async drives error
message text selection.

NEW BRIDGE: hir_builder_emit_setup_with_common_c — out-param returns
enter_result via void**.

C primitives used: hir_c_create_load_attr_special_reg + hir_c_create_vectorcall_reg
+ hir_c_set_operand + hir_deopt_set_frame_state + hir_builder_temps_alloc_stack
(all existing).

C++ HIRBuilder::emitSetupWithCommon → 6-line bridge stub returning
Register* via cast of out-param.

Verification: cmake --build target jit/phoenix_jit clean (BUILD_EXIT=0).
This is the chain-dep root for W27c python#2 (SetupWith) + python#3 (BeforeWith).
SonicField added a commit to SonicField/cpython that referenced this pull request Apr 23, 2026
BEFORE_WITH/BEFORE_ASYNC_WITH (3.12+) + pre-3.12 BEFORE_ASYNC_WITH opcode
handler. Per W27c Step A scope.

C body: hir_builder_emit_before_with_c (~17 lines). Calls SetupWithCommon
helper (W27c python#1) → push enter_result. Simpler than SetupWith — no
SetupFinally call.

PY_VERSION_HEX + opcode-branch conditional folded into C++ stub:
  - pre-3.12: __aenter__/__aexit__, is_async=1
  - 3.12+ BEFORE_ASYNC_WITH: __aenter__/__aexit__, is_async=1
  - 3.12+ BEFORE_WITH: __enter__/__exit__, is_async=0

ZERO new bridges (uses W27c python#1 helper).

C++ HIRBuilder::emitBeforeWith → ~25-line stub (PY_VERSION_HEX + opcode
branch + delegation).

Verification: cmake --build target jit/phoenix_jit clean (BUILD_EXIT=0).
SonicField added a commit to SonicField/cpython that referenced this pull request Apr 23, 2026
MATCH_CLASS (mainline) opcode handler. Per W27d Step A scope.

C body: hir_builder_emit_match_class_c (~70 lines). Pops names/type/subject.
Loads nargs as TCUInt64 const. Emits MatchClass → attrs_tuple. Refines to
TOptTupleExact = TTupleExact|TNullptr (constructed via hir_type_union per
theologian L2544 fallback — HIR_TYPE_OPTTUPLEEXACT not defined). Cond-branch:
true_block refines to TTupleExact + (pre-3.12) loads Py_True; false_block
emits CheckErrOccurred + (pre-3.12 Py_False+assign-subject; 3.12+ Py_None
+assign-none). Converges at done.

ZERO new bridges.

C primitives: hir_c_create_load_const + hir_c_create_match_class_reg2 +
hir_c_create_refine_type_reg + hir_c_create_cond_branch +
hir_c_create_check_err_occurred_reg + hir_c_create_assign_reg +
hir_c_create_branch_cpp + hir_type_from_cuint + hir_type_union +
hir_type_from_object + hir_func_alloc_register + hir_cfg_alloc_block
+ hir_builder_temps_alloc_stack (all existing).

C++ HIRBuilder::emitMatchClass → 4-line delegation stub.

Verification: cmake --build target jit/phoenix_jit clean (BUILD_EXIT=0).
Sole-path: MATCH_CLASS is mainline-tested per theologian L2544
coverage observation.
SonicField added a commit to SonicField/cpython that referenced this pull request Apr 23, 2026
…ERO C++

SEQUENCE_GET (Static Python) opcode handler. FINAL emit-method conversion
in W27 burndown. Per W27d Step A scope.

C body: hir_builder_emit_sequence_get_c (~85 lines). Same shape as
emitSequenceSet (W27c python#5) + SEQ_SUBSCR_UNCHECKED bit gating + emitLoadArrayItem
(vs StoreArrayItem):
  - oparg & SEQ_SUBSCR_UNCHECKED set → skip CheckSequenceBounds, raw idx
  - else CheckSequenceBounds + adjusted_idx
  - Per (oparg & ~UNCHECKED): SEQ_LIST/INEXACT/CHECKED_LIST → load_field
    'ob_item' at PyListObject offset + TCPtr; SEQ_ARRAY_INT64 → load_const
    offset + load_field_address
  - LoadArrayItem with element_type_from_seq_type(oparg)

PHX_SEQ_SUBSCR_UNCHECKED = (1<<3) = 8 hard-coded inline.
PHX_SEQ_* base values reused from W27c python#5 (PHX_SEQ_LIST/TUPLE/LIST_INEXACT/
CHECKED_LIST/ARRAY_INT64).

ZERO new bridges.

C primitives: hir_c_create_load_field_reg + hir_c_create_guard_is_reg +
hir_c_create_refine_type_reg + hir_c_create_check_seq_bounds_reg +
hir_c_create_load_field_address_reg + hir_c_create_load_array_item_reg +
hir_c_create_load_const + hir_type_from_cint +
hir_builder_temps_alloc_stack (all existing).

C++ HIRBuilder::emitSequenceGet → 4-line delegation stub.

Verification: cmake --build target jit/phoenix_jit clean (BUILD_EXIT=0).
Sole-path: SEQUENCE_GET is __static__-only per accepted-residual L2531.

🎯 W27d CLOSURE — ZERO C++ ACHIEVED for emit-methods:
  W27d python#1: emitCopyFreeVars
  W27d python#2: emitGetYieldFromIter
  W27d python#3: emitMatchClass
  W27d python#4: emitMatchMappingSequence
  W27d python#5: emitSequenceGet (THIS)

Pure-C++ count: 5 → 0 / 123 (100% per scripts/count_emit_methods.sh).
Total W27 burndown: 20 → 0 across 4 batches (W27a/b/c/d).
W27e residual paragraph (theologian L2533) attached to closure announcement
to Alex (10 __static__-only methods accepted-residual per Phoenix-doesn't-
expose-Static-Python framing).
SonicField added a commit to SonicField/cpython that referenced this pull request Apr 23, 2026
Per supervisor L2565 + theologian L2569 ACK. Reduces C++ stub from
~13 lines to 8 lines (qualifies as STUB).

Strategy: change bridge convention from caller-allocates-out to
callee-allocates-out. C body of bridge now allocates 'out' internally
via hir_builder_temps_alloc_stack. Both call sites (C++ stub at
builder.cpp + C-body call from emit_any_call_c) updated to drop
the explicit out alloc.

Bridge sig change: void *out param removed (was 4th arg). Falsification
discipline: change is mechanically validated by build (callers updated
in same commit) — no signature drift surface beyond the tightening.

Verification: cmake --build target jit/phoenix_jit clean (BUILD_EXIT=0).
Pure-C++ count unchanged (still 0); PARTIAL count drops 9→8.
SonicField added a commit to SonicField/cpython that referenced this pull request Apr 23, 2026
Per supervisor [chat L2626] + L2742 + librarian L2737 (close pythia python#87
python#3 ephemera-gap durably).

Captures empirical W26 push 84 incident (95c9f9b1553c14 fix):
- Both cinder_opcode_ids.h + Include/opcode.h use Py_OPCODE_H guard
- Include order silently shadows whichever loads second
- W26 case: BINARY_OP_ADD_INT undefined → attr_probe HIR regression
  caught by W21 golden trip-wire

Three resolution options enumerated:
- (A) rename cinder_opcode_ids.h guard to CINDERX_OPCODE_IDS_H —
  recommended, eliminates collision class
- (B) static_assert in cinder_opcode.h to detect collision at compile
  — hardens detection without fixing
- (C) header-comment only — current state, NOT recommended (chat-
  ephemera proven insufficient)

Related W29 candidate noted: PHX_PRIM_OP_* / PHX_PRIM_UOP_* hard-coded
in builder_emit_c.c lines 3727-3746 with no static_assert binding to
classloader.h authoritative #defines (per pythia python#89 python#3 re-issue).

DEFERRED per supervisor — schedule post-Batch-2 burndown, before any
upstream sync touching Include/opcode.h or classloader.h.
SonicField added a commit to SonicField/cpython that referenced this pull request Apr 23, 2026
…r.cpp

Per supervisor 21:27:42Z + theologian 21:28:13Z methodology cross-check:
4 caller-search patterns (word-boundary + fn-pointer + Lib/test
substring + broad), 1 caller (FORMAT_SIMPLE bytecode dispatch at
builder.cpp:2457), argument-forwarding equivalence verified.

Caller-rewrite: FORMAT_SIMPLE case now invokes
hir_builder_emit_format_simple_c(&tc, current_func_, this) directly
instead of going through the C++ method wrapper. Extern "C" decl
hoisted to file-scope (builder.cpp:56) so the dispatch loop has
visibility before the method's original location.

Numstat (verified pre-commit per shepard 20:41:46Z + supervisor
20:16:25Z discipline):
  builder.cpp   +4/-8   (NET -4; 3-line wrapper deleted + 4-line
                          comment block deleted + 1-line extern decl
                          hoisted to file scope + 4-line comment hoist
                          NET -4 — see split below)
  builder.h     +0/-1   (NET -1; method declaration removed)

Bundle: -5L net, ZERO new bridges (existing C function + existing
extern decl, just relocated).

Pattern validated for Phase 1 batch-of-N scaling per supervisor
21:26:49Z 'Phase 1 python#3 will be batch-of-5+ aggressive across simple
1-caller methods'.

Verified at HEAD post-fix:
  test_phoenix_jit_comparisons + controlflow + autocompile +
    partial_conversions: 369/369 PASS (no regression).
  W44 DO-NOT-USE caller gate: PASS (2 markers, 0 violations).
SonicField added a commit to SonicField/cpython that referenced this pull request Apr 23, 2026
Per supervisor 21:39:13Z + theologian 21:39:06Z methodology cross-check
PASS for batch-of-5: emitBuildCheckedList + emitBuildCheckedMap +
emitSequenceGet + emitSequenceSet + emitGetYieldFromIter.

All 5 had 1 caller in builder.cpp dispatch + 0 fn-pointer + 0 Lib/test
substring (caller-search per supervisor 21:13:23Z scope: full repo + .py
+ Lib/test). All 5 were pure delegation stubs (no logic before C call).

Pattern (validated by Phase 1 python#2 emitFormatSimple precedent):
  1. Hoist extern "C" decl to file scope (builder.cpp:54-62)
  2. Rewrite caller in dispatch switch to call C function directly
  3. Delete C++ method wrapper + decl

emitBeforeWith DROPPED from batch (25-line PY_VERSION_HEX-conditional
logic violates 0-bridge constraint per theologian 21:39:06Z; defer to
single-method batch later).

emitGetYieldFromIter caller-rewrite preserves required casts per
theologian warning 21:39:06Z: static_cast<int>(co_flags) +
static_cast<void*>(&PyCoro_Type).

Numstat (verified pre-commit per shepard 20:41:46Z + supervisor
20:16:25Z discipline):
  builder.cpp   +14/-53   (NET -39; 5 wrapper bodies deleted + 5
                            extern decls migrated to file-scope
                            comment block)
  builder.h     +0/-13    (NET -13; 5 method declarations removed)

Bundle: -52L net, ZERO new bridges (all 5 C functions + extern decls
already existed; just relocated externs to file-scope).

Verified at HEAD post-fix:
  test_phoenix_jit_comparisons + controlflow + autocompile +
    partial_conversions: 369/369 PASS (no regression).
  W44 DO-NOT-USE caller gate: PASS (2 markers, 0 violations).

Phase 1 burndown advances: builder.cpp 4900→4859 (-41 lines beyond
Phase 1 python#2 baseline). Pattern repeats cleanly for next batch on the
remaining 1-caller / pure-delegation methods.
SonicField added a commit to SonicField/cpython that referenced this pull request Apr 23, 2026
…oadSpecial/MatchClass/MatchMappingSequence/Send)

Per supervisor 21:45:14Z + theologian 21:45:17Z methodology cross-check
PASS for batch-of-5: emitCopyFreeVars + emitLoadSpecial + emitMatchClass
+ emitMatchMappingSequence + emitSend.

Methods deleted (all bytecode-dispatch overloads, NOT the inline
helpers in HIRBuilder class body that share the same name with
Register*-based signatures — overload distinction verified by
theologian on disk: helper at builder.cpp:710/807/859 vs dispatch at
:4642/4679/4728).

emitSetupWith DROPPED from batch (25-line PY_VERSION_HEX-conditional
enter_id/exit_id logic = Cat-B per emitBeforeWith precedent in python#3).

6 caller-rewrites (multi-caller methods: emitCopyFreeVars × 2 at
1065+1878, emitMatchMappingSequence × 2 at 2408+2412; single-caller
methods: emitLoadSpecial+emitMatchClass+emitSend × 1 each).

Numstat (verified pre-commit per shepard 20:41:46Z + supervisor
20:16:25Z discipline):
  builder.cpp   +18/-60   (NET -42; 5 wrapper bodies + 5 inline extern
                            decls deleted, +18 from caller-rewrite
                            expansions and 5 file-scope extern decls
                            for the new C dispatch targets)
  builder.h     +0/-12    (NET -12; 5 method declarations removed)

Bundle: -54L net, ZERO new bridges (5 existing C functions reused via
file-scope extern hoists; matches Phase 1 python#3 -52L precedent).

Verified at HEAD post-fix:
  test_phoenix_jit_comparisons + controlflow + autocompile +
    partial_conversions: 369/369 PASS (no regression).
  W44 DO-NOT-USE caller gate: PASS.

Phase 1 cumulative burndown: -35 (python#1+python#1.5) + -5 (python#2) + -52 (python#3) +
-54 (python#4) = -146L total. builder.cpp 4859→4817.
SonicField added a commit to SonicField/cpython that referenced this pull request Apr 23, 2026
Per supervisor 21:54:07Z + theologian 21:53:58Z methodology cross-check
PASS for batch-of-6: emitPrimitiveLoadConst + emitPrimitiveBox +
emitPrimitiveUnbox + emitPrimitiveBinaryOp + emitPrimitiveCompare +
emitPrimitiveUnaryOp.

All 6 had 1 caller each in builder.cpp dispatch (lines 2005/2009/2013/
2017/2021/2025) + Lib/test/ scope EMPIRICALLY VERIFIED clean per
theologian 21:53:58Z (grep -E 'emitPrimitive(LoadConst|Box|Unbox|
BinaryOp|Compare|UnaryOp)' Lib/test/test_phoenix_*.py = 0 references).

Methods deleted (all bytecode-dispatch overloads). Inline helpers in
HIRBuilder class body with Register*-based signatures (lines 944, 733,
456, 978) STAY — distinct overloads. tc.emitPrimitiveBox /
tc.emitPrimitiveUnbox at lines 3875/3884 are TranslationContext class
methods (different class) — NOT affected.

6 caller-rewrites (lines 2005, 2009, 2013, 2017, 2021, 2025) at
bytecode dispatch.

Numstat (verified pre-commit per shepard 20:41:46Z + supervisor
20:16:25Z discipline + supervisor 21:54:07Z 'commit-message count = 6
caller-rewrites avoid python#4 annotation typo'):
  builder.cpp   +14/-62   (NET -48; 6 wrapper bodies + 6 inline extern
                            decls deleted, +14 from caller-rewrite
                            expansions and 6 file-scope extern decl
                            hoists)
  builder.h     +0/-18    (NET -18; 6 method declarations removed,
                            3 lines per declaration)

Bundle: -66L net, ZERO new bridges (6 existing C functions reused via
file-scope extern hoists).

Verified at HEAD post-fix:
  test_phoenix_jit_comparisons + controlflow + autocompile +
    partial_conversions: 369/369 PASS (no regression).
  W44 DO-NOT-USE caller gate: PASS (2 markers, 0 violations).

Phase 1 cumulative burndown: -35 (python#1+python#1.5) + -5 (python#2) + -52 (python#3) +
-54 (python#4) + -66 (python#5) = -212L total. builder.cpp 4817→4769.
SonicField added a commit to SonicField/cpython that referenced this pull request Apr 24, 2026
…nix.sh

Adds Step 1g per spec §2.7.3 python#3, invoking
scripts/w45_section_3_5_derivation_drift.sh --strict after Step 1e
(W44 DO-NOT-USE caller gate). Step 1f reserved for future W45 §1-§2
bridge-sig falsifier integration.

Pattern mirrors Step 1e (W44): capture output, exit code, GATE_PASS
flag, FAILURES annotation. ~15L diff.

Authorization: supervisor 00:22:51Z post-push priority (1) per spec
§2.7.3 python#3 integration step; ~10L estimate (actual 15L for output
capture + failure annotation parity with Step 1e).
SonicField added a commit to SonicField/cpython that referenced this pull request Apr 24, 2026
Theologian 01:53:41Z draft per shepard 01:53:07Z + pythia python#104 (3) +
supervisor 01:53:55Z GO. Adds proactive complement to existing gate python#3
(HEAD==binary AND tree-clean during build, REACTIVE detection at
build-symptom).

4-step discipline for multi-file (≥2) edit sequences:
1. Pre-edit baseline snapshot
2. Mid-edit integrity check (HALT on unexpected change)
3. Pre-commit verification (HALT if staged diff diverges)
4. HALT response (clean-HEAD restore + observed-but-not-attributed
   report; do NOT auto-resume)

Rationale: 5+ prior incidents caused gate failures + false BUILD PASS +
ARM64 build BLOCK (D-1775810621, D-1775669703, D-1776414469,
D-1776434533, D-1776887480/D-1776890644 per librarian 01:46:19Z).

Triggered by 01:23Z external file-state revert during Tier 8 pilot
Phase A execution (generalist 01:24:43Z observed-but-not-attributed
HALT + clean-HEAD restore demonstrated the prescribed response).

Doc-only +14L. No §3.5 BUILD MODE per touched-files rule (no
builder*.{cpp,h,c} touched).
SonicField added a commit to SonicField/cpython that referenced this pull request Apr 24, 2026
…xtension

Per supervisor 02:35:05Z (PIR redirect to theologian) + 02:37:20Z
(GO atomic commit + Tier 8 Phase A resume directive). Theologian
02:36:49Z PIR delivery + 4-section CLAUDE.md amendment.

PIR scope (docs/2026-04-24-pre-edit-revert-pir.md, 132L NEW):
  (1) Automated-detection feasibility — 3 options analyzed:
      (a) inotify file-watcher daemon: feasible but multi-session
          NBS-suite extension; DEFERRED to W48
      (b) pre-commit git hook: REJECTED (duplicates gate python#3)
      (c) agent-side mtime-checkpoint discipline: ADOPTED (~5L per
          agent edit-loop; in-session feasible)
  (2) Per-incident root-cause attribution for 5 priors + this incident:
      D-1775810621 / D-1775669703 / D-1776414469 — SYMPTOM-only
      D-1776434533 — DIRECTIVE-only (Alex 'always full commit checkouts')
      D-1776887480/D-1776890644 — GATE-hardening (gate python#3 added)
      2026-04-24T01:23Z — SYMPTOM-only (observed-but-not-attributed)
      TOTAL: 6 incidents, 0 root-cause attributions
  (3) Class CONFIRMED 'undiagnosed-recurring' (already labeled in
      CLAUDE.md amendment e8a83df per pythia python#105)

CLAUDE.md mtime-checkpoint extension (+1L net, rule 1 enhancement):
  Pre-edit baseline now also captures per-touched-file mtime via
  `stat -c %Y %n`; verify before each subsequent write within edit
  sequence. mtime mismatch = external revert; HALT. Mechanizes
  detection vs requiring agent to notice mid-edit.

Bundle scope: doc-only (PIR file + CLAUDE.md edit), no §3.5 BUILD MODE
per touched-files rule. Atomic per supervisor 02:37:20Z.

Phase 3 closure-amendment (docs/tier7-phase3-closure-summary.md)
remains STAGED on disk per theologian 02:36:49Z + supervisor 02:37:20Z
('RETRACT only on successful Phase A resume push'). NOT committed
this commit.

Tier 8 Phase A resume armed post-push 29 per supervisor 02:37:20Z
GO (R-retry) — PIR + mtime-checkpoint discipline mechanizes
recurrence detection; don't infinitely block on Alex when discipline
armed.
SonicField added a commit to SonicField/cpython that referenced this pull request Apr 24, 2026
…amendment

Per supervisor 02:48:39Z atomic doc-only bundle. Closes the
6→7 escalation triggered by Tier 8 pilot Phase A (R-retry) recurring
revert at incident python#7.

W48 spec (docs/w48-nbs-inotify-file-watcher-spec.md, +194L NEW):
  Theologian 02:48:25Z spec per W42/W44/W45 spec pattern. Elevates
  PIR §2.1 option (a) inotify file-watcher from DEFERRED to ACTIVE
  workstream. Mechanism: pyinotify daemon as NBS-suite sidecar; narrow
  watch per agent edit-set; event correlation with agent Write tool
  calls; forensic snapshot for root-cause attribution (closes
  pythia python#105 (3) zero-attribution gap).
  4-escalation history honest framing: Alex directive D-1776434533 →
  gate python#3 D-1776887480 → 4-step discipline 03a0dcb → mtime-checkpoint
  48339e2 → W48. Each progressively detective, none preventive.
  Cost ~3-5 sessions multi-session NBS-suite extension.
  Acceptance: 7 items including CLAUDE.md rule 5 addition + Tier 8
  pilot retry under W48.

PIR amendment (docs/2026-04-24-pre-edit-revert-pir.md, +21/-2):
  - Incident table: appended incident python#7 (2026-04-24T02:45Z, same
    pattern as python#6, mtime-checkpoint detected but did not prevent)
  - Conclusion: 7 incidents (was 6), 0 root cause attributions
  - NEW 'Incident python#7 ESCALATION' subsection: documents (R-retry)
    reasoning empirically INVALIDATED + pythia python#105 'fever has name'
    validated twice
  - NEW 'W48 ESCALATION' subsection: cross-links W48 spec landing +
    Tier 8 pilot Phase A retry GATED on W48 landing

Doc-only bundle, no §3.5 BUILD MODE per touched-files rule. Closes
the post-incident-python#7 reactive cycle: closure-amendment shipped at
push 30 (f6328cd), W48 + PIR ship at push 31.

Authorization: theologian 02:48:25Z (W48 spec) + supervisor 02:48:39Z
(atomic bundle GO).
SonicField added a commit to SonicField/cpython that referenced this pull request Apr 24, 2026
ROOT CAUSE FIX for the 8-incident undiagnosed-recurring file-state
revert class (D-1776998268 + 7 priors).

Per supervisor 04:14:27Z post-incident-python#8 ROOT CAUSE IDENTIFICATION:
the §3.5 falsifier's restore_files() trap was the "external reverter"
across all 8 incidents. It ran `git checkout HEAD --` on TOUCHED_FILES
on script exit; if those files had unstaged modifications BEFORE the
script ran (e.g., agent's in-flight Tier 8 Phase A content), the trap
blew them away.

Empirical validation (this session 04:13:36Z):
- Test python#6 + python#7 (trivial content, single-mechanism): no revert
- Tests python#5/python#7 idle: no revert
- cmake build alone: no revert
- §3.5 invocation on staged Phase A: REVERT (PhxExceptionTable
  count 13 → 0; mtime bumped 1777002918 → 1777003987; builder_state_c.h
  no longer M in git status)

8 prior incidents now retroactively attributed to §3.5 trap firing
during build/gate cycles concurrent with agent Tier 8 attempts.
NO external actor (no VS Code, no Alex, no formatter, no cron).
W48 inotify daemon NOT NEEDED. (Iso-A) host relocation NOT NEEDED.
Class size CLOSED — class type changed from "undiagnosed-recurring"
to "self-inflicted via §3.5 trap, RESOLVED".

Fix mechanism: snapshot per-file content to /tmp on first
snapshot_file_if_new() call (per fixture mutation start). restore_files()
copies from snapshot (not HEAD), preserving pre-script unstaged state.
Snapshots cleaned + FILE_SNAPSHOTS array unset post-restore.

Re-validation (this session post-fix):
- §3.5 BUILD MODE 4/4 PASS
- post-restore build [OK]
- Phase A content (PhxExceptionTable count 13) SURVIVED §3.5 invocation
- ALL 6 Tier 8 staged files still M

Doc-only (script-only) push, no §3.5 BUILD MODE per touched-files rule
(this IS the §3.5 script being amended; meta-circular but doc-only
gate appropriate).

Authorization: supervisor 04:14:27Z FIX directive post-ROOT-CAUSE
identification (generalist 04:13:58Z catch).

Pythia python#105 'fever has name infection still spreads' was structurally
correct re self-inflicted infrastructure — but the infection wasn't
external-class undiagnosable; it was OUR OWN script's exit trap
trampling unstaged work. 5 detection layers (Alex directive D-1776434533,
gate python#3 D-1776887480, 4-step Pre-Edit WT Integrity D-1776995670,
mtime-checkpoint D-1776998268, W48 spec D-1776999077) added to detect
ourselves. Audit own scripts BEFORE external-actor hypotheses (per
new feedback memory entry).
@chongwick chongwick mentioned this pull request Aug 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants