From 82b788b90b2944c73775d50d550363adad312964 Mon Sep 17 00:00:00 2001 From: RayPals Date: Fri, 18 Sep 2026 15:57:19 +0000 Subject: [PATCH] port: advance MSVC600 Python core frontier --- PORT_STATUS.md | 2013 ++++++++- .../msvc600/cpython-3.11.16-vc6-headers.patch | 3760 ++++++++++++++++- scripts/vc6-probe-pythoncore-frontier.sh | 4 + scripts/vc6-probe-pythoncore-frontier.test.sh | 2328 ++++++++++ 4 files changed, 8103 insertions(+), 2 deletions(-) diff --git a/PORT_STATUS.md b/PORT_STATUS.md index f5a9b42..a60f250 100644 --- a/PORT_STATUS.md +++ b/PORT_STATUS.md @@ -1,6 +1,2017 @@ # Port Status — CPython 3.11.16 to Windows 98 SE -Date: 2026-08-22 +## Latest revision (`faulthandler.c` VC6 declaration/API compatibility slices) + +Date: 2026-09-18 16:03 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c878260a8a4549`. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`. + +This continuation cleared the remaining reported `faulthandler.c` compile errors without changing its core control flow: + +- Converted Windows exception-handler, traceback, disable-loop, and SIGFPE locals to VC6/C89 declaration order. +- Guarded abort behavior flags unavailable in the MSVC6 CRT. +- Replaced the `Py_FatalError` use that expands through unsupported `__func__` with an explicit `_Py_FatalErrorFunc` call. +- Replaced the `faulthandler` module's designated initializer with positional fields. +- Hoisted `faulthandler_init_enable()` locals. + +**Exact verified result:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` | exit 2; summary `total=31 compiled=30 cached=0 skipped=0` | +| Current first blocker | `cpython/Modules/gcmodule.c` | + +The next file contains many independent C89 declaration-order and control-flow failures, including errors around lines 1456, 1530, 1600, 1681, 1686, and 1714. No speculative broad edit was made. + +This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`_datetime_exec`, datetime module definition, and errno VC6 slice) + +Date: 2026-09-18 15:44 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c878260a8a4549`. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`. + +This slice advanced the real pythoncore compile frontier from 27 to 29 compiled sources. It addressed only bounded VC6 compatibility families: + +- `cpython/Modules/_datetimemodule.c`: hoisted all `_datetime_exec()` locals before executable statements, preserved initializer/evaluation order, and replaced the module definition's C99 designated initializer with declared-order positional fields. +- `cpython/Modules/errnomodule.c`: converted `_add_errcode()` and `errno_exec()` mixed declarations to C89 declaration order and replaced `errnomodule`'s designated module initializer with positional fields. +- `scripts/vc6-probe-pythoncore-frontier.test.sh`: added regression coverage for `_datetime_exec()`'s declaration family. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch`: must be regenerated from the complete nested diff after this status update. + +**Exact verified results:** + +| Command | Result | +|---|---| +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` | exit 0; `ALL TESTS PASSED` | +| `bash -n` on frontier scripts plus existing probe/core/pathcch/getpath/stdint regression suites | exit 0; all applicable suites passed | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` | exit 2; summary `total=30 compiled=29 cached=0 skipped=0` | +| Current first blocker | `cpython/Modules/faulthandler.c` | + +The next file is not a single narrow defect: the probe reports multiple independent MSVC6/Win9x issues in `faulthandler.c`, including C99 loop/mixed declarations, missing `_WRITE_ABORT_MSG` and `_CALL_REPORTFAULT`, missing `__func__`, volatile/declaration syntax failures, and a designated initializer at line 1335. No speculative broad edit was made. + +This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`datetime_fromisoformat` C89 declaration-order slice) + +Date: 2026-09-18 14:34 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c878260a8a4549`. Before changing anything, `PORT_STATUS.md`, `README.md`, and `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md` were read. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded `_blake2/blake2s_impl.c` sequence was force-re-probed first and remained applicable: `_blake2/blake2s_impl.c` compiled successfully, 27 sources compiled, and `_datetimemodule.c` remained first. The first stable diagnostics were `_datetimemodule.c(5518)` C2275/C2065 for `datetime_fromisoformat()`'s post-statement `dtstr_clean` declaration, followed by its same-function declaration-order cascades. One focused read-only Codex coding-agent delegation inspected this exact function and recommended hoisting all function-scope locals while preserving each initializer's original execution point; it exited 0, made no file changes, and ran no builds. This run addressed only that declaration-order family. + +- `cpython/Modules/_datetimemodule.c` — hoisted `datetime_fromisoformat()`'s locals into its opening declaration group and changed initialized declarations to assignments at their original execution points. Sanitization, UTF-8 conversion, separator detection, parsing, cleanup labels, reference counting, and return behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the C89-safe declaration group, original-point assignments, and rejection of mixed declarations. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; `_blake2/blake2s_impl.c` compiled, 27 sources compiled, and first stable diagnostics were `_datetimemodule.c(5518)` C2275/C2065 for `dtstr_clean`; summary `total=28 compiled=27 cached=0 skipped=0`. | +| focused read-only `codex exec -s read-only --skip-git-repo-check ...` | exit 0; recommended the minimal `datetime_fromisoformat()` hoist and original-point assignments; no files changed and no builds run by the child. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `datetime_fromisoformat declaration missing from opening group: PyObject *dtstr_clean;`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; `datetime_fromisoformat()` compiled past this family. The next first stable diagnostics are `_datetimemodule.c(6814)` C2275/C2065/C2059 for `_datetime_exec()`'s post-statement `PyTypeObject *types[]` declaration, followed by its C99 loop declaration; later distinct mixed declarations remain at `(6847)` and `(6875)`, and a designated initializer remains at `(7013)`. Summary `total=28 compiled=27 cached=0 skipped=0`. Existing C4761 warnings remain in `arraymodule.c(2247)` and `audioop.c(1536)`, `(1609)`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh` | exit 0; all applicable regression suites and shell syntax checks passed; the focused frontier suite ended with `ALL TESTS PASSED`. | +| `git -C cpython diff --check`; `cmp -s <(git -C cpython diff) compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; source diff is clean and the compatibility patch exactly matches the nested source diff. | + +**Current compile-frontier state:** `datetime_fromisoformat()` now compiles past its C89 declaration-order family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is `_datetime_exec()` at `_datetimemodule.c(6814)`, beginning with the `types[]` declaration after executable statements. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`_datetimemodule.c` VC6 64-bit spelling/literal-suffix slice) + +Date: 2026-09-18 10:17 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c878260a8a4549`. Before changing anything, `PORT_STATUS.md`, `README.md`, and `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md` were read. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded frontier was force-re-probed first and remained applicable: `_blake2/blake2s_impl.c` compiled successfully, 27 sources compiled, and `_datetimemodule.c` remained first. The first stable diagnostics were the distinct VC6 `long long`/C99 literal-suffix family at `_datetimemodule.c(5053)`–`(5074)`, followed by later declaration-order diagnostics. The required focused coding-agent delegation was attempted but could not launch because the runtime lacks the `anthropic` package; no child changes or independent review are claimed. This run addressed only the 64-bit spelling/literal-suffix family. + +- `cpython/Modules/_datetimemodule.c` — replaced this file's `long long` declarations with CPython's `PY_LONG_LONG` abstraction and its `LL` epoch literals with `PY_LL(719163)`. Arithmetic, ranges, control flow, and API behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion rejecting `long long`/`719163LL` and requiring `PY_LONG_LONG`/`PY_LL`. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; `_blake2/blake2s_impl.c` compiled, 27 sources compiled, and first stable diagnostics were `_datetimemodule.c(5053)`–`(5057)` C2632/C2059/C2146/C2143 for `long long` and `LL`, with later cascades; summary `total=28 compiled=27 cached=0 skipped=0`. | +| focused coding-agent delegation | failed before launch: `The 'anthropic' package is required for the Anthropic provider`; no child files were used and no independent review is claimed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `_datetimemodule long long keyword remains`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; `_datetimemodule.c` compiled past the 64-bit spelling/literal-suffix family. The next first stable diagnostics are `_datetimemodule.c(5355)`/`(5356)` C2143 declaration-order errors; summary `total=28 compiled=27 cached=0 skipped=0`. Existing C4761 warnings remain in `arraymodule.c(2247)` and `audioop.c(1536)`, `(1609)`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0; all applicable regression suites, source checks, and nested source diff checks passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch`; `cmp -s <(git -C cpython diff) compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; compatibility patch regenerated and exactly matches the complete nested source diff. | + +**Current compile-frontier state:** `_datetimemodule.c` now compiles past its VC6 `long long`/literal-suffix family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the distinct C89 declaration-order family beginning at `_datetimemodule.c(5355)`. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`_datetimemodule.c` `time_fromisoformat` C89 declaration-order slice) + +Date: 2026-09-18 08:10 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c878260a8a4549`. Before changing anything, `PORT_STATUS.md`, `README.md`, and `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md` were read. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded frontier was force-re-probed first and remained applicable: `_blake2/blake2s_impl.c` compiled successfully, 27 sources compiled, and `_datetimemodule.c` remained first. The first stable diagnostics were `_datetimemodule.c(4699)` C2275/C2146/C2065 for `time_fromisoformat()`'s post-statement `Py_ssize_t len` declaration, followed by the same function's later locals. One focused read-only Codex coding-agent delegation inspected this exact function and recommended hoisting `len`, `p`, the integer locals, `tzinfo`, and `t` while preserving each initializer's original execution point; it made no file changes and ran no builds. This run addressed only that declaration-order family. + +- `cpython/Modules/_datetimemodule.c` — hoisted `time_fromisoformat()` locals into its opening declaration group and changed the UTF-8 conversion, zero initialization, parser call, and timezone construction declarations into assignments at their original execution points. Parsing, error labels, reference counting, and return behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the C89-safe declarations and assignment sequence. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; `_blake2/blake2s_impl.c` compiled, 27 sources compiled, and first stable diagnostic `_datetimemodule.c(4699) C2275/C2146/C2065` for `Py_ssize_t len`; summary `total=28 compiled=27 cached=0 skipped=0`. | +| focused read-only `codex exec -s read-only --skip-git-repo-check ...` | exit 0; recommended the minimal `time_fromisoformat()` declaration hoist and original-point assignments; no files changed and no builds run by the child. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `time_fromisoformat declaration missing from opening group: Py_ssize_t len;`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; `time_fromisoformat()` compiled past this declaration-order family. The next first stable diagnostics are the distinct `long long`/literal-suffix family at `_datetimemodule.c(5053)`–`(5057)`; summary `total=28 compiled=27 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0; all applicable regression suites, source checks, and nested source diff checks passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch`; `cmp -s <(git -C cpython diff) compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; compatibility patch regenerated and exactly matches the complete nested source diff. | + +**Current compile-frontier state:** `time_fromisoformat()` now compiles past its C89 declaration-order family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the distinct `_datetimemodule.c(5053)` `long long`/integer-literal-suffix family. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`_datetimemodule.c` `date_isocalendar` C89 result-local slice) + +Date: 2026-09-18 06:02 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c878260a8a4549`. Before changing anything, `PORT_STATUS.md`, `README.md`, and `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md` were read. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded `_blake2/blake2s_impl.c` sequence was force-re-probed first and remained applicable: 27 sources compiled, with `_datetimemodule.c` still first. The first stable diagnostics were `_datetimemodule.c(3513) C2275/C2065` for `date_isocalendar()`'s post-statement `PyObject* v` declaration. One focused coding-agent delegation was attempted as required but failed before launch because the runtime lacks the `anthropic` package; no child files were used and no independent review is claimed. This run addressed only that C89 declaration-order family. + +- `cpython/Modules/_datetimemodule.c` — hoisted `PyObject* v` into `date_isocalendar()`'s opening declaration group and changed only the constructor declaration initializer to an assignment at the original call site. ISO calendar calculation, NULL handling, and return behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the opening declaration and constructor assignment. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 27 sources compiled; first stable diagnostics `_datetimemodule.c(3513) C2275/C2065` for `PyObject* v`; summary `total=28 compiled=27 cached=0 skipped=0`. Existing warnings remained at `arraymodule.c(2247)` and `audioop.c(1536)`, `(1609)` C4761. | +| focused coding-agent delegation | failed before launch: `The 'anthropic' package is required for the Anthropic provider`; no child files were used and no independent review is claimed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `date_isocalendar v declaration missing from opening group`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; `date_isocalendar()` compiled past this defect family. The next first stable diagnostics are `_datetimemodule.c(4699)` C2275/C2146/C2065 for a distinct declaration-order family; summary `total=28 compiled=27 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0; all applicable regression suites and source checks passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch`; `cmp -s <(git -C cpython diff) compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; compatibility patch regenerated and exactly matches the complete nested source diff. | + +**Current compile-frontier state:** `date_isocalendar()` now compiles past its C89 declaration-order family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is `_datetimemodule.c(4699)`, a distinct declaration-order family. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`_datetimemodule.c` `PyDateTime_IsoCalendarDateType` positional-initializer slice) + +Date: 2026-09-18 03:54 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c878260a8a4549`. Before changing anything, `PORT_STATUS.md`, `README.md`, and `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md` were read. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. The existing modifications to `scripts/vc6-probe-pythoncore-frontier.sh` and all prior CPython edits were preserved. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded frontier was force-re-probed first and remained applicable: `_blake2/blake2s_impl.c` compiled successfully, 27 sources compiled, and `_datetimemodule.c` remained first. The first stable diagnostic was `_datetimemodule.c(3426) C2059: syntax error '.'` from the designated `PyTypeObject` initializer for `PyDateTime_IsoCalendarDateType`. One focused coding-agent delegation was attempted for advisory inspection but failed before launch because the runtime lacks the `anthropic` package; no child files were used and no independent review is claimed. This run addressed only that designated-initializer family. + +- `cpython/Modules/_datetimemodule.c` — replaced only `PyDateTime_IsoCalendarDateType`'s C99 designated fields with declared-order positional `PyTypeObject` fields, matching the already-portable datetime type definitions. The type name, size, repr, flags, documentation, methods, getset, and constructor values are unchanged; previously implicit fields remain zero/NULL. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the exact positional initializer. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; `_blake2/blake2s_impl.c` compiled, 27 sources compiled, and first stable diagnostic `_datetimemodule.c(3426) C2059` for the designated initializer; summary `total=28 compiled=27 cached=0 skipped=0`. | +| focused coding-agent delegation | failed before launch: `The 'anthropic' package is required for the Anthropic provider`; no child files were used and no independent review is claimed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `iso calendar date type positional initializer mismatch`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; the designated-initializer blocker cleared and the next first stable diagnostic is `_datetimemodule.c(3513) C2275/C2065` for `PyObject* v` in `date_isocalendar()`; summary `total=28 compiled=27 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0; all applicable regression suites and source checks passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch`; `cmp -s <(git -C cpython diff) compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; compatibility patch regenerated and exactly matches the complete nested source diff. | + +**Current compile-frontier state:** `PyDateTime_IsoCalendarDateType` now compiles past its C99 designated-initializer family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the distinct post-statement `PyObject* v` declaration in `date_isocalendar()` at `_datetimemodule.c(3513)`. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`_datetimemodule.c` `iso_calendar_date_repr` C89 declaration-order slice) + +Date: 2026-09-18 01:43 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c878260a8a4549`. Before changing anything, `PORT_STATUS.md`, `README.md`, and `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md` were read. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded frontier was force-re-probed first and remained applicable: `_blake2/blake2s_impl.c` compiled successfully, 27 sources compiled, and `_datetimemodule.c` remained first. The first stable diagnostics were `_datetimemodule.c(3349)`/`(3353)` C2275/C2065 for `iso_calendar_date_repr()`'s post-statement `week`/`weekday` declarations. One focused read-only Codex delegation inspected this exact function and recommended hoisting those two declarations while preserving the lookup and NULL-check sequence; it made no file changes and ran no builds. This run addressed only that declaration-order family. + +- `cpython/Modules/_datetimemodule.c` — hoisted `PyObject* week` and `PyObject* weekday` into `iso_calendar_date_repr()`'s opening declaration group and changed their initializers to assignments at the original evaluation points. Lookup order, NULL checks, and formatting behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the C89-safe declaration and assignment shape. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; `_blake2/blake2s_impl.c` compiled, 27 sources compiled, and first stable diagnostics were `_datetimemodule.c(3349)`/`(3353)` C2275/C2065 for `week`/`weekday`; summary `total=28 compiled=27 cached=0 skipped=0`. | +| focused read-only `codex exec -s read-only --skip-git-repo-check ...` | exit 0; recommended opening declarations for `week`/`weekday` and assignments at their original lookup points; no files changed and no builds run by the child. No independent review is claimed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `iso_calendar_date_repr declaration missing from opening group: PyObject* week;`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; `iso_calendar_date_repr()` compiled past this defect family. The next first stable diagnostic is `_datetimemodule.c(3426) C2059` for the distinct designated initializer in `PyDateTime_IsoCalendarDateType`; summary `total=28 compiled=27 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check && git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch && git -C cpython diff --check` | exit 0; all applicable regression suites, source checks, and patch regeneration passed. | + +**Current compile-frontier state:** `iso_calendar_date_repr()` now compiles past its `week`/`weekday` C89 declaration-order family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the distinct designated initializer in `PyDateTime_IsoCalendarDateType` at `_datetimemodule.c(3426)`. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`_datetimemodule.c` `date_fromisocalendar` C89 declaration-order slice) + +Date: 2026-09-17 23:34 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c878260a8a4549`. Before changing anything, `PORT_STATUS.md`, `README.md`, and `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md` were read. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded frontier was force-re-probed first and remained applicable: `_blake2/blake2s_impl.c` compiled successfully, 27 sources compiled, and `_datetimemodule.c` remained first. The first stable diagnostics were `_datetimemodule.c(3152)`/`(3153)` C2143 for `date_fromisocalendar()`'s post-statement `month`/`rv` declarations. One focused read-only Codex delegation inspected this exact function and recommended hoisting the declarations while preserving the conversion call's execution point; no child files were changed and no independent review is claimed. This run addressed only that declaration-order family. + +- `cpython/Modules/_datetimemodule.c` — hoisted `int month` and `int rv` into `date_fromisocalendar()`'s opening declaration group and changed `int rv = iso_to_ymd(...)` to `rv = iso_to_ymd(...)` at the original evaluation point. The conversion call, error handling, and return behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the C89-safe declaration and assignment shape. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 27 sources compiled, including `_blake2/blake2s_impl.c`; first stable diagnostics `_datetimemodule.c(3152)`/`(3153)` C2143 and `(3156)`/`(3167)` cascades for `rv`/`month`; summary `total=28 compiled=27 cached=0 skipped=0`. | +| focused read-only `codex exec -s read-only --skip-git-repo-check ...` | exit 0; recommended opening declarations `int month; int rv;` and assignment `rv = iso_to_ymd(...)`; no files changed and no tests run by the child. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `date_fromisocalendar declaration missing from opening group: int month;`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; `date_fromisocalendar()` compiled past this defect family. The next first stable diagnostics are `_datetimemodule.c(3349)`/`(3353)` C2275/C2065 for `iso_calendar_date_repr()`'s post-statement `week`/`weekday` declarations; summary `total=28 compiled=27 cached=0`. | +| applicable regression suites and source checks | exit 0; shell syntax, public/core/PathCch/getpath/stdint/frontier suites and nested `git -C cpython diff --check` all passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; compatibility patch regenerated. | + +**Current compile-frontier state:** `date_fromisocalendar()` now compiles past its C89 declaration-order family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is `iso_calendar_date_repr()` at `_datetimemodule.c(3349)`/`(3353)`, beginning with `week`/`weekday`. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`_datetimemodule.c` `date_fromisoformat` C89 declaration-order slice) + +Date: 2026-09-17 21:27 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c878260a8a4549`. Before changing anything, `PORT_STATUS.md`, `README.md`, and `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md` were read. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded frontier was force-re-probed first and remained applicable: `_blake2/blake2s_impl.c` compiled successfully, 27 sources compiled, and `_datetimemodule.c` remained first. The first stable diagnostics were `_datetimemodule.c(3095)` for `date_fromisoformat()` declarations after executable statements. One focused Codex delegation was attempted in an isolated snapshot but failed before launch because the snapshot copy hit `Disk quota exceeded`; no child files were used and no independent review is claimed. This run addressed only the `date_fromisoformat()` declaration-order family. + +- `cpython/Modules/_datetimemodule.c` — hoisted `len`, `dt_ptr`, `year`, `month`, `day`, and `rv` into `date_fromisoformat()`'s opening declaration group. Changed `dt_ptr` and date-local initialization to assignments at their original evaluation sequence; parsing, error handling, and return behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the C89-safe declaration and assignment shape. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 27 sources compiled, including `_blake2/blake2s_impl.c`; first stable diagnostics `_datetimemodule.c(3095)` C2275/C2146/C2065 for `Py_ssize_t len`, followed by the distinct later declaration families; summary `total=28 compiled=27 cached=0 skipped=0`. | +| focused Codex delegation | exit 1 before launch: isolated snapshot copy failed with `Disk quota exceeded`; no child files were used and no independent review is claimed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `date_fromisoformat declaration missing from opening group: Py_ssize_t len;`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; `date_fromisoformat()` compiled past this defect family. The next first stable diagnostics are `_datetimemodule.c(3152)`/`(3153)` C2143 and `(3156)` C2065 for the distinct `date_fromisocalendar()` declaration family; summary `total=28 compiled=27 cached=0 skipped=0`. | +| applicable regression suites and source checks | exit 0; shell syntax, public/core/PathCch/getpath/stdint/frontier suites and nested `git -C cpython diff --check` all passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` plus diff check | exit 0; compatibility patch regenerated and nested source diff is clean. | +| pristine detached nested `cpython` worktree at commit `41388c9cb160d0886d5ca00d2e6c878260a8a4549` plus `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; patch applies cleanly; temporary verification worktree removed. | + +**Current compile-frontier state:** `date_fromisoformat()` now compiles past its C89 declaration-order family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is `date_fromisocalendar()` at `_datetimemodule.c(3152)`/`(3153)`, beginning with its post-statement `month`/`rv` declarations. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`_datetimemodule.c` `delta_repr` C89 declaration-order slice) + +Date: 2026-09-17 19:20 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c878260a8a4549`. Before changing anything, `PORT_STATUS.md`, `README.md`, and `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md` were read. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded frontier was force-re-probed first and remained applicable: 27 sources compiled, including `_blake2/blake2s_impl.c`, and `_datetimemodule.c` remained first. The first stable diagnostics were `_datetimemodule.c(2663)`/`(2670)` for `delta_repr()`'s post-statement `sep` declaration, with a later `repr` declaration at `(2697)`. One focused coding-agent delegation was attempted but failed before launch because the runtime lacks the `anthropic` package; no child files or independent review are claimed. This run addressed only the `delta_repr()` declaration-order family. + +- `cpython/Modules/_datetimemodule.c` — hoisted `const char *sep` and `PyObject *repr` into `delta_repr()`'s opening declaration group; changed their initializers to assignments at the original evaluation points. Formatting, reference counting, and return behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the C89-safe `delta_repr()` declaration and assignment shape. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 27 sources compiled, including `_blake2/blake2s_impl.c`; first stable diagnostics `_datetimemodule.c(2663)`/`(2670)` C2143/C2065 for `sep`; summary `total=28 compiled=27 cached=0 skipped=0`. | +| focused coding-agent delegation | failed before launch: `The 'anthropic' package is required for the Anthropic provider`; no child files were used and no independent review is claimed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `delta_repr declaration missing from opening group: const char *sep;`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; `delta_repr()` compiled past this defect family. The next first stable diagnostics are `_datetimemodule.c(3095)` C2275/C2146/C2065 for a distinct declaration-order family; summary `total=28 compiled=27 cached=0 skipped=0`. | +| applicable regression suites and source checks | exit 0; shell syntax, public/core/PathCch/getpath/stdint/frontier suites and nested `git -C cpython diff --check` all passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; compatibility patch regenerated and nested source diff is clean. | +| pristine detached nested `cpython` worktree at commit `41388c9cb160d0886d5ca00d2e6c878260a8a4549` plus `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; patch applies cleanly; temporary verification worktree removed. | + +**Current compile-frontier state:** `delta_repr()` now compiles past its C89 declaration-order family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is `_datetimemodule.c(3095)`, beginning with a distinct declaration-order family. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`_datetimemodule.c` `tzinfo_from_isoformat_results` C89 declaration-order slice) + +Date: 2026-09-17 17:13 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c878260a8a4549`. Before changing anything, `PORT_STATUS.md`, `README.md`, and `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md` were read. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded frontier was force-re-probed first and remained applicable: 27 sources compiled, including `_blake2/blake2s_impl.c`, and `_datetimemodule.c` was first. The first stable diagnostic was `_datetimemodule.c(1435)` for `tzinfo_from_isoformat_results()`'s post-statement `PyObject *delta` declaration. One focused coding-agent delegation was attempted but failed before launch because the runtime lacks the `anthropic` package; no child files or independent review are claimed. This run addressed only that declaration-order family. + +- `cpython/Modules/_datetimemodule.c` — hoisted `PyObject *delta` into `tzinfo_from_isoformat_results()`'s opening declaration group and changed its initializer to an assignment at the original evaluation point. Timezone construction, reference counting, error handling, and return behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the C89-safe declaration and assignment shape. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 27 sources compiled; first stable diagnostic `_datetimemodule.c(1435) C2275/C2065` for `PyObject *delta`; later cascades included distinct declaration and legacy-integer families; summary `total=28 compiled=27 cached=0 skipped=0`. | +| focused coding-agent delegation | failed before launch: `The 'anthropic' package is required for the Anthropic provider`; no child files were used and no independent review is claimed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `tzinfo_from_isoformat_results delta declaration missing from opening group`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; `tzinfo_from_isoformat_results()` compiled past this defect family. The next first stable diagnostics are `_datetimemodule.c(2663)`/`(2670)` for `sep` in a distinct declaration-order family; summary `total=28 compiled=27 cached=0 skipped=0`. | +| applicable regression tests and source checks | exit 0; shell syntax, public/core/PathCch/getpath/stdint/frontier suites and nested `git -C cpython diff --check` all passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` plus patch check | exit 0; compatibility patch regenerated and nested source diff is clean. | +| pristine detached nested `cpython` worktree at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549` plus `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; patch applies cleanly; temporary verification worktree removed. | + +**Current compile-frontier state:** `tzinfo_from_isoformat_results()` now compiles past its C89 declaration-order family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is `_datetimemodule.c(2663)`/`(2670)`, beginning with `sep`. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`_datetimemodule.c` `parse_hh_mm_ss_ff` C89 declaration-order slice) + +Date: 2026-09-17 12:59 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`. Before changing anything, `PORT_STATUS.md`, `README.md`, and `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md` were read. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded `_datetimemodule.c` frontier was force-re-probed first and remained applicable: 27 sources compiled, including `_blake2/blake2s_impl.c`, and `parse_hh_mm_ss_ff()` was first. The first stable diagnostics were C2143 declaration-order errors at `_datetimemodule.c(822)`–`(829)`, with cascades from its post-statement locals, C99 loop declaration, and later declarations. One focused read-only Codex coding-agent lane inspected this exact function and recommended the minimal behavior-preserving C89 transformation; it made no file changes and ran no build. No independent review is claimed. + +- `cpython/Modules/_datetimemodule.c` — hoisted `parse_hh_mm_ss_ff()` locals and its static correction table, replaced the nonconstant `vals` initializer with assignments, changed the loop counter and character local to C89 declaration/assignment forms, and changed fractional locals to assignments. Parsing order and return behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion for the exact C89-safe `parse_hh_mm_ss_ff()` shape. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 27 sources compiled; first stable diagnostics `_datetimemodule.c(822)`/`(823)` C2143, followed by `(824)`, `(826)`, and `(829)` declaration/loop cascades; summary `total=28 compiled=27 cached=0 skipped=0`. | +| focused read-only Codex delegation | exit 0; recommended hoisting `p`, `p_end`, `vals`, `has_separator`, `i`, `len_remains`, `to_parse`, and `correction`, explicit `vals` assignments, C89 loop/local forms, and fractional assignments; no files changed and no child build run. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `parse_hh_mm_ss_ff declaration missing from opening group: int *vals[3];`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; `parse_hh_mm_ss_ff()` compiled past its defect family. Existing warnings remain `arraymodule.c(2247)` and `audioop.c(1536)`, `(1609)` C4761. The next first stable diagnostics are `_datetimemodule.c(914)`/`(917)` for `parse_isoformat_time()`'s post-statement `rv`; summary `total=28 compiled=27 cached=0 skipped=0`. | +| applicable regression suites and source checks | exit 0; shell syntax, public/core/PathCch/getpath/stdint/frontier suites and nested `git -C cpython diff --check` all passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` plus patch check | exit 0; compatibility patch regenerated and nested source diff is clean. | +| pristine detached nested `cpython` checkout at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549` plus `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; patch applies cleanly; temporary worktree removed. | + +**Current compile-frontier state:** `parse_hh_mm_ss_ff()` now compiles past its C89 declaration-order family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is `parse_isoformat_time()` at `_datetimemodule.c(914)`, beginning with its `rv` declaration after executable statements. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`_datetimemodule.c` `parse_isoformat_date` `rv` C89 slice) + +Date: 2026-09-17 10:50 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`. Before changing anything, `PORT_STATUS.md`, `README.md`, and `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md` were read. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded frontier was force-re-probed first and remained applicable: 27 sources compiled, including `_blake2/blake2s_impl.c`, and `_datetimemodule.c` was first. The first stable diagnostics were `_datetimemodule.c(793)`/`(794)` C2143/C2065 for the distinct `rv` declaration in `parse_isoformat_date()`. One focused coding-agent delegation was attempted as required but failed before launch because the runtime lacks the `anthropic` package; no child changes or independent review are claimed. This run addressed only the `rv` declaration-order family. + +- `cpython/Modules/_datetimemodule.c` — hoisted `int rv` into `parse_isoformat_date()`'s opening declaration group and changed only its original initializer to an assignment immediately before `if (rv)`. ISO-week conversion and return behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the C89-safe `rv` declaration/assignment shape. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +|| Command | Result | +||---|---| +|| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 27 sources compiled; first stable diagnostics `_datetimemodule.c(793)`/`(794)` C2143/C2065 for `rv`; summary `total=28 compiled=27 cached=0 skipped=0`. | +|| focused coding-agent delegation | failed before launch: `The 'anthropic' package is required for the Anthropic provider`; no child files were used and no independent review is claimed. | +|| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `parse_isoformat_date rv declaration missing from opening group`. | +|| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +|| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; `_datetimemodule.c` compiled past the `rv` family. The next first stable diagnostics are `(822)`/`(823)` C2143 for `parse_hh_mm_ss_ff()` declarations; summary `total=28 compiled=27 cached=0 skipped=0`. | +|| applicable regression suites and source checks | exit 0; shell syntax, public/core/PathCch/getpath/stdint/frontier suites and nested `git -C cpython diff --check` all passed. | +|| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` plus patch check | exit 0; compatibility patch regenerated and nested source diff is clean. | +|| pristine detached nested `cpython` checkout at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549` plus `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; patch applies cleanly; temporary worktree removed. | + +**Current compile-frontier state:** `parse_isoformat_date()` now compiles past its `rv` C89 declaration-order family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the distinct `parse_hh_mm_ss_ff()` declaration-order family at `_datetimemodule.c(822)`/`(823)`. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`_datetimemodule.c` `parse_isoformat_date` ISO-week locals C89 slice) + +Date: 2026-09-17 08:44 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`. Before changing anything, `PORT_STATUS.md`, `README.md`, and `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md` were read. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded frontier was force-re-probed first and remained applicable: 27 sources compiled, including `_blake2/blake2s_impl.c`, and `_datetimemodule.c` was first. The first stable diagnostics were `_datetimemodule.c(769)`/`(770)` C2143 for `iso_week`/`iso_day`, followed by a distinct `rv` declaration at `(791)`. One focused coding-agent delegation was attempted as required but failed before launch because the runtime lacks the `anthropic` package; no child changes or independent review are claimed. This run addressed only the ISO-week local declaration family. + +- `cpython/Modules/_datetimemodule.c` — hoisted `int iso_week` and `int iso_day` into `parse_isoformat_date()`'s opening declaration group and changed only their original initializers to assignments after the `W` marker. ISO-week parsing, default-day behavior, conversion, and return behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the C89-safe ISO-week declaration/assignment shape. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 27 sources compiled; first stable diagnostics `_datetimemodule.c(769)`/`(770)` C2143 for `iso_week`/`iso_day`, followed by cascades; summary `total=28 compiled=27 cached=0 skipped=0`. | +| focused coding-agent delegation | failed before launch: `The 'anthropic' package is required for the Anthropic provider`; no child files were used and no independent review is claimed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `parse_isoformat_date ISO-week declaration missing from opening group: int iso_week;`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; `parse_isoformat_date()` compiled past the ISO-week family. The next first stable diagnostics are `_datetimemodule.c(793)`/`(794)` C2143/C2065 for the distinct `rv` declaration; summary `total=28 compiled=27 cached=0 skipped=0`. | +| applicable regression suites and source checks | exit 0; shell syntax, public/core/PathCch/getpath/stdint/frontier suites and nested `git -C cpython diff --check` all passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` plus diff check | exit 0; compatibility patch regenerated and nested source diff is clean. | +| pristine detached nested `cpython` checkout at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549` plus `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; patch applies cleanly; temporary worktree removed. | + +**Current compile-frontier state:** `parse_isoformat_date()` now compiles past its `iso_week`/`iso_day` C89 declaration-order family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the distinct `rv` declaration at `_datetimemodule.c(791)` (now observed as `(793)`/`(794)` after the hoist). This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`_datetimemodule.c` `parse_isoformat_date` C89 declaration-order slice) + +Date: 2026-09-17 06:39 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`. Before changes, `PORT_STATUS.md`, `README.md`, and `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md` were read. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded `_datetimemodule.c` frontier was force-re-probed first and remained applicable: 27 sources compiled, and the first stable diagnostics were `_datetimemodule.c(760)`/`(761)` for `parse_isoformat_date()`'s post-statement `uses_separator` declaration. One focused coding-agent delegation was attempted as required, but failed before launch because the runtime lacks the `anthropic` package; no child changes or independent review are claimed. This run addressed only that declaration-order family. + +- `cpython/Modules/_datetimemodule.c` — hoisted `unsigned char uses_separator` into `parse_isoformat_date()`'s opening declaration group and changed only its initializer to an assignment at the original evaluation point. Separator detection, pointer advancement, ISO-week handling, and return behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the C89-safe declaration/assignment shape. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 27 sources compiled; first stable diagnostics `_datetimemodule.c(760)`/`(761)` C2143/C2065 for `uses_separator`; summary `total=28 compiled=27 cached=0 skipped=0`. | +| focused coding-agent delegation | failed before launch: `The 'anthropic' package is required for the Anthropic provider`; no child files were used and no independent review is claimed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `parse_isoformat_date separator declaration missing`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; `parse_isoformat_date()` compiled past the `uses_separator` family. The next first stable diagnostics are `_datetimemodule.c(769)`/`(770)` for `iso_week`/`iso_day`, followed by `rv` and later distinct declaration families; summary `total=28 compiled=27 cached=0 skipped=0`. | +| applicable regression suites and source checks | exit 0; shell syntax, public/core/PathCch/getpath/stdint/frontier suites and nested `git -C cpython diff --check` all passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` plus diff check | exit 0; compatibility patch regenerated and nested source diff is clean. | + +**Current compile-frontier state:** `parse_isoformat_date()` now compiles past its `uses_separator` C89 declaration-order family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the distinct `iso_week`/`iso_day` declaration family at `_datetimemodule.c(769)`/`(770)`. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`_datetimemodule.c` `parse_digits` C89 loop-declaration slice) + +Date: 2026-09-17 04:31 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`. Before changes, `PORT_STATUS.md`, `README.md`, and `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md` were read. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded `_datetimemodule.c` frontier was force-re-probed first and remained applicable: 27 sources compiled, and the first stable diagnostics were `_datetimemodule.c(727)` C2143/C2065/C2059 errors from `for (size_t i = ...)`, with declaration-order cascades later in the same source. One focused coding-agent delegation was attempted as required, but failed before launch because the runtime lacks the `anthropic` package; no child changes or independent review are claimed. This run addressed only `parse_digits()`'s loop-counter declaration family. + +- `cpython/Modules/_datetimemodule.c` — hoisted `size_t i` into `parse_digits()`'s opening declaration group and changed only the `for` initializer to assignment. Digit parsing, pointer advancement, bounds check, and accumulation order are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the C89-safe loop-counter declaration and assignment. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 27 sources compiled; first stable blocker `_datetimemodule.c(727)` C2143/C2065/C2059 from the C99 loop declaration; summary `total=28 compiled=27 cached=0 skipped=0`. | +| focused coding-agent delegation | failed before launch: `The 'anthropic' package is required for the Anthropic provider`; no child files were used and no independent review is claimed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `parse_digits loop counter declaration missing`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; `parse_digits()` compiled past the line-727 loop family. The next first stable diagnostics are `_datetimemodule.c(760)`/`(761)` for `parse_isoformat_date()`'s post-statement `uses_separator` declaration, followed by later distinct declaration families; summary `total=28 compiled=27 cached=0 skipped=0`. | +| applicable regression suites and source checks | exit 0; shell syntax, public/core/PathCch/getpath/stdint/frontier suites and nested `git -C cpython diff --check` all passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` plus `git -C cpython diff --check` | exit 0; compatibility patch regenerated and nested source diff is clean. | +| pristine detached nested `cpython` worktree at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549` plus `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; patch applies cleanly; temporary worktree removed. | + +**Current compile-frontier state:** `parse_digits()` now compiles past its C89 loop-declaration family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is `parse_isoformat_date()` at `_datetimemodule.c(760)`, beginning with the `uses_separator` declaration after executable statements. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`_datetimemodule.c` `iso_to_ymd` C89 declaration-order slice) + +Date: 2026-09-17 02:25 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`. Before changes, `PORT_STATUS.md`, `README.md`, and `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md` were read. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded `cmathmodule.c` frontier was force-re-probed first and remained applicable: 27 sources compiled, and `_datetimemodule.c` was first. The first stable diagnostics were `_datetimemodule.c(422)` and `(424)` C2143 declaration-order errors for `day_1` and `day_offset`. One focused coding-agent delegation was attempted as required, but failed before launch because the runtime lacks the `anthropic` package; no child changes or independent review are claimed. This run addressed only the `iso_to_ymd()` C89 declaration-order family. + +- `cpython/Modules/_datetimemodule.c` — hoisted `day_1` and `day_offset` into the opening declaration group and changed only their later initializers to assignments. ISO-week validation, conversion order, and behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the C89-safe declaration/assignment shape. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 27 sources compiled; first stable diagnostics were `_datetimemodule.c(422)` and `(424)` C2143 declaration-order errors; summary `total=28 compiled=27 cached=0 skipped=0`. | +| focused coding-agent delegation | failed before launch: `The 'anthropic' package is required for the Anthropic provider`; no child files were used and no independent review is claimed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `iso_to_ymd declaration missing from opening group: int day_1;`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; `iso_to_ymd()` compiled past the `day_1`/`day_offset` family. The next first stable diagnostics are `_datetimemodule.c(727)` C89 `for (size_t i = ...)`, followed by declaration-order errors at `(758)` and later; summary `total=28 compiled=27 cached=0 skipped=0`. | +| applicable regression suites and source checks | exit 0; shell syntax, public/core/PathCch/getpath/stdint/frontier suites and nested `git -C cpython diff --check` all passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` plus `git -C cpython diff --check` | exit 0; compatibility patch regenerated and nested source diff is clean. | +| pristine detached `v3.11.16` temporary worktree plus `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; patch applies cleanly; temporary worktree removed. | + +**Current compile-frontier state:** `_datetimemodule.c` now compiles past `iso_to_ymd()`'s C89 declaration-order family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is `parse_digits()` at line 727, beginning with its C99 loop declaration. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`pymath.h` VC6 `Py_NAN` fallback slice) + +Date: 2026-09-17 00:17 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`. Before changes, `PORT_STATUS.md`, `README.md`, and `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md` were read. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded `cmathmodule.c` frontier was re-probed first and remained applicable: 26 sources compiled and `cmathmodule.c(380)` was the first stable diagnostic, `error C2065: 'NAN' : undeclared identifier`, caused by `Py_NAN`'s C99 `NAN` fallback in `Include/pymath.h`. One focused coding-agent delegation was attempted as required, but failed before launch because the runtime lacks the `anthropic` package; no child changes or independent review are claimed. This run addressed only the VC6 `Py_NAN` defect family. + +- `cpython/Include/pymath.h` — added an `_MSC_VER < 1300` branch defining `Py_NAN` as `(Py_HUGE_VAL * 0.0)`, retaining the existing builtin and C99 branches for other compilers. No cmath behavior or non-VC6 branch was changed. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added a focused TDD assertion requiring the VC6 fallback and retaining the C99 fallback. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 26 sources compiled; first stable diagnostic `cmathmodule.c(380) C2065: 'NAN' undeclared`; summary `total=27 compiled=26 cached=0`. | +| focused coding-agent delegation | failed before launch: `The 'anthropic' package is required for the Anthropic provider`; no child files were used and no independent review is claimed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; the new `pymath.h` fallback assertion reported `not ok`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; `cmathmodule.c` compiled past the `NAN` blocker; existing warnings remain at `arraymodule.c(2247)` and `audioop.c(1536)`, `(1609)` C4761. The next first stable diagnostics are `_datetimemodule.c(422)`/`(424)` C2143 declaration-order errors; summary `total=28 compiled=27 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0; all applicable regression suites and source checks passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` plus `git -C cpython diff --check` | exit 0; compatibility patch regenerated and nested source diff is clean. | +| pristine detached `v3.11.16` temporary worktree plus `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; patch applies cleanly; temporary worktree removed. | + +**Current compile-frontier state:** `cmathmodule.c` now compiles past the VC6 `Py_NAN`/C99 `NAN` family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is `_datetimemodule.c` at line 422, beginning with C89 declaration-order errors. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`cmathmodule.c` positional PyModuleDef initializer slice) + +Date: 2026-09-16 22:10 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`. Before changes, `PORT_STATUS.md`, `README.md`, and `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md` were read. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner is `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded `_blake2/blake2s_impl.c` sequence was re-probed first and remained applicable through `binascii.c`. The actual first stable blocker was `cmathmodule.c(380) : error C2065: 'NAN' : undeclared identifier`, with a separate later designated-initializer diagnostic at line 1417. One focused Codex read-only coding-agent delegation inspected this exact source and recommended addressing the narrower `PyModuleDef` designated-initializer family first; it made no changes and no independent review is claimed. This run addressed only that initializer family; the `NAN` blocker remains untouched. + +- `cpython/Modules/cmathmodule.c` — replaced only `cmathmodule`'s designated `PyModuleDef` fields with declared-order positional fields: name, doc, size, methods, and slots. Values and module behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the exact positional initializer and rejecting the designated form. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 26 sources compiled; first stable diagnostics were `cmathmodule.c(380) C2065: 'NAN' undeclared` and `(1417) C2059: syntax error : '.'`; summary `total=27 compiled=26 cached=0 skipped=0`. | +| focused Codex read-only delegation in `/tmp/python-win9x-codex-cmath` | exit 0; recommended the minimal positional `cmathmodule` initializer; no files changed and no tests run by the child. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `cmathmodule positional initializer mismatch`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; `cmathmodule.c` compiled past the designated-initializer blocker. The next first stable diagnostic is `cmathmodule.c(380) C2065: 'NAN' undeclared`; existing warnings remain `arraymodule.c(2247)` and `audioop.c(1536)`, `(1609)` C4761; summary `total=27 compiled=26 cached=0 skipped=0`. | +| applicable regression suites and source checks | exit 0; shell syntax, public/core/PathCch/getpath/stdint/frontier suites and `git -C cpython diff --check` all passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch && git -C cpython diff --check` | exit 0; compatibility patch regenerated and nested source diff is clean. | +| pristine detached `v3.11.16` temporary worktree plus `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; patch applies cleanly; temporary worktree removed. | + +**Current compile-frontier state:** `cmathmodule.c` now compiles past its C99 designated `PyModuleDef` initializer under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the distinct `NAN`/`Py_NAN` compatibility blocker at line 380; it was not changed speculatively. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`binascii.c` `a2b_base64` C89 declaration-order slice) + +Date: 2026-09-16 20:02 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`. Before changes, `PORT_STATUS.md`, `README.md`, and `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md` were read. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner is `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded `_blake2/blake2s_impl.c` sequence was re-probed first and remained applicable through `binascii.c`. The prior `zlib.h` blocker was bypassed narrowly by suppressing `USE_ZLIB_CRC32` for `binascii.c`; its in-tree CRC32 fallback is already present. The new first stable blocker was `binascii_a2b_base64_impl()` C89 declaration ordering at lines 393–418. One focused coding-agent delegation was attempted with Codex but failed before launch because the runtime requires the unavailable `anthropic` package; no child changes or independent review are claimed. This run addressed only the `a2b_base64` declaration family. + +- `scripts/vc6-probe-pythoncore-frontier.sh` — suppresses only `USE_ZLIB_CRC32` for `cpython/Modules/binascii.c`, keeping the external zlib dependency out of this minimal frontier while selecting binascii's existing fallback. +- `cpython/Modules/binascii.c` — hoisted the `a2b_base64` locals into the opening declaration group and changed only their initializers to assignments; decoding, error handling, allocation, and loop order are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added focused TDD assertions for the binascii define suppression and C89-safe local/assignment sequence. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 25 sources compiled; first stable diagnostic was `binascii.c(66) : fatal error C1083: Cannot open include file: 'zlib.h'`; summary `total=26 compiled=25 cached=0 skipped=0`. | +| focused Codex delegation | failed before launch: `The 'anthropic' package is required for the Anthropic provider`; no child changes were used. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the define-suppression assertion, before build-script edit | exit 1 as required by TDD; `frontier disables unavailable zlib CRC32 path for binascii.c`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after build-script edit | exit 2; binascii compiled past the zlib-header blocker; first stable diagnostics were `binascii.c(393)`–`(418)` C89 declaration errors; summary `total=27 compiled=26 cached=0 skipped=0`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the source assertion, before source edit | exit 1 as required by TDD; `a2b_base64 declaration missing from opening group: const unsigned char *ascii_data;`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; `a2b_base64` compiled past its C89 declaration family. Existing warnings remain `arraymodule.c(2247)`, `audioop.c(1536)`, and `(1609)` C4761. The next first stable diagnostics are `cmathmodule.c(380) : error C2065: 'NAN' : undeclared identifier` and `(1417) : error C2059: syntax error : '.'`; summary `total=27 compiled=26 cached=0 skipped=0`. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch && bash -n scripts/vc6-probe-pythoncore-frontier.sh scripts/vc6-probe-pythoncore-frontier.test.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0; all applicable regression suites and source checks passed. | +| pristine detached `v3.11.16` temporary worktree plus `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; patch applies cleanly; temporary worktree removed. | +| `WINEPREFIX=/home/ubuntu/.wine-win9xport wine cmd /c 'call ...\\VCVARS32.BAT && cl'` | exit 0; banner `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. Wine emitted expected headless-display warnings. | + +**Current compile-frontier state:** `binascii.c` now compiles past both the unavailable external zlib-header path and `a2b_base64`'s C89 declaration-order family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the distinct `cmathmodule.c` `NAN`/designated-initializer family at lines 380 and 1417. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + + +## Latest revision (`audioop.c` `audioop_ratecv_impl` unavailable `SIZE_MAX` slice) + +Date: 2026-09-16 17:50 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`. Before changes, `PORT_STATUS.md`, `README.md`, and `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md` were read. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner is `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded `_blake2/blake2s_impl.c` sequence was re-probed first and remained applicable: `_blake2/blake2s_impl.c`, `atexitmodule.c`, and all preceding sources compiled. The actual first stable blocker was `audioop.c(1375) : error C2065: 'SIZE_MAX' : undeclared identifier`. One focused external Codex read-only lane (`codex-cli 0.153.4`) inspected this exact defect and recommended the existing VC6-compatible `(size_t)-1` idiom; it made no changes. This run addressed only that `SIZE_MAX` defect family under the strict TDD cycle. + +- `cpython/Modules/audioop.c` — replaced only the `audioop_ratecv_impl()` allocation-overflow guard's `SIZE_MAX` operand with `((size_t)-1)`. The strict comparison, `MemoryError` path, and allocation order are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added a focused source-shape regression requiring the replacement guard, rejecting `SIZE_MAX` within `audioop_ratecv_impl()`, and preserving the error/allocation sequence. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; `_blake2/blake2s_impl.c` and preceding sources compiled, 24 sources compiled, and first stable diagnostic was `cpython\\Modules\\audioop.c(1375) : error C2065: 'SIZE_MAX' : undeclared identifier`; summary `total=25 compiled=24 cached=0 skipped=0`. | +| `codex exec -s read-only --skip-git-repo-check ...` | exit 0; recommended replacing the guard operand with `((size_t)-1)` based on the existing `_pickle.c` precedent; no files changed and no tests were run by the child. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `audioop ratecv SIZE_MAX guard replacement missing`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; `audioop.c` compiled past the `SIZE_MAX` blocker, with existing warnings `audioop.c(1536)` and `(1609)` C4761. The next first stable diagnostic is `cpython\\Modules\\binascii.c(66) : fatal error C1083: Cannot open include file: 'zlib.h': No such file or directory`; summary `total=26 compiled=25 cached=0 skipped=0`. | +| `WINEPREFIX=/home/ubuntu/.wine-win9xport wine cmd /c 'call ...\\VCVARS32.BAT && cl'` | exit 0; banner `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. Wine emitted expected headless-display warnings. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && git -C cpython diff --check` | exit 0; all applicable regression suites and source checks passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch && git -C cpython diff --check` | exit 0; compatibility patch regenerated and nested source diff is clean. | +| pristine detached `v3.11.16` temporary worktree plus `git apply --check` | exit 0; patch applies cleanly; temporary verification worktree removed. | + +**Current compile-frontier state:** `audioop_ratecv_impl()` now compiles past its unavailable `SIZE_MAX` family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the distinct external zlib dependency at `binascii.c(66)` (`zlib.h` unavailable). This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`atexitmodule.c` `atexitmodule` positional PyModuleDef initializer slice) + +Date: 2026-09-16 15:44 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`. Before changes, `PORT_STATUS.md`, `README.md`, and `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md` were read. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded frontier was re-probed first and remained applicable: `_blake2/blake2s_impl.c` and all preceding sources compiled, 23 sources compiled total, and `atexitmodule.c` first failed at line 293 with C2059 on C99 designated fields. This run addressed only that initializer family. One focused external coding-agent lane was attempted in an isolated temporary snapshot; it failed before launch with `Error: No such file or directory (os error 2)` after the initial snapshot setup attempt also used an incorrect relative source path. No child changes or independent review are claimed. The source edit was therefore performed directly under the required TDD cycle. + +- `cpython/Modules/atexitmodule.c` — replaced only `atexitmodule`'s designated `PyModuleDef` fields with declared-order positional fields: head, name, doc, size, and methods. Values and module behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the exact positional initializer and rejecting designated fields. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; `_blake2/blake2s_impl.c` and preceding sources compiled, 23 sources compiled, and first stable diagnostic was `cpython\\Modules\\atexitmodule.c(293) : error C2059: syntax error : '.'`; summary `total=24 compiled=23 cached=0 skipped=0`. | +| focused coding-agent delegation in isolated `/tmp/python-win9x-codex-atexit` snapshot | failed before launch with `Error: No such file or directory (os error 2)`; no child files were used and no independent review is claimed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `atexitmodule positional initializer mismatch`, followed by `FAILED`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; `atexitmodule.c` compiled past the designated-initializer family. The next first stable diagnostic is `cpython\\Modules\\audioop.c(1375) : error C2065: 'SIZE_MAX' : undeclared identifier`; summary `total=25 compiled=24 cached=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh` | exit 0; all applicable regression suites and focused frontier assertions reported `ALL TESTS PASSED`. | +| `git -C cpython diff --check` | exit 0. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch && git -C cpython diff --check` | exit 0; compatibility patch regenerated and nested source diff is clean. | +| pristine detached `v3.11.16` temporary worktree plus `git apply --check` | exit 0; patch applies cleanly; temporary worktree removed. | + +**Current compile-frontier state:** `atexitmodule.c` now compiles past its C99 designated `PyModuleDef` initializer under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the distinct `SIZE_MAX` blocker in `audioop.c` at line 1375. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`atexitmodule.c` `atexit_unregister` C89 declaration-order slice) + +Date: 2026-09-16 13:37 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`. Before changes, `PORT_STATUS.md`, `README.md`, and `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md` were read. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. The required one focused coding-agent delegation was attempted but failed before launch because the runtime lacks the `anthropic` package; no child changes or independent review are claimed. + +The recorded frontier was re-probed first, but its state had advanced beyond the recorded `atexit_register()` blocker: 23 sources compiled through `atexitmodule.c`, and the actual first stable diagnostics were in `atexit_unregister()` at line 243. This run addressed only that C89 declaration-order family: the loop counter `i`, callback pointer `cb`, and comparison result `eq`. + +- `cpython/Modules/atexitmodule.c` — hoisted `int i`, `atexit_callback *cb`, and `int eq` before executable statements; changed the loop, callback lookup, and rich-comparison declarations to assignments at their original evaluation points. Unregister traversal, error handling, callback deletion, and ordering are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the three opening declarations, rejecting mixed declarations, and preserving loop/lookup/comparison assignments. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 23 sources compiled through `atexitmodule.c`; first stable diagnostics were `atexitmodule.c(243)` C2143/C2065/C2059/C2044 errors from `for (int i = ...)` and later `cb`/`eq` declarations; summary `total=24 compiled=23 cached=0 skipped=0`. | +| focused coding-agent delegation | failed before launch: `The 'anthropic' package is required for the Anthropic provider`; no child changes were used. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `atexit_unregister declaration missing from opening group: int i;`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; `atexit_unregister()` compiled past its declaration-order family. The next first stable diagnostic is `atexitmodule.c(293) C2059` for the remaining designated module initializer; summary `total=24 compiled=23 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && git -C cpython diff --check` | exit 0; all applicable regression suites and source checks passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch && git -C cpython diff --check` | exit 0; compatibility patch regenerated and nested source diff is clean. | +| pristine detached `v3.11.16` temporary worktree plus `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; patch applies cleanly; temporary worktree removed. | + +**Current compile-frontier state:** `atexit_unregister()` now compiles past its C89 declaration-order family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the separate designated initializer in `atexitmodule.c` at line 293. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`atexitmodule.c` `atexit_register` C89 declaration-order slice) + +Date: 2026-09-16 11:29 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. The required focused coding-agent delegation was attempted but failed before launch because the runtime lacks the `anthropic` package; no child changes or independent review are claimed. + +The recorded `atexitmodule.c` frontier was re-probed first and remained applicable: 23 sources compiled through `_blake2/blake2s_impl.c`, and `atexitmodule.c` was first. This run addressed only `atexit_register()`'s C89 declaration-order family. The later `atexit_clear()` loop/declaration blockers remain untouched. + +- `cpython/Modules/atexitmodule.c` — hoisted `func`, `state`, `r`, `size`, and `callback` into the function's opening declaration group; changed only declaration initializers to assignments at their original evaluation points. Registration, allocation, reference-counting, error handling, and callback ordering are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the five opening declarations, rejecting mixed declarations, and preserving assignment/reallocation order. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 23 sources compiled; first stable diagnostics were `atexitmodule.c(150)` for `PyObject *func`, followed by `atexitmodule.c(157)`, `(161)`, and `(169)` declaration-order/cascade diagnostics; summary `total=24 compiled=23 cached=0 skipped=0`. | +| focused coding-agent delegation | failed before launch: `The 'anthropic' package is required for the Anthropic provider`; no child changes or independent review are claimed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `atexit_register declaration missing from opening group: PyObject *func;`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; `atexit_register()` compiled past its declaration family. The next first stable diagnostics are `atexitmodule.c(243)` C2143/C2065/C2059 errors for the later `atexit_clear()` loop/declarations; summary `total=24 compiled=23 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && git -C cpython diff --check` | exit 0; all applicable regression suites and source checks passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch && git -C cpython diff --check` | exit 0; compatibility patch regenerated and nested source diff is clean. | +| pristine detached `v3.11.16` temporary worktree plus `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; patch applies cleanly; temporary worktree removed. | + +**Current compile-frontier state:** `atexit_register()` now compiles past its C89 declaration-order family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the distinct `atexit_clear()` blocker at `atexitmodule.c(243)`. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`atexitmodule.c` `atexit_callfuncs` mixed-declaration slice) + +Date: 2026-09-16 09:23 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. Before changes, `PORT_STATUS.md`, `README.md`, and `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md` were read. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. One focused coding-agent delegation was attempted, but failed before launch because the runtime lacks the `anthropic` package; no child changes or independent review are claimed. + +The recorded frontier was re-probed first and remained applicable: `cpython/Modules/_blake2/blake2s_impl.c` and all preceding sources compiled, 23 sources compiled total, and `atexitmodule.c` was first. This run addressed only `atexit_callfuncs()`'s post-statement `the_func`/`res` declaration family. The later `atexitmodule.c` declaration families remain untouched. + +- `cpython/Modules/atexitmodule.c` — hoisted `PyObject *the_func` and `PyObject *res` into the opening declaration group and changed only their declaration initializers to assignments at the existing callback-call point. Callback order, reference-counting, error handling, and cleanup behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the two opening-group declarations, rejecting the mixed declarations, and preserving both assignment statements. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 23 sources compiled through `_blake2/blake2s_impl.c` and `arraymodule.c`; first stable diagnostics were `atexitmodule.c(99)` C2143 and `(100)` C2275/C2065 for `the_func`/`res`; summary `total=24 compiled=23 cached=0 skipped=0`. | +| `WINEPREFIX=/home/ubuntu/.wine-win9xport wine cmd /c 'call Z:\\\\home\\\\ubuntu\\\\projects\\\\python-win9x\\\\MSVC600\\\\VC98\\\\Bin\\\\VCVARS32.BAT && cl'` | exit 0; banner `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`; Wine emitted expected headless-display warnings. | +| focused coding-agent delegation | failed before launch: `The 'anthropic' package is required for the Anthropic provider`; no child changes were used. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `atexit_callfuncs: the_func declaration missing`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; `atexit_callfuncs()` compiled past the `the_func`/`res` family. The next first stable diagnostics are `atexitmodule.c(150)` for `atexit_register()`'s mixed declaration, followed by `atexitmodule.c(157)` and later blockers; summary `total=24 compiled=23 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0; all applicable regression suites and source checks passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch && git -C cpython diff --check` | exit 0; compatibility patch regenerated and nested source diff is clean. | +| pristine detached `v3.11.16` temporary worktree plus `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; patch applies cleanly; temporary worktree removed. | + +**Current compile-frontier state:** `atexit_callfuncs()` now compiles past its mixed-declaration family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is `atexit_register()` at `atexitmodule.c(150)`. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`atexitmodule.c` C89 loop-declaration slice) + +Date: 2026-09-16 07:16 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. Before changes, `PORT_STATUS.md`, `README.md`, and `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md` were read. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded `_blake2/blake2s_impl.c` sequence was re-probed first and remained passed: 23 sources compiled through `arraymodule.c`, and `atexitmodule.c` was first. This run addressed only the C89 loop-declaration family at `atexit_cleanup()` and `atexit_callfuncs()`. One focused Codex implementation lane (`codex-cli 0.153.4`) ran in an isolated temporary snapshot; its exact two-function candidate was inspected and applied manually. No independent review is claimed. + +- `cpython/Modules/atexitmodule.c` — added opening-group `int i` declarations in `atexit_cleanup()` and `atexit_callfuncs()`, changing only the two `for` initializers to assignments. Callback cleanup/call order and behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added focused TDD assertions for both C89-safe loop forms and preserved loop sequences. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +|| Command | Result | +|---|---| +|| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; `_blake2/blake2s_impl.c` and preceding sources compiled, 23 sources compiled total, and first stable diagnostics were `atexitmodule.c(43)` and `(90)` C2143/C2065/C2059/C2044 errors from C99 `for (int i = ...)` declarations; summary `total=24 compiled=23 cached=0 skipped=0`. | +|| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `cleanup: loop counter declaration missing`. | +|| isolated `codex exec -s workspace-write --skip-git-repo-check ...` | exit 0; candidate changed only the two requested loops in `atexitmodule.c`; exact-content and whitespace checks passed; no build/runtime tests were run by the candidate. | +|| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +|| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; both loop-declaration blockers cleared. The next first stable diagnostics are `atexitmodule.c(99)`/`(100)` for post-statement `the_func`/`res` declarations, followed by later mixed declarations; summary `total=24 compiled=23 cached=0 skipped=0`. | +|| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0; all applicable regression suites and source checks passed. | +|| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch && git -C cpython diff --check` | exit 0; compatibility patch regenerated and nested source diff is clean. | +|| pristine detached `v3.11.16` temporary worktree plus `git apply --check` | exit 0; patch applies cleanly; temporary verification worktree removed. | + +**Current compile-frontier state:** `atexitmodule.c` now compiles past its two C89 loop-declaration blockers under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the separate `atexit_callfuncs()` mixed-declaration family at lines 99–100. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`arraymodule.c` `arraymodule` PyModuleDef positional-initializer slice) + +Date: 2026-09-16 05:09 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. Before changes, `PORT_STATUS.md`, `README.md`, and `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md` were read. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded `_blake2/blake2s_impl.c` sequence was re-probed first and remained passed: `_blake2/blake2s_impl.c` and the preceding sources compiled, 22 sources compiled in total, and `arraymodule.c` was first. The first stable diagnostics were the separate C99 designated initializer at `arraymodule.c(3161)`; the earlier `array_modexec()` declaration-order family was clear. One focused coding-agent delegation was attempted as required, but failed before launch because the runtime lacks the `anthropic` package; no child changes or independent review are claimed. This run addressed only the `arraymodule` PyModuleDef initializer family. + +- `cpython/Modules/arraymodule.c` — converted `arraymodule` to declared-order positional `PyModuleDef` initialization: base, name, doc, size, methods, slots, traverse, clear, and free. Values and behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the exact positional initializer and rejecting designated fields. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; `_blake2/blake2s_impl.c` and preceding sources compiled; 22 sources compiled; first stable diagnostics were `arraymodule.c(3161) C2059` for `.` and `,`; summary `total=23 compiled=22 cached=0 skipped=0`. | +| focused coding-agent delegation | failed before launch: `The 'anthropic' package is required for the Anthropic provider`; no child changes were used. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `arraymodule positional initializer mismatch`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; `arraymodule.c` compiled successfully, with existing warning `arraymodule.c(2247) C4761`; next first stable blocker is `atexitmodule.c(43)` C89 loop declarations and related mixed declarations; summary `total=24 compiled=23 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0; all applicable regression suites and source checks passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch && git -C cpython diff --check` | exit 0; compatibility patch regenerated and nested source diff is clean. | +| pristine detached `v3.11.16` temporary worktree plus `git apply --check` | exit 0; patch applies cleanly; temporary verification worktree removed. | + +**Current compile-frontier state:** `arraymodule.c` now compiles past its PyModuleDef designated-initializer family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is `atexitmodule.c(43)`, beginning with C89 loop-declaration errors. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`arraymodule.c` `array_modexec` C89 declaration-order slice) + +Date: 2026-09-16 03:01 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. Before changes, `PORT_STATUS.md`, `README.md`, and `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md` were read. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded frontier was re-probed first and remained applicable: `_blake2/blake2s_impl.c` and the preceding sources compiled, 22 sources compiled in total, and `arraymodule.c` first failed on `array_modexec()` declarations at lines 3114, 3119, and 3125. This run addressed only that C89 declaration-order family. One focused Codex implementation lane (`codex-cli 0.153.4`) ran in an isolated copy with the existing edits; its candidate was inspected and applied manually. No independent review is claimed. + +- `cpython/Modules/arraymodule.c` — hoisted `abc_mod`, `mutablesequence`, and `res` into `array_modexec()`'s opening declaration group and changed only their declaration initializers to assignments at the original evaluation points. Import, attribute lookup, registration, cleanup, and error behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion for the three C89-safe declarations and preserved assignment sequence. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 22 sources compiled; first stable diagnostics were `arraymodule.c(3114)`, `(3119)`, and `(3125)` C2275/C2065 declaration errors for `abc_mod`, `mutablesequence`, and `res`; the later designated initializer was at `(3158)`; summary `total=23 compiled=22 cached=0 skipped=0`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `array_modexec local missing from opening declaration group: PyObject *abc_mod;`. | +| isolated `codex exec -s workspace-write --skip-git-repo-check ...` | exit 0; candidate changed only the requested `array_modexec()` source block; its scope assertion passed and `git diff --check` produced no output. No candidate build or runtime tests were run. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; the three `array_modexec()` declaration blockers cleared. The next first stable diagnostics are the separate designated `arraymodule` initializer at `arraymodule.c(3161)` C2059; summary `total=23 compiled=22 cached=0 skipped=0`. | +| `bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0; all applicable regression suites and source checks passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch && git -C cpython diff --check` | exit 0; compatibility patch regenerated and nested source diff is clean. | +| pristine detached `v3.11.16` temporary worktree plus `git apply --check` | exit 0; patch applies cleanly; temporary verification worktree removed. | + +**Current compile-frontier state:** `array_modexec()` now compiles past its three C89 declaration-order blockers under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the separate designated initializer in `arraymodule` at line 3161. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`arraymodule.c` `arrayiter_spec` positional-initializer slice) + +Date: 2026-09-16 00:54 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. Before this run, `PORT_STATUS.md`, `README.md`, and `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md` were read. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded frontier was re-probed first and remained applicable: 22 sources compiled, including `_blake2/blake2s_impl.c`, and `arraymodule.c` first failed at the C99 designated initializer for `arrayiter_spec` at line 3026. This run addressed only that initializer family. The focused coding-agent delegation was attempted and failed before launch because the runtime lacks the `anthropic` package; no child changes or independent review are claimed. + +- `cpython/Modules/arraymodule.c` — converted `arrayiter_spec` to declared-order positional `PyType_Spec` initialization: name, basicsize, itemsize (`0`), flags, and slots. Values and behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion rejecting designated fields and requiring the positional field order. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 22 sources compiled; first stable diagnostic was `arraymodule.c(3026) C2059 syntax error : '.'`; later blockers were `(3113)`, `(3118)`, `(3124)`, and `(3157)`; summary `total=23 compiled=22 cached=0 skipped=0`. | +| focused coding-agent delegation | failed before launch: `The 'anthropic' package is required for the Anthropic provider`; no child changes were used. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `arrayiter_spec retains designated fields`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; the `arrayiter_spec` C2059 blocker cleared. The next first stable diagnostics are `arraymodule.c(3114)`, `(3119)`, and `(3125)` for post-statement locals in `array_modexec()`, followed by the designated `arraymodule` initializer at `(3158)`; summary `total=23 compiled=22 cached=0 skipped=0`. | +| `WINEPREFIX=/home/ubuntu/.wine-win9xport wine cmd /c 'call Z:\\\\home\\\\ubuntu\\\\projects\\\\python-win9x\\\\MSVC600\\\\VC98\\\\Bin\\\\VCVARS32.BAT && cl'` | exit 0; banner `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. Wine emitted expected headless-display warnings. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0; all applicable regression suites and source checks passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch && git -C cpython diff --check` | exit 0; compatibility patch regenerated and nested source diff is clean. | +| pristine detached `v3.11.16` temporary worktree plus `git apply --check` | exit 0; patch applies cleanly; temporary verification worktree removed. | + +**Current compile-frontier state:** `arraymodule.c` now compiles past `arrayiter_spec`'s C99 designated-initializer family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is `array_modexec()`'s post-statement `abc_mod`, `mutablesequence`, and `res` declarations at lines 3114, 3119, and 3125. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`arraymodule.c` `array_arrayiterator___reduce___impl` C89 declaration-order slice) + +Date: 2026-09-15 22:45 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. Before changes, `PORT_STATUS.md`, `README.md`, and `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md` were read. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. One focused coding-agent delegation was attempted as required, but failed before launch because the runtime lacks the `anthropic` package; no child changes or independent review are claimed. + +The current frontier was re-probed first and remained applicable: `_blake2/blake2s_impl.c` and the preceding sources compiled, 22 sources compiled in total, and `arraymodule.c` remained first. The first stable diagnostics were `arraymodule.c(2976)`/`(2978)` from `array_arrayiterator___reduce___impl()` declarations after executable statements. This run addressed only that C89 declaration-order family. The later `arrayiter_spec` designated initializer at line 3026 and module-setup blockers remain untouched. + +- `cpython/Modules/arraymodule.c` — hoisted `array_state *state` and `PyObject *func` into the opening declaration group and changed only their later declaration initializers to assignments. Lookup, assertion, iterator handling, and return behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the declaration group and preserved state lookup/func assignment sequence. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 22 sources compiled; first stable diagnostics were `arraymodule.c(2976)` C2143 and `(2978)` undeclared/cascade errors for `func`; later diagnostics included lines 2992, 3004, 3024, 3111, 3116, 3122, and 3155; summary `total=23 compiled=22 cached=0 skipped=0`. | +| focused coding-agent delegation | failed before launch: `The 'anthropic' package is required for the Anthropic provider`; no child changes were used. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after the corrected assertion, with source unchanged | exit 1 as required by TDD; `array iterator reduce state declaration missing from opening group`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; the `array_arrayiterator___reduce___impl()` C2143/undeclared-local blockers cleared. The next first stable diagnostic is `arraymodule.c(3026)` C2059 for the separate `arrayiter_spec` designated initializer; later blockers remain at 3113, 3118, 3124, and 3157; summary `total=23 compiled=22 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0; all applicable regression suites and source checks passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch && git -C cpython diff --check` | exit 0; compatibility patch regenerated and nested source diff is clean. | +| pristine detached `v3.11.16` temporary worktree plus `git apply --check` | exit 0; patch applies cleanly; temporary verification worktree removed. | +| `git diff --check` at the workspace root | exit 2 only on the generated compatibility patch's pre-existing patch-payload trailing-whitespace lines; nested `git -C cpython diff --check` remains exit 0. | + +**Current compile-frontier state:** `array_arrayiterator___reduce___impl()` now compiles past its C89 declaration-order family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the separate `arrayiter_spec` C99 designated initializer at `arraymodule.c(3026)`. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`arraymodule.c` `arrayiter_next` C89 declaration-order slice) + +Date: 2026-09-15 20:27 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`. The nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. `README.md` and the legacy-toolchain reference at `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md` were read before changes. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner is `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. One focused coding-agent delegation was attempted as required, but could not launch because the runtime lacks the `anthropic` package; no child changes or independent review are claimed. + +The recorded frontier was re-probed first and remained applicable: `_blake2/blake2s_impl.c` and the preceding sources compiled, 22 sources compiled in total, and `arraymodule.c` remained first. The first stable diagnostics were `arraymodule.c(2922)`/`(2923)` from `arrayiter_next()`'s debug-only `array_state` declaration after executable statements. This run addressed only that C89 declaration-order family. The later `array_arrayiterator___reduce___impl()` declaration at line 2976, `arrayiter_spec` designated initializer, and module-setup blockers remain untouched. + +- `cpython/Modules/arraymodule.c` — added a bare `array_state *state` to `arrayiter_next()`'s opening declaration group and changed the debug-only lookup to an assignment. The `#ifndef NDEBUG` guard, type assertion, lookup point, and iterator behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the C89-safe declaration and preserved debug lookup/assertion sequence. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 22 sources compiled; first stable diagnostics were `arraymodule.c(2922)` C2143 and `(2923)` undeclared/cascade errors for `state`; later diagnostics included lines 2975, 2991, 3023, 3110, 3115, 3121, and 3154; summary `total=23 compiled=22 cached=0 skipped=0`. | +| `WINEPREFIX=/home/ubuntu/.wine-win9xport wine cmd /c 'call Z:\\\\home\\\\ubuntu\\\\projects\\\\python-win9x\\\\MSVC600\\\\VC98\\\\Bin\\\\VCVARS32.BAT && cl'` | exit 0; banner `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. Wine emitted expected headless-display warnings. | +| focused coding-agent delegation | failed before launch: `The 'anthropic' package is required for the Anthropic provider`; no child changes were used. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; after correcting the assertion matcher, it failed with `arrayiter_next state declaration missing from opening group`. No production source was changed before the expected red result. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; the `arrayiter_next()` C2143/state blockers cleared. The next first stable diagnostics are `arraymodule.c(2976)`/`(2978)` for `array_arrayiterator___reduce___impl()`'s post-statement `array_state`/`func` declarations, followed by lines 2992, 3024, 3111, 3116, 3122, and 3155; summary `total=23 compiled=22 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0; all applicable regression suites and source checks passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch && git -C cpython diff --check` | exit 0; compatibility patch regenerated and nested source diff is clean. | +| pristine detached `v3.11.16` temporary worktree plus `git apply --check` | exit 0; patch applies cleanly; temporary verification worktree removed. | + +**Current compile-frontier state:** `arrayiter_next()` now compiles past its C89 declaration-order family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is `array_arrayiterator___reduce___impl()` at `arraymodule.c(2976)`. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`arraymodule.c` `array_spec` positional-initializer slice) + +Date: 2026-09-15 18:24 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. The relevant reference was read from `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md`. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded frontier was re-probed first and remained applicable: `_blake2/blake2s_impl.c` compiled cleanly, 22 sources compiled, and `arraymodule.c` first failed at the C99 designated initializer for `array_spec` at line 2876. This run addressed only that initializer family. One focused Codex implementation lane (`codex-cli 0.153.4`) ran in an isolated minimal copy after an initial oversized-copy attempt hit `/tmp` disk-quota exhaustion; the candidate diff was inspected and applied manually. No independent review is claimed. + +- `cpython/Modules/arraymodule.c` — converted `array_spec` to declared-order positional `PyType_Spec` initialization: name, basicsize, itemsize (`0`), flags, and slots. Values and behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion rejecting designated fields and requiring the positional field order. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; `_blake2/blake2s_impl.c` compiled cleanly, 22 sources compiled, and first stable diagnostics were `arraymodule.c(2876) C2059 syntax error : '.'`; later diagnostics included iterator declaration-order, additional designated initializers, and module-setup blockers; summary `total=23 compiled=22 cached=0 skipped=0`. | +| focused assertion after adding it, before source edit | exit 1 as required by TDD; `array_spec retains designated fields`. | +| focused Codex implementation lane in `/tmp/python-win9x-codex-array-spec` | exit 0; candidate changed only the requested `array_spec` source block, with positional fields in declared order; candidate diff was inspected before manual application. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; the `array_spec` C2059 blocker cleared. The next first stable diagnostics are `arraymodule.c(2922)`/`(2923)` for `arrayiter_next()`'s debug-only `array_state` declaration after executable statements, followed by distinct declaration, initializer, and module-setup blockers; summary `total=23 compiled=22 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0; all applicable regression suites and source checks passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch && git -C cpython diff --check` | exit 0; compatibility patch regenerated and nested source diff is clean. | +| pristine detached `v3.11.16` temporary worktree plus `git apply --check` | exit 0; patch applies cleanly; temporary worktree removed. | + +**Current compile-frontier state:** `arraymodule.c` now compiles past `array_spec`'s C99 designated-initializer family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the separate `arrayiter_next()` debug-block declaration-order family at `arraymodule.c(2922)`. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`arraymodule.c` `arraytype_doc` VC6 string-size slice) + +Date: 2026-09-15 16:14 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. The legacy-toolchain reference was read from `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md`. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded frontier was re-probed first and remained applicable: `_blake2/blake2s_impl.c` compiled cleanly, 22 sources compiled, and `arraymodule.c` remained first. The first stable diagnostic was `arraymodule.c(2830) : error C2026: string too big, trailing characters truncated` in `arraytype_doc`. This run addressed only that VC6 string-literal-size family. One focused Codex implementation lane (`codex-cli 0.153.4`) ran in an isolated `/tmp/python-win9x-codex-array-doc` copy, preserved the existing local edits, and supplied the candidate shape. The candidate was inspected and applied manually; no independent review is claimed. + +- `cpython/Modules/arraymodule.c` — split `arraytype_doc` at the existing documentation-section boundary into adjacent string literals, keeping the complete 2,340-byte documentation text and the existing `PyDoc_STRVAR`/`Py_tp_doc` behavior unchanged. The resulting literal chunks are 1,346 and 994 bytes. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added a focused TDD assertion that all literals are at most 2,048 bytes, the concatenated documentation SHA-256 remains `36d98a6261ec374e1e5ed2da654bb1c47286a2658b86c28800af1543c40f6822`, and the type documentation slot is retained. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; `_blake2/blake2s_impl.c` compiled cleanly, 22 sources compiled, and first stable diagnostics were `arraymodule.c(2830) C2026 string too big`, followed by designated-initializer, declaration-order, and module-setup blockers; summary `total=23 compiled=22 cached=0 skipped=0`. | +| `codex exec -s workspace-write --skip-git-repo-check ...` in isolated `/tmp/python-win9x-codex-array-doc` | exit 0; candidate changed only `arraymodule.c` and the focused test, reported RED exit 1 before the source split and GREEN exit 0 after it, and passed shell syntax checking. No candidate files were copied automatically. | +| focused TDD assertion in the delegated copy before source edit | exit 1 as required by TDD; `arraytype_doc exceeds VC6's 2048-byte individual string literal limit`. | +| focused TDD assertion in the delegated copy after source edit | exit 0; `ok - arraymodule arraytype_doc uses VC6-sized literals with unchanged text`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after applying the source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after the source edit | exit 2; the C2026 blocker cleared. The next first stable diagnostic is `arraymodule.c(2876) : error C2059: syntax error : '.'` for `array_spec`, followed by declaration-order and module-setup blockers; summary `total=23 compiled=22 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0; every applicable regression suite and source check reported `ALL TESTS PASSED`. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch && git -C cpython diff --check` | exit 0; compatibility patch regenerated and nested source diff is clean. | +| pristine detached `v3.11.16` temporary worktree plus `git apply --check` | exit 0; patch applies cleanly; temporary worktree removed. | + +**Current compile-frontier state:** `arraymodule.c` now compiles past `arraytype_doc`'s VC6 string-size family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the separate C99 designated initializer in `array_spec` at line 2876. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`arraymodule.c` `typecode_to_mformat_code` 64-bit width spelling slice) + +Date: 2026-09-15 14:07 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. The legacy-toolchain reference was read from `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md`. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded frontier was re-probed first and remained applicable: `_blake2/blake2s_impl.c` compiled cleanly, 22 sources compiled, and `arraymodule.c` remained first with `sizeof(long long)` diagnostics at `arraymodule.c(1911)` and `(1915)`. One focused coding-agent delegation was attempted but failed before launch because the `anthropic` package is unavailable; no child changes or independent review are claimed. This run addressed only that `sizeof(long long)` defect family. + +- `cpython/Modules/arraymodule.c` — changed only the q/QQ cases in `typecode_to_mformat_code()` from `sizeof(long long)` to `sizeof(PY_LONG_LONG)`. Signedness, typecode dispatch, width calculation, and behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring exactly two `sizeof(PY_LONG_LONG)` assignments in `typecode_to_mformat_code()` and rejecting the old spelling. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 22 sources compiled; first stable diagnostics were `arraymodule.c(1911)` and `(1915)`, `error C2632: 'long' followed by 'long' is illegal`; later diagnostics included string-size, initializer, declaration-order, and API blockers; summary `total=23 compiled=22 cached=0 skipped=0`. | +| `WINEPREFIX=/home/ubuntu/.wine-win9xport wine cmd /c 'call ...\\VCVARS32.BAT && cl'` | exit 0; compiler banner `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. | +| focused coding-agent delegation | failed before launch: `The 'anthropic' package is required for the Anthropic provider`; no child changes were used. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `get_native_typecode q/QQ width is not VC6-compatible`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; the `(1911)`/`(1915)` diagnostics cleared. The next first stable diagnostics are `arraymodule.c(2830)` string-size, `(2876)` initializer, `(2921)` declaration-order, and later API/setup blockers; summary `total=23 compiled=22 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0; all applicable regression suites and source checks reported `ALL TESTS PASSED`. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch && git -C cpython diff --check` | exit 0; compatibility patch regenerated and nested source diff clean. | +| pristine detached `v3.11.16` temporary worktree plus `git apply --check` | exit 0; patch applies cleanly; temporary worktree removed. | + +**Current compile-frontier state:** `typecode_to_mformat_code()` now compiles past its q/QQ `sizeof(long long)` keyword family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is `arraymodule.c(2830)`, the separate string-size family. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`arraymodule.c` `array_array_fromunicode` C89 declaration-order slice) + +Date: 2026-09-15 11:59 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. The legacy-toolchain reference was read from `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md`. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded frontier was re-probed first and remained applicable: `_blake2/blake2s_impl.c` compiled cleanly, 22 sources compiled, and `arraymodule.c` remained first with C89 declaration diagnostics at `arraymodule.c(1746)` and `(1750)`. This run addressed only `array_array_fromunicode_impl()`'s `ustr_length`/`old_size` declaration-order family. One focused Codex read-only delegation (`codex-cli 0.153.4`) inspected the exact function and recommended the minimal hoist; it made no changes. No independent review is claimed. + +- `cpython/Modules/arraymodule.c` — hoisted `ustr_length` into the function declaration group and `old_size` before the decrement in the guarded block; changed only the declaration initializers to assignments, preserving conversion/guard/decrement/resize evaluation points and behavior. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added focused TDD assertions for the declaration groups, assignment sequence, and preserved guard/decrement behavior. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 22 sources compiled; first stable diagnostics were `arraymodule.c(1746)`/`(1750)` for C89 `ustr_length`/`old_size`; later diagnostics included 64-bit, string-size, initializer, and API blockers; summary `total=23 compiled=22 cached=0 skipped=0`. | +| `codex exec -s read-only --skip-git-repo-check ...` | exit 0; recommended hoisting exactly `ustr_length` and `old_size`, retaining their original evaluation points; no files changed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `fromunicode: ustr_length declaration missing from opening group`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; both `ustr_length`/`old_size` diagnostics cleared. The next first stable diagnostics are `arraymodule.c(1911)`/`(1915)` for the separate `long long` family, followed by string-size, initializer, declaration-order, and API blockers; summary `total=23 compiled=22 cached=0 skipped=0`. | +| full applicable regression suite and source checks | exit 0; shell syntax, public/core/PathCch/getpath/stdint/frontier suites and `git -C cpython diff --check` all passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` plus diff check | exit 0; compatibility patch regenerated and source diff clean. | +| pristine detached `v3.11.16` temporary worktree plus `git apply --check` | exit 0; patch applies cleanly; temporary worktree removed. | + +**Current compile-frontier state:** `array_array_fromunicode_impl()` now compiles past its `ustr_length`/`old_size` C89 declaration-order family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the separate `long long` family at `arraymodule.c(1911)` and `(1915)`. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`arraymodule.c` `array_state` declaration-order slice) + +Date: 2026-09-15 09:53 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. The relevant reference was read from `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md`. MSVC6 remains an external/local-only prerequisite through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded frontier was re-probed first and remained applicable: 22 sources compiled, including `_blake2/blake2s_impl.c`, then `arraymodule.c` was first. This run addressed only the two C89 declaration-order diagnostics for `array_state` in `array_array_fromfile_impl()` and `array_array_tofile_impl()`. One focused Codex read-only delegation inspected the exact functions and recommended the minimal hoist; it made no changes. No independent review is claimed. + +- `cpython/Modules/arraymodule.c` — added one bare `array_state *state` declaration to each function's opening declaration group and changed only the two later declaration initializers to assignments. Lookup timing, early exits, assertions, and write/read sequences are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added focused TDD assertions for both functions. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. + +**Exact command results:** prior slice recorded in the following historical entry; all applicable regression suites, patch regeneration, and pristine patch application passed. + +**Current compile-frontier state:** `array_array_fromfile_impl()` and `array_array_tofile_impl()` now compile past their `array_state` declaration-order family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier was `arraymodule.c(1746)`/`(1750)`, addressed in the entry above. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`arraymodule.c` `array_repeat` C89 declaration-order slice) + +Date: 2026-09-15 03:34 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. The legacy-toolchain reference was read from `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md`. MSVC6 remains an external/local-only prerequisite invoked through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded `arraymodule.c(920)` frontier was re-probed first and remained true: 22 sources compiled, including `_blake2/blake2s_impl.c`, then `array_repeat()` was the first failing source. This run addressed only its C89 declaration-order family. One focused Codex read-only implementation-guidance lane (`codex-cli 0.153.4`) inspected the exact function and recommended the same five-local hoist; it made no changes. No independent review is claimed. + +- `cpython/Modules/arraymodule.c` — hoisted `array_length`, `size`, `np`, `oldbytes`, and `newbytes` before executable statements; changed only their later declaration initializers to assignments, preserving normalization, overflow checks, allocation, early returns, and byte repetition order. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the C89-safe declaration group and preserved assignment sequence. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 22 sources compiled; first stable diagnostics were `arraymodule.c(920)`, `(924)`, `(925)`, `(931)`, and `(932)` for mixed C99 declarations in `array_repeat()`; later blockers included lines 1086, 1171, 1494, 1552, 1741, 1745, 1902, 1906, 2821, 2867, 2912, 2965, 2981, 3013, and 3100; summary `total=23 compiled=22 cached=0 skipped=0`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `array_repeat declaration missing: Py_ssize_t array_length`. | +| `codex exec -s read-only --skip-git-repo-check ...` focused implementation guidance | exit 0; recommended hoisting the five locals and preserving assignments at the original evaluation points; no files changed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; `array_repeat()` compiled past the five declaration diagnostics. The next first stable diagnostics are `arraymodule.c(1086)` for `array_inplace_repeat()`'s post-statement `size` declaration, followed by distinct loop/declaration, API, 64-bit, string-size, initializer, and module-setup blockers; summary `total=23 compiled=22 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0; all applicable regression suites and source checks reported `ALL TESTS PASSED`. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch && git -C cpython diff --check` | exit 0; compatibility patch regenerated and nested source diff clean. | +| pristine detached `v3.11.16` temporary worktree plus `git apply --check` | exit 0; patch applies cleanly; temporary worktree removed. | + +**Current compile-frontier state:** `array_repeat()` now compiles past its C89 declaration-order family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is `array_inplace_repeat()` at `arraymodule.c(1086)`. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`arraymodule.c` `array_richcompare` duplicate `cmp` declaration slice) + +Date: 2026-09-15 01:27 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. The relevant reference was read from `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md`. MSVC6 remains an external/local-only prerequisite invoked through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the previously verified banner is `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded frontier was re-probed first and remained applicable: 22 sources compiled, then `arraymodule.c` failed first at the distinct duplicate `int cmp;` declaration after `compare_sizes:`. This run addressed only that C89 declaration-order family. One focused coding-agent implementation delegation was attempted and failed before launch because the `anthropic` package is unavailable; no child changes or independent review are claimed. + +- `cpython/Modules/arraymodule.c` — removed only the duplicate `int cmp;` declaration after `compare_sizes:`; the opening declaration remains the sole local and the size-comparison switch is unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added a focused assertion rejecting the duplicate post-label declaration and preserving the compare-size assignment sequence. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +|| Command | Result | +|---|---| +|| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 22 sources compiled; first stable diagnostic was `arraymodule.c(768) : error C2143: syntax error : missing ';' before 'type'` for the duplicate `int cmp;`; later independent blockers began at lines 920, 924, 1166, 1489, 1547, 1736, 1897, 2816, 2862, 2907, 2960, 3008, and 3095; summary `total=23 compiled=22 cached=0 skipped=0`. | +|| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `array_richcompare compare_sizes retains duplicate cmp declaration`. | +|| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +|| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; the line-768 duplicate declaration blocker cleared. The next first stable diagnostics are the separate `arraymodule.c(920)` C89 declaration-order family (`const` after executable statements), followed by later declaration, initializer, string-size, and API-call blockers; summary `total=23 compiled=22 cached=0 skipped=0`. | +|| full applicable regression suite and source checks: `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0; all suites reported `ALL TESTS PASSED`. | +|| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch && git -C cpython diff --check` | exit 0; patch regenerated and nested source diff clean. | +|| pristine detached `v3.11.16` temporary worktree plus `git apply --check` | exit 0; compatibility patch applies cleanly; temporary worktree removed. | + +**Current compile-frontier state:** `array_richcompare()` now compiles past the duplicate `cmp` declaration under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the separate `arraymodule.c(920)` declaration-order family. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`arraymodule.c` `array_richcompare` compare-size locals slice) + +Date: 2026-09-14 23:19 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite invoked through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; verified banner: `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded frontier was re-probed first and remained applicable: `_blake2/blake2s_impl.c` compiled cleanly, 22 sources compiled, and `arraymodule.c` remained the first failing source. This run addressed only the C89 declaration-order family for `vs` and `ws` in `array_richcompare()`; the separate duplicate `int cmp` declaration after `compare_sizes:` and all later blockers remain untouched. One focused Codex implementation lane (`codex-cli 0.153.4`) worked in an isolated temporary snapshot; its candidate was inspected and only the requested source shape was applied manually. No independent review is claimed. + +- `cpython/Modules/arraymodule.c` — added `vs` and `ws` to the opening declaration group and changed their post-label declaration-with-initializer statements to assignments. Evaluation point, size comparisons, and behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring both locals before executable statements and preserving their assignment sequence. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 22 sources compiled; first stable diagnostics were `arraymodule.c(766)`/`(767)` C89 `Py_ssize_t vs/ws` declarations, followed by the separate `int cmp` declaration at line 768 and later declaration, `long long`, string-size, and initializer families; summary `total=23 compiled=22 cached=0 skipped=0`. | +| `WINEPREFIX=/home/ubuntu/.wine-win9xport wine cmd /c 'call ...\\VCVARS32.BAT && cl'` | exit 0; banner `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `array_richcompare size locals missing from opening group`. | +| isolated Codex implementation lane in `/tmp/python-win9x-codex-array` | exit 0; changed only the copied `arraymodule.c`; focused source-shape assertion reported `Source shape assertions passed`. No prohibited Git operations. | +| `diff -u cpython/Modules/arraymodule.c /tmp/python-win9x-codex-array/cpython/Modules/arraymodule.c` | exit 1 because the candidate differed only in the requested `vs/ws` declaration and assignment lines; candidate inspected before manual application. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after applying the source edit and correcting the declaration-group matcher | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after the source edit | exit 2; `vs/ws` diagnostics cleared. The next first stable diagnostic is the separate post-label `int cmp` declaration at `arraymodule.c(768)`; summary `total=23 compiled=22 cached=0`. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch && git -C cpython diff --check` | exit 0; compatibility patch regenerated and nested source diff clean. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh` | exit 0; all applicable regression suites and focused frontier assertions reported `ALL TESTS PASSED`. | +| pristine detached `v3.11.16` temporary worktree plus `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; patch applies cleanly; temporary verification worktree removed. | + +**Current compile-frontier state:** `array_richcompare()` now compiles past the `vs/ws` C89 declaration-order family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the distinct post-label `int cmp` declaration at line 768. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`arraymodule.c` `array_richcompare` fast-path `res` declaration slice) + +Date: 2026-09-14 21:12 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite invoked through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; verified banner: `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. + +The recorded `arraymodule.c` frontier was re-probed first and remained applicable: `_blake2/blake2s_impl.c` and the preceding 21 sources compiled, then the first stable diagnostic was `arraymodule.c(736) : error C2275: 'PyObject' : illegal use of this type as an expression` for the fast-path `PyObject *res` declaration after executable statements. This run addressed only that C89 declaration-order family. A single focused Codex read-only delegation (`codex-cli 0.153.4`) inspected the exact source and recommended reusing the existing opening `res` local; it made no changes. No independent review is claimed. + +- `cpython/Modules/arraymodule.c` — changed only `PyObject *res = cmp ? Py_True : Py_False;` to `res = cmp ? Py_True : Py_False;`, reusing the existing declaration at the function opening. Boolean selection, reference counting, and return behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring one opening `res` declaration, no fast-path declaration, and the preserved assignment/incref/return sequence. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 22 sources compiled, then `arraymodule.c(736)` first reported `error C2275: 'PyObject' : illegal use of this type as an expression`; later independent blockers began at lines 766, 921, 925, 1082, 1167, 1490, 1548, 1737, 1898, 2817, 2863, 2908, 2961, 3009, and 3096. Summary `total=23 compiled=22 cached=0 skipped=0`. | +| focused Codex delegation: `codex exec -s read-only --skip-git-repo-check ...` | exit 0; recommended the one-line reuse of the existing `res` declaration and supplied the focused assertion shape. No files changed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before the source edit | exit 1 as required by TDD; `array_richcompare fast path retains res declaration`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after the source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after the source edit | exit 2; the line-736 `PyObject *res` blocker cleared. The next first stable diagnostics are the separate C89 `Py_ssize_t vs/ws` declarations at lines 766–767, followed by later declaration, `long long`, string-size, and initializer families. Summary `total=23 compiled=22 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && git -C cpython diff --check` | exit 0; all applicable regression suites and source checks passed. | +| `WINEPREFIX=/home/ubuntu/.wine-win9xport wine cmd /c 'call Z:\\\\home\\\\ubuntu\\\\projects\\\\python-win9x\\\\MSVC600\\\\VC98\\\\Bin\\\\VCVARS32.BAT && cl'` | exit 0; compiler banner `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. Wine emitted expected headless-display warnings. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; compatibility patch regenerated. | +| pristine detached `v3.11.16` temporary worktree plus `git apply --check` | exit 0; patch applies cleanly; temporary worktree removed. | + +**Current compile-frontier state:** `array_richcompare()` now compiles past the fast-path `res` declaration family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the separate C89 declaration-order family for `Py_ssize_t vs` and `Py_ssize_t ws` at lines 766–767. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`arraymodule.c` `array_richcompare` C89 `cmp` declaration slice) + +Date: 2026-09-14 19:05 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite invoked through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; verified banner: `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. The single focused coding-agent delegation was attempted but failed before launch because the `anthropic` package is unavailable; no child changes or independent review are claimed. + +The recorded `arraymodule.c` frontier was re-probed through the preceding `getarrayitem()` fix and remained applicable: 22 sources compiled, then `arraymodule.c` was the first failing source. This run addressed only the C89 declaration-order family for `int cmp` in `array_richcompare()`; later mixed-declaration families in that function remain untouched. + +- `cpython/Modules/arraymodule.c` — hoisted `int cmp` into `array_richcompare()`'s opening declaration group and removed only the fast-path declaration after executable statements. The comparison switch, assignments, and return behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the opening-group declaration and preserving the fast-path comparison assignment sequence. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| focused coding-agent delegation | failed before launch: `The 'anthropic' package is required for the Anthropic provider`; no child changes were used. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, with source unchanged | exit 1 as required by TDD; `array_richcompare cmp declaration missing from opening group`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after the source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after the source edit | exit 2; 22 sources compiled and `arraymodule.c` was reached. The `int cmp` blocker cleared. The next first stable diagnostics are `arraymodule.c(736) : error C2275: 'PyObject' : illegal use of this type as an expression` for `PyObject *res` after executable statements, followed by later declaration-order, string-size, and initializer diagnostics; summary `total=23 compiled=22 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh` | exit 0. | +| `bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0; all applicable regression suites and source checks passed. | +| `WINEPREFIX=/home/ubuntu/.wine-win9xport wine cmd /c 'call Z:\\home\\ubuntu\\projects\\python-win9x\\MSVC600\\VC98\\Bin\\VCVARS32.BAT && cl'` | exit 0; compiler banner `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. Wine emitted expected headless-display warnings before the banner. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; compatibility patch regenerated. | +| pristine detached `v3.11.16` temporary worktree plus `git apply --check` | exit 0; patch applies cleanly; temporary verification worktree removed. | + +**Current compile-frontier state:** `array_richcompare()` now compiles past the `int cmp` C89 declaration-order family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is its separate `PyObject *res` declaration at line 736. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`arraymodule.c` duplicate `getarrayitem` declaration slice) + +Date: 2026-09-14 16:58 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with all pre-existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite invoked through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; verified banner: `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. The single focused coding-agent delegation was attempted for frontier guidance but failed before launch because the `anthropic` package is unavailable; no child changes or independent review are claimed. + +The recorded `arraymodule.c` frontier was not still true on re-probe: `_blake2/blake2s_impl.c` and the earlier sources compiled, but `getarrayitem()` still contained a duplicate `arrayobject *ap` declaration after the debug-only assertion. This run therefore followed the actual first stable blocker and addressed only that duplicate/C89 declaration-order family. The previously recorded `int cmp` frontier was not changed in this slice. + +- `cpython/Modules/arraymodule.c` — removed the duplicate post-`#endif` `arrayobject *ap` declaration; retained the opening declaration, later assignment, assertion, and item access unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — strengthened the existing `getarrayitem()` regression assertion to require exactly one `ap` declaration and the preserved assignment form. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 22 sources compiled; first stable diagnostics were `arraymodule.c(633) : error C2143` at the duplicate `arrayobject *ap`, followed by parser/cascade diagnostics; summary `total=23 compiled=22 cached=0 skipped=0`. | +| focused coding-agent delegation | failed before launch: `The 'anthropic' package is required for the Anthropic provider`; no child changes were used. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the duplicate-declaration assertion, before the source edit | exit 1 as required by TDD; `getarrayitem ap declaration is duplicated`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after the source edit and assertion-boundary correction | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after the source edit | exit 2; the duplicate `getarrayitem()` blocker cleared. The next first stable diagnostic is the separate `arraymodule.c(726) : error C2143` for `int cmp` after executable statements; summary `total=23 compiled=22 cached=0 skipped=0`. | +| `bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0; all applicable regression suites and source checks passed. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh` | exit 0. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; compatibility patch regenerated. | +| pristine detached `v3.11.16` worktree plus `git apply --check` | exit 0; patch applies cleanly; temporary verification worktree removed. | + +**Current compile-frontier state:** `getarrayitem()` now compiles past the duplicate declaration under MSVC6 (`cl.exe 12.00.8804`) through Wine. The next narrow frontier is the separate `array_richcompare()` `int cmp` C89 declaration-order family at line 726. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`arraymodule.c` `getarrayitem` C89 declaration-order slice) + +Date: 2026-09-14 14:49 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with all existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite invoked through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; verified compiler banner: `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. The required single focused coding-agent delegation was attempted but failed before launch because the `anthropic` package is unavailable; no child changes or independent review are claimed. + +The recorded frontier was re-probed first and remained true: `_blake2/blake2s_impl.c` compiled cleanly, and `arraymodule.c` remained the first failing source after 22 compiled sources. The first stable diagnostic was the C89 declaration-order error at `arraymodule.c(632)` for `arrayobject *ap` after the debug-only executable assertion. This run addressed only that one declaration-order family. + +- `cpython/Modules/arraymodule.c` — hoisted `arrayobject *ap` before the `#ifndef NDEBUG` assertion block; preserved the assignment, assertion, bounds check, and item access behavior. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the `ap` declaration before the debug block and preserving the assignment form. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `WINEPREFIX=/home/ubuntu/.wine-win9xport wine cmd /c 'call ...\\VCVARS32.BAT && cl'` | exit 0; compiler banner `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. Wine emitted expected headless-display warnings before the banner. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 22 sources compiled; first stable diagnostic `cpython\\Modules\\arraymodule.c(632) : error C2143: syntax error : missing ';' before 'type'`; summary `total=23 compiled=22 cached=0 skipped=0`. | +| focused coding-agent delegation | failed before launch: `The 'anthropic' package is required for the Anthropic provider`; no child changes were used. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `getarrayitem ap declaration is not before debug block`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; `getarrayitem()` advanced past the blocker. The next first stable diagnostic is the separate C89 declaration-order family at `arraymodule.c(727)`, `int cmp` after executable statements; summary `total=23 compiled=22 cached=0 skipped=0`. | +| `bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0; all applicable regression suites and source checks passed. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh` | exit 0. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; compatibility patch regenerated. | +| first patch verification using `git -C build/verify-vc6-patch-worktree apply --check` | exit 128 due to an incorrect relative worktree path; no source was modified, and the temporary worktree was removed. | +| corrected pristine detached `v3.11.16` temporary worktree plus `git apply --check` | exit 0; patch applies cleanly; temporary worktree removed. | + +**Current compile-frontier state:** `arraymodule.c` now compiles past `getarrayitem()`'s C89 declaration-order family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the separate `int cmp` declaration-order family at line 727. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`arraymodule.c` q/QQ descriptor-width type spelling slice) + +Date: 2026-09-14 12:43 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with all existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite invoked through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; verified compiler banner: `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. The single focused coding-agent delegation was attempted for frontier implementation guidance but failed before launch because the `anthropic` package is unavailable; no child changes or independent review are claimed. + +The recorded `arraymodule.c` frontier was re-probed first and remained true: 22 sources compiled, then the q/QQ descriptor entries reported `error C2632: 'long' followed by 'long' is illegal` at lines 572–573. This run addressed only that `sizeof(long long)` type-spelling family. + +- `cpython/Modules/arraymodule.c` — changed only the q/QQ descriptor item-width expressions from `sizeof(long long)` to `sizeof(PY_LONG_LONG)`. Descriptor widths, typecodes, handlers, and behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring VC6-compatible q/QQ descriptor widths and rejecting the original `sizeof(long long)` forms. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 22 sources compiled; first stable diagnostics were `arraymodule.c(572)` and `(573)`, `error C2632: 'long' followed by 'long' is illegal`; later diagnostics began at `arraymodule.c(632)` with C89 mixed declarations; summary `total=23 compiled=22 cached=0 skipped=0`. | +| focused coding-agent delegation | failed before launch: `The 'anthropic' package is required for the Anthropic provider`; no child changes were used. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `q descriptor does not use VC6-compatible 64-bit width`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; q/QQ `sizeof(long long)` diagnostics cleared. The next first stable diagnostics are the separate C89 declaration-order family beginning at `arraymodule.c(632)`, followed by later declaration, initializer, and string-size families; summary `total=23 compiled=22 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0 for every command; all applicable regression suites and source checks passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; compatibility patch regenerated from the complete nested checkout. | +| regenerated patch applied with `git -C build/verify-vc6-patch-worktree apply --check` to detached baseline `v3.11.16` | exit 0; temporary verification worktree removed. | + +**Current compile-frontier state:** the q/QQ descriptor widths now compile past their `sizeof(long long)` keyword family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the separate C89 declaration-order family beginning in `arraymodule.c` at line 632. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`arraymodule.c` `DEFINE_COMPAREITEMS` 64-bit type-argument slice) + +Date: 2026-09-14 10:37 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with its existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite, invoked through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler is `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. The single focused coding-agent delegation was attempted but failed before launch because the `anthropic` package is unavailable; no child changes or independent review are claimed. + +The recorded `arraymodule.c` frontier was re-probed first and remained true: 22 sources compiled, then VC6 reported the first stable `long long` type-argument diagnostics in the `DEFINE_COMPAREITEMS(q, ...)` and `DEFINE_COMPAREITEMS(QQ, ...)` macro invocations at lines 554–555. This run addressed only that macro-argument spelling family; later `sizeof(long long)` and declaration-order families remain untouched. + +- `cpython/Modules/arraymodule.c` — changed only the `q` and `QQ` `DEFINE_COMPAREITEMS` type arguments to `PY_LONG_LONG` and `unsigned PY_LONG_LONG`, respectively. The macro body and comparison behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring both VC6-compatible macro arguments and rejecting the original `long long` spellings. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `WINEPREFIX=/home/ubuntu/.wine-win9xport wine cmd /c 'call ...\\VCVARS32.BAT && cl'` | exit 0; compiler banner `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 22 sources compiled; first stable diagnostics were `arraymodule.c(554)` and `(555)`, `error C2632: 'long' followed by 'long' is illegal`, followed by later `sizeof(long long)` diagnostics at `(572)` and `(573)`; summary `total=23 compiled=22 cached=0 skipped=0`. | +| focused coding-agent delegation | failed before launch: `The 'anthropic' package is required for the Anthropic provider`; no child changes were used. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `signed q compare macro argument is not VC6-compatible`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; the macro-invocation `long long` diagnostics at `(554)` and `(555)` cleared. The next first stable diagnostics are the separate `sizeof(long long)` family at `(572)` and `(573)`, followed by later declaration-order and initializer families; summary `total=23 compiled=22 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0 for every command; all applicable regression suites and source checks passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; compatibility patch regenerated from the nested checkout. | + +**Current compile-frontier state:** the `DEFINE_COMPAREITEMS` q/QQ macro invocations now compile past their `long long` keyword family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the separate `sizeof(long long)` family in the `arraymodule.c` descriptor table. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`arraymodule.c` `DEFINE_COMPAREITEMS` C89 loop-declaration slice) + +Date: 2026-09-14 08:30 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with its existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite, invoked through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler is `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. The single focused coding-agent delegation was attempted but failed before launch because the `anthropic` package is unavailable; no child changes or independent review are claimed. + +The recorded `arraymodule.c` frontier was re-probed first and remained true: 22 sources compiled, then VC6 failed at `DEFINE_COMPAREITEMS` invocation line 544 because the macro expanded `for (Py_ssize_t i = 0; ...)`. This run addressed only that C89 loop-declaration family. + +- `cpython/Modules/arraymodule.c` — added `Py_ssize_t i;` to `DEFINE_COMPAREITEMS`'s declaration group and changed the loop to `for (i = 0; ...)`. Comparison order, bounds, increment, and return behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the C89-safe macro declaration and loop form. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 22 sources compiled; first stable diagnostics were the C89 `for (Py_ssize_t i = ...)` expansion at `arraymodule.c(544)` with `error C2143`, followed by parser fallout; summary `total=23 compiled=22 cached=0 skipped=0`. | +| focused coding-agent delegation | failed before launch: `The 'anthropic' package is required for the Anthropic provider`; no child changes were used. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `arraymodule compare macro loop counter declaration missing`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; the C89 loop-declaration blocker cleared. The next first stable diagnostics are the separate `long long` macro-type arguments at `arraymodule.c(554)`, `(555)`, `(572)`, and `(573)`, followed by later declaration-order and initializer families; summary `total=23 compiled=22 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0 for every command; all applicable regression suites and source checks passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; compatibility patch regenerated from the nested checkout only. | +| regenerated patch applied with `git -C apply --check` at baseline commit | exit 0; temporary detached verification worktree removed. | + +**Current compile-frontier state:** `DEFINE_COMPAREITEMS` now compiles past its C89 loop-declaration family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the separate `long long` type-argument family in the macro invocations. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`arraymodule.c` q/QQ VC6 64-bit-type spelling slice) + +Date: 2026-09-14 06:24 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with its existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite, invoked through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler is `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. The single focused coding-agent delegation was attempted but failed before launch because the `anthropic` package is unavailable; no child changes or independent review are claimed. + +The recorded `arraymodule.c` frontier was re-probed first and remained true: 22 sources compiled, then VC6 reported the first stable `long long` keyword diagnostics in `q_getitem()`, `q_setitem()`, `QQ_getitem()`, and `QQ_setitem()` at lines 449–491. This run addressed only that active signed/unsigned 64-bit type-spelling family, using the existing `PY_LONG_LONG` abstraction. + +- `cpython/Modules/arraymodule.c` — replaced the live `long long` and `unsigned long long` declarations/casts in the q/QQ handlers with `PY_LONG_LONG` and `unsigned PY_LONG_LONG`. Function calls, widths, pointer casts, conversion behavior, and control flow are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring both VC6-compatible spellings and rejecting live `long long` keywords in that handler family. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 22 sources compiled; first stable diagnostics were `arraymodule.c(449)`, `(455)`, `(459)`, `(467)`, `(473)`, `(484)`, and `(491)`, `error C2632: 'long' followed by 'long' is illegal`; summary `total=23 compiled=22 cached=0 skipped=0`. | +| focused coding-agent delegation | failed before launch: `The 'anthropic' package is required for the Anthropic provider`; no child changes were used. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `arraymodule q/QQ handlers use VC6-compatible 64-bit type spellings` failed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; q/QQ `long long` diagnostics cleared. The next first stable blocker is the separate C89 `for (Py_ssize_t i = ...)` family in `DEFINE_COMPAREITEMS` at `arraymodule.c(544)`; remaining later diagnostics include the macro's `long long` type arguments and additional declaration-order errors. Summary `total=23 compiled=22 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh; bash scripts/vc6-probe.test.sh; bash scripts/vc6-probe-core.test.sh; bash scripts/vc6-probe-pathcch.test.sh; bash scripts/generate-getpath-frozen.test.sh; bash scripts/vc6-probe-stdint.test.sh; bash scripts/vc6-probe-pythoncore-frontier.test.sh; git -C cpython diff --check` | exit 0 for every command; all applicable regression suites and source checks passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; compatibility patch regenerated from the nested checkout only. | +| regenerated patch applied with `git -C apply --check` at baseline commit | exit 0; temporary detached verification worktree removed. | + +**Current compile-frontier state:** the q/QQ handlers now compile past their live `long long` keyword family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the separate C89 loop-declaration family in `DEFINE_COMPAREITEMS` at `arraymodule.c(538)`, first surfaced at invocation line 544. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`arraymodule.c` `u_setitem` C89 declaration-order slice) + +Date: 2026-09-14 04:17 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with its existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite, invoked through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; the verified compiler banner is `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. The required single focused coding-agent delegation was attempted but failed before launch because the `anthropic` package is unavailable; no child changes or independent review are claimed. + +The recorded frontier was re-probed first and remained true: 22 sources compiled, then `Modules/arraymodule.c` was the first failing source. This run addressed only the C89 mixed-declaration family in `u_setitem()` at the `len` and `w` locals. + +- `cpython/Modules/arraymodule.c` — hoisted `Py_ssize_t len` and `wchar_t w` into `u_setitem()`'s declaration group; changed the first declaration-with-initializer to an assignment and removed the later `w` declaration. The `PyUnicode_AsWideChar()` call order and error/control-flow behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the C89-safe declarations and preserving both `u_setitem()` conversion calls. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 22 sources compiled; first blocker `arraymodule.c(265)` reported `error C2275: 'Py_ssize_t' : illegal use of this type as an expression`, with the related `wchar_t` declaration at line 272 and later cascade diagnostics; summary `total=23 compiled=22 cached=0 skipped=0`. | +| focused coding-agent delegation | failed before launch: `The 'anthropic' package is required for the Anthropic provider`; no child changes were used. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before the source edit | exit 1 as required by TDD; `arraymodule u_setitem uses C89 declaration-order-safe len and w locals` failed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after the source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after the source edit | exit 2; `arraymodule.c` passed the `u_setitem()` family. The next first stable blocker is the separate `long long` family at lines 449, 455, 459, 467, 473, 484, and 491, followed by C89 `for`-initializer diagnostics; summary `total=23 compiled=22 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh; bash scripts/vc6-probe.test.sh; bash scripts/vc6-probe-core.test.sh; bash scripts/vc6-probe-pathcch.test.sh; bash scripts/generate-getpath-frozen.test.sh; bash scripts/vc6-probe-stdint.test.sh; bash scripts/vc6-probe-pythoncore-frontier.test.sh; git -C cpython diff --check` | exit 0 for every command; all applicable regression suites and source checks passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; compatibility patch regenerated. | +| regenerated patch applied with `git apply --check` to a pristine detached `v3.11.16` worktree | exit 0; temporary worktree removed. | + +**Current compile-frontier state:** `arraymodule.c` now compiles past `u_setitem()`'s C89 declaration-order family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the separate `long long` family in `arraymodule.c`. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + + +## Latest revision (`_struct.c` PyModuleDef positional-initializer slice) + +Date: 2026-09-14 02:10 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite, invoked through Wine with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. The single focused coding-agent delegation was attempted but failed before launch because the `anthropic` package is unavailable; no child changes or independent review are claimed. + +The recorded `_blake2/blake2s_impl.c` state was re-probed first and was no longer the live frontier: it compiled cleanly. The actual first blocker was `_struct.c(2484)`, a C99 designated initializer. This run addressed only that initializer family. + +- `cpython/Modules/_struct.c` — converted `_structmodule` to positional `PyModuleDef` initialization in declared field order (`m_base`, `m_name`, `m_doc`, `m_size`, `m_methods`, `m_slots`, `m_traverse`, `m_clear`, `m_free`). Values and behavior are preserved. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the exact positional initializer and rejecting designated fields. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; `_blake2/blake2s_impl.c` compiled cleanly and `_struct.c(2484)` reported `error C2059: syntax error : '.'`; summary `total=21 compiled=20 cached=0 skipped=0`. | +| Focused coding-agent delegation | failed before launch: `The 'anthropic' package is required for the Anthropic provider`; no child changes were used. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before source edit | exit 1 as required by TDD; `_structmodule positional initializer mismatch`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edit | exit 2; `_struct.c` compiled cleanly. The first blocker advanced to `Modules/arraymodule.c(265)`, beginning with `error C2275: 'Py_ssize_t' : illegal use of this type as an expression`, followed by C89 mixed declarations, `long long`, and other diagnostics; summary `total=23 compiled=22 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && git -C cpython diff --check` | exit 0; all applicable regression suites passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; compatibility patch regenerated. | +| regenerated patch applied with `git apply --check` to a pristine detached `v3.11.16` worktree | exit 0; temporary worktree removed. | + +**Current compile-frontier state:** `_struct.c` now compiles cleanly under MSVC6 (`cl.exe` 12.00.8804) through Wine, advancing the frontier to `Modules/arraymodule.c`. This is compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`_struct.c C89 declaration-order frontier slice`) + +Date: 2026-09-14 00:04 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with its existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite, invoked through Wine on Linux with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; verified compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. The required single focused coding-agent delegation was attempted, but the delegation runtime failed before launch because the `anthropic` package is unavailable; no child changes or independent review are claimed. + +The recorded frontier was re-probed first and remained true: `_blake2/blake2s_impl.c` compiled cleanly, and `_struct.c` was the first failing source. This run addressed only the C89 declaration-order family at `s_new()`, `s_dealloc()`, and `s_pack()`; the later designated initializer remains untouched. + +- `cpython/Modules/_struct.c` — hoisted `alloc_func` in `s_new()`, `tp` and `free_func` in `s_dealloc()`, and `writer` in `s_pack()` into declaration groups before executable statements; preserved each initializer's original execution point and all control flow/refcount behavior. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added focused TDD assertions covering all three functions. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 20 sources compiled, then `_struct.c` reported the first stable C89 declaration-order blockers at lines 1447, 1530, and 1923. | +| Focused coding-agent delegation | failed before launch: `The 'anthropic' package is required for the Anthropic provider`; no child changes were used. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding assertions, before source edits | exit 1 as required by TDD; the new assertion failed with `s_new: declaration not hoisted`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after source edits | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after source edits | exit 2; `_struct.c` compiled cleanly (no `_struct.c` diagnostics), and the first blocker advanced to the separate designated initializer at `_struct.c(2484)`; summary `total=21 compiled=20 cached=0 skipped=0`. | +| `bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh` | exit 0; all applicable regression suites reported `ALL TESTS PASSED`. | +| `git -C cpython diff --check && bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh` | exit 0. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; compatibility patch regenerated. | +| regenerated patch applied with `git apply --check` to a clean detached `v3.11.16` temporary worktree | exit 0; temporary worktree removed. | + +**Current compile-frontier state:** `_struct.c` now compiles past the C89 declaration-order family under MSVC6 through Wine. The next narrow frontier is the separate C99 designated initializer at line 2484. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`_struct.c` MSVC6 `long long` keyword compatibility slice) + +Date: 2026-09-13 21:58 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with its existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. MSVC6 remains an external/local-only prerequisite, invoked through Wine on Linux with `WINEPREFIX=/home/ubuntu/.wine-win9xport`; verified compiler banner: `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. The single requested coding-agent implementation attempt was made but could not start because the delegation runtime lacks the `anthropic` package; no child changes or independent review are claimed. + +The recorded frontier was re-probed first and remained true: `_blake2/blake2s_impl.c` compiled cleanly, and `_struct.c` was the first failing source. This run addressed only the distinct `long long` keyword family. The later `_struct.c` declaration-order and designated-initializer blockers remain untouched. + +- `cpython/Modules/_struct.c` — replaced live signed `long long` spellings with `PY_LONG_LONG`, live unsigned spellings with `unsigned PY_LONG_LONG`, and updated the two sign-extension casts and native-size calculations. Integer widths and runtime operations are unchanged; comments and user-facing format documentation retain their original wording. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion that strips comments/module documentation and rejects live `long long` keywords while requiring the complete `PY_LONG_LONG` replacement family. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 20 sources compiled, then `_struct.c` reported the first stable `error C2632: 'long' followed by 'long' is illegal` family at lines 103, 211, 213, 221, 234, 236, 244, 493, 501, 702, 712, 801–802, 843, 851, 858, 1064, 1072, and 1079. Later independent blockers were at 1447/1530/1923 and 2480. Summary `total=21 compiled=20 cached=0 skipped=0`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before the source edit | exit 1 as required by TDD; the new `_struct` assertion failed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after the source edit and assertion matcher corrections | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after the source edit | exit 2; all `_struct.c` `long long` diagnostics cleared. The first stable blocker advanced to `_struct.c(1447)` C89 declaration ordering, followed by 1530/1923 declaration-order diagnostics and the designated initializer at 2480. Summary `total=21 compiled=20 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh` plus public/core/PathCch/getpath/stdint/frontier regression suites | exit 0; every applicable suite reported `ALL TESTS PASSED`. | +| `git -C cpython diff --check` | exit 0. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; compatibility patch regenerated. | +| regenerated patch applied with `git apply --check` to a pristine detached `v3.11.16` worktree | exit 0; temporary worktree removed. | + +**Current compile-frontier state:** `_struct.c` now compiles past the `long long` keyword family under MSVC6 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is `_struct.c`'s C89 declaration-order family at lines 1447, 1530, and 1923. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`_struct.c` MSVC6 `_Bool` compatibility slice) + +Date: 2026-09-13 19:48 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with its existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. The compiler banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`, invoked through Wine on Linux with `WINEPREFIX=/home/ubuntu/.wine-win9xport`. + +The recorded `_blake2/blake2s_impl.c` state was re-probed first and was no longer the live frontier: `_blake2s_impl.c` compiled cleanly. The actual first stable blocker was `_struct.c`; this run addressed only the missing C99 `_Bool` defect family. A single focused Codex implementation lane ran in an isolated temporary snapshot; its candidate was inspected and copied manually. No independent review is claimed. + +- `cpython/Modules/_struct.c` — added a guarded MSVC6-only `typedef unsigned char _Bool;`, preserving the one-byte layout required by the module's native `?` format handling. No other `_struct.c` defect family was changed. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion for the guarded one-byte typedef. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 20 sources compiled, then `_struct.c` first reported `_Bool` syntax/undeclared diagnostics at lines 85, 94, 504, 719, and related fallout. Summary `total=21 compiled=20 cached=0 skipped=0`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before the source edit | exit 1 as required by TDD; `_struct provides a guarded one-byte VC6 _Bool compatibility typedef` failed. | +| focused Codex implementation lane in `/tmp/python-win9x-codex-struct` | exit 0; changed only `cpython/Modules/_struct.c`; its focused test ended with `ALL TESTS PASSED`. Candidate diff was inspected before manual application. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after the source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after the source edit | exit 2; all `_Bool` diagnostics cleared. The first stable blocker remains `_struct.c`'s separate `long long` keyword family, followed by C89 mixed declarations at lines 1447/1530/1923 and a designated initializer at line 2480. Summary `total=21 compiled=20 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0; all applicable regression suites and source diff checks passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; patch regenerated. Existing generated patch payload retains its previously documented trailing-whitespace lines. | +| regenerated patch applied with `git apply --check` to a pristine detached `v3.11.16` worktree | exit 0; temporary worktree removed. | + +**Current compile-frontier state:** `_blake2/blake2s_impl.c` and `_struct.c` through the `_Bool` family compile past this slice under MSVC 6.0 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is `_struct.c`'s `long long` keyword compatibility family. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`_stat.c` `statmodule` positional-initializer slice) + +Date: 2026-09-13 17:40 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with its existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. The required focused coding-agent delegation could not start because the delegation runtime requires the unavailable `anthropic` package; implementation and verification were performed directly, with no independent review claimed. The MSVC6 banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`, invoked through Wine on Linux. + +The recorded `_stat.c` state was re-probed first and remained true: 19 sources compiled, then VC6 reported only the `statmodule` C99 designated initializer at line 635. This run addressed only that designated-initializer defect family. + +- `cpython/Modules/_stat.c` — converted `statmodule` to positional `PyModuleDef` initialization in declared field order (`m_base`, `m_name`, `m_doc`, `m_size`, `m_methods`, `m_slots`, `m_traverse`, `m_clear`, `m_free`). The previously implicit trailing fields are explicitly `NULL`; names, values, and module behavior are preserved. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the exact positional initializer and rejecting designated fields. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 19 sources compiled; `_stat.c(635)` reported `error C2059: syntax error : '.'`; summary `total=20 compiled=19 cached=0 skipped=0`. | +| focused coding-agent delegation | not started; runtime reported `The 'anthropic' package is required for the Anthropic provider`; no child changes were used. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before the source edit | exit 1 as required by TDD; `statmodule positional initializer mismatch`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after the source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after the source edit | exit 2; `_stat.c` compiled cleanly and the first stable blocker advanced to `_struct.c`; summary `total=21 compiled=20 cached=0 skipped=0`. First `_struct.c` diagnostics include undeclared/unsupported `_Bool`, illegal `long long`, declaration-order errors, and a later designated initializer at line 2475. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0; all applicable regression suites, shell syntax checks, and nested source diff checks passed. | +| `bash scripts/vc6-probe-core.sh cpython/Modules/main.c && bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 0 for both compile probes. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; compatibility patch regenerated. | +| regenerated patch applied with `git apply --check` to a pristine detached `v3.11.16` worktree | exit 0; temporary worktree removed. | + +**Current compile-frontier state:** `_stat.c` now compiles cleanly under MSVC 6.0 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is `_struct.c`, beginning with its `_Bool`/`long long` compatibility diagnostics. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`_stat.c` Win9x/VC6 header-constant availability slice) + +Date: 2026-09-13 15:33 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with its existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. The MSVC6 banner remains `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`, invoked through Wine on Linux. One focused Codex implementation lane (`codex-cli 0.153.4`) used an isolated temporary worktree; its candidate was inspected and the narrow source change was applied to the real checkout. No independent review is claimed. + +The recorded `_blake2/blake2s_impl.c` state was re-probed first and remained clean. The actual first stable blocker was `_stat.c`: the VC6 headers lacked `FILE_ATTRIBUTE_DEVICE`, `FILE_ATTRIBUTE_VIRTUAL`, and `IO_REPARSE_TAG_SYMLINK`. This run addressed only that header-constant availability family; the later `_stat.c` designated initializer remains untouched. + +- `cpython/Modules/_stat.c` — added guarded fallbacks in the existing `MS_WINDOWS` section: `FILE_ATTRIBUTE_DEVICE 0x0040`, `FILE_ATTRIBUTE_VIRTUAL 0x10000`, and `IO_REPARSE_TAG_SYMLINK 0xA000000CL`. The `#ifndef` guards preserve any definitions supplied by a newer Windows header. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring all three guarded definitions and exact values. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +|| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 19 sources compiled; `_stat.c(580)`, `(594)`, and `(597)` reported undeclared `FILE_ATTRIBUTE_DEVICE`, `FILE_ATTRIBUTE_VIRTUAL`, and `IO_REPARSE_TAG_SYMLINK`, followed by the designated-initializer error at line 622; summary `total=20 compiled=19 cached=0 skipped=0`. | +| isolated `codex exec -s workspace-write --skip-git-repo-check ...` implementation lane | exit 0; its focused assertion produced RED exit 1 naming all three missing guards, then GREEN exit 0 after the candidate edit. Its attempted VC6 probe was blocked before compilation by Wine `wineserver: mkdir /run/user/1000/wine/...: Read-only file system`; no child changes were copied automatically. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the focused assertion, before the source edit | exit 1 as required by TDD; `_stat provides guarded VC6/Win9x file-attribute fallbacks` failed with `FILE_ATTRIBUTE_DEVICE`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after the source edit | exit 0; all focused assertions passed. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after the source edit | exit 2; `_stat.c` advanced past the three missing-constant diagnostics. The next first stable blocker is the separate C99 designated initializer at `_stat.c(635)`; summary `total=20 compiled=19 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh; bash scripts/vc6-probe.test.sh; bash scripts/vc6-probe-core.test.sh; bash scripts/vc6-probe-pathcch.test.sh; bash scripts/generate-getpath-frozen.test.sh; bash scripts/vc6-probe-stdint.test.sh; bash scripts/vc6-probe-pythoncore-frontier.test.sh; git -C cpython diff --check` | exit 0; all applicable regression suites, shell syntax checks, and nested source diff checks passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; compatibility patch regenerated. | +| regenerated patch applied with `git apply --check` to a pristine temporary detached `v3.11.16` worktree | exit 0; temporary worktree removed. | + +**Current compile-frontier state:** `_stat.c` now compiles past the missing Win9x/VC6 header-constant family under MSVC 6.0 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is `_stat.c`'s `PyModuleDef` C99 designated initializer at line 635. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + + +## Latest revision (`_stat.c` `stat_exec` C89 declaration-order slice) + +Date: 2026-09-13 13:27 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with its existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. One focused Codex read-only delegation (`codex-cli 0.153.4`) inspected this exact frontier and recommended the minimal slice; it made no changes. No independent review is claimed. + +The recorded `_sre/sre.c` frontier was re-probed before editing and remained clear. The actual first stable blocker was `Modules/_stat.c`: `stat_exec()` declared `st_constants` and the `for` loop counter after executable `ADD_INT_MACRO` calls, producing VC6/C89 declaration-order diagnostics at lines 557 and 570. This run made only that one defect-family fix; the later missing Win32 constants and designated initializer remain untouched. + +- `cpython/Modules/_stat.c` — moved the unchanged `st_constants` table and an `int i` declaration into `stat_exec()`'s opening declaration group; changed the loop to use `for (i = 0; ...)`. Constant order, assigned values, registration order, and immediate error returns are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the table and loop counter before the first executable macro call and rejecting the C99 loop declaration. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +|| Command | Result | +|---|---| +|| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 19 sources compiled; `_stat.c(557)` and `(570)` reported C89 mixed-declaration errors, followed by parser fallout and missing `FILE_ATTRIBUTE_DEVICE`, `FILE_ATTRIBUTE_VIRTUAL`, and `IO_REPARSE_TAG_SYMLINK`, plus the later designated-initializer error at line 621; summary `total=20 compiled=19 cached=0 skipped=0`. | +|| `codex exec -s read-only --skip-git-repo-check ...` focused frontier inspection | exit 0; recommended moving `st_constants` and hoisting `int i`; no files changed. | +|| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the focused assertion, before the source edit | exit 1 as required by TDD after correcting the assertion's extraction boundary; `_stat stat_exec uses C89 declaration-order-safe constants and loop counter` failed while prior assertions passed. | +|| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after the source edit | exit 0; all focused assertions passed. | +|| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after the source edit | exit 2; `_stat.c` advanced past the C89 declaration-order family. Remaining first diagnostics are missing `FILE_ATTRIBUTE_DEVICE`, `FILE_ATTRIBUTE_VIRTUAL`, and `IO_REPARSE_TAG_SYMLINK`, followed by the `statmodule` designated initializer at line 622; summary `total=20 compiled=19 cached=0 skipped=0`. | +|| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0; all applicable regression suites and nested source diff checks passed. | +|| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; compatibility patch regenerated. | +|| regenerated patch applied with `git apply --check` to a pristine temporary detached `v3.11.16` worktree | exit 0; temporary worktree removed. | + +**Current compile-frontier state:** `Modules/_stat.c` now compiles past its C89 declaration-order blocker under MSVC 6.0 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the distinct Win9x/VC6 header-constant availability group (`FILE_ATTRIBUTE_DEVICE`, `FILE_ATTRIBUTE_VIRTUAL`, `IO_REPARSE_TAG_SYMLINK`), followed by the `statmodule` C99 designated initializer. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`_sre/sre.c` `sremodule` PyModuleDef designated-initializer slice) + +Date: 2026-09-13 11:20 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with its existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. One focused Codex implementation lane (`codex-cli 0.153.4`) ran in an isolated temporary worktree snapshot; its candidate was reviewed, the temporary worktree was removed, and no independent review is claimed. + +The recorded `_sre/sre.c` frontier was re-probed before editing and remained true: 18 sources compiled, then VC6 reported the `sremodule` `PyModuleDef` C99 designated-initializer family at line 3031. This run made only that defect-family fix. + +- `cpython/Modules/_sre/sre.c` — converted `sremodule` from designated initializers to positional `PyModuleDef` initialization in declared field order (`m_base`, `m_name`, `m_doc`, `m_size`, `m_methods`, `m_slots`, `m_traverse`, `m_clear`, `m_free`). The previously omitted `m_doc` is explicitly `NULL`; field values, order, and behavior are preserved. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the exact positional `sremodule` initializer and rejecting designated fields. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 18 sources compiled; `_sre.c(3031)` reported `error C2059: syntax error : '.'` and `','`; summary `total=19 compiled=18 cached=0 skipped=0`. | +| isolated `codex exec -s workspace-write ...` focused implementation lane | exit 0 in a temporary worktree; candidate source edit and an extra upstream test-file change were inspected, but the temporary worktree was removed and only the narrow source shape was applied to the real checkout. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before the source edit | exit 1 as required by TDD; `sremodule positional initializer mismatch` and `not ok - _sre sremodule uses C89-compatible positional initializers`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after the source edit | exit 0; all focused assertions passed. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after the source edit | exit 2; `_sre/sre.c` compiled cleanly and the first stable blocker advanced to `Modules/_stat.c`; first diagnostics include C89 declaration-order errors at lines 557/570, missing `FILE_ATTRIBUTE_DEVICE`, `FILE_ATTRIBUTE_VIRTUAL`, `IO_REPARSE_TAG_SYMLINK`, and a designated-initializer error at line 621; summary `total=20 compiled=19 cached=0 skipped=0`. | +| `bash -n ... && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && git -C cpython diff --check` | exit 0; all applicable regression suites and source diff checks passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; compatibility patch regenerated. | +| regenerated patch applied with `git apply --check` to a pristine temporary detached `v3.11.16` worktree | exit 0; temporary worktree removed. | + +**Current compile-frontier state:** `_sre/sre.c` now compiles cleanly under MSVC 6.0 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is `Modules/_stat.c`; it must be re-probed and addressed one defect family at a time. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`_sre/sre.c` ADD_ULONG_CONSTANT C89 declaration-order slice) + +Date: 2026-09-13 09:10 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with its existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. One focused Codex delegation ran read-only with `codex-cli 0.153.4`; it confirmed the smallest safe slice and made no changes. No independent review is claimed. The relevant legacy-toolchain reference was read from `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md`. + +The recorded `_sre/sre.c` designated-initializer frontier was re-probed before editing and was no longer the live first blocker: the actual first stable diagnostics were the C89 mixed declarations inside `ADD_ULONG_CONSTANT` at lines 2982 and 2985. This run made only that one defect-family fix; the later `sremodule` designated initializers remain untouched. + +- `cpython/Modules/_sre/sre.c` — changed the macro-local `int res = PyModule_AddObjectRef(...)` to an opening `int res;` declaration followed by assignment after the existing `if (!o) goto error;`. Allocation, NULL handling, module insertion, decref ordering, error jump, both call sites, and behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the C89-safe macro shape and preserving the operation sequence. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 18 sources compiled; `_sre/sre.c(3011)` and `(3012)` expanded `ADD_ULONG_CONSTANT` and reported C89 declaration-order diagnostics at macro lines 2982 and 2985, followed by parser fallout; summary `total=19 compiled=18 cached=0 skipped=0`. | +| `codex exec -s read-only --skip-git-repo-check "...inspect only the live VC6 frontier..."` | exit 0; read-only analysis identified the minimal `ADD_ULONG_CONSTANT` `res` hoist and no semantic risk; no files changed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the focused assertion, before the source edit | exit 1 as required by TDD; the new `_sre ADD_ULONG_CONSTANT` assertion failed while prior assertions passed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after the source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after the source edit | exit 2; the `ADD_ULONG_CONSTANT` diagnostics cleared. The next first stable blocker is `_sre/sre.c(3031)`, the separate `sremodule` C99 designated-initializer family; summary `total=19 compiled=18 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && git -C cpython diff --check` | exit 0; all regression suites passed and the nested source diff was clean. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; compatibility patch regenerated. | +| regenerated patch applied with `git apply --check` to a pristine temporary detached `v3.11.16` worktree | exit 0; temporary worktree removed. | + +**Current compile-frontier state:** `_sre/sre.c` now compiles past the `ADD_ULONG_CONSTANT` C89 declaration-order defect under MSVC 6.0 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the separate `sremodule` `PyModuleDef` designated-initializer family at lines 3030–3037. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`_sre/sre.c` PyType_Spec designated-initializer slice) + +Date: 2026-09-13 07:04 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with its existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. The required focused coding-agent delegation was attempted, but the delegation runtime could not start because the `anthropic` package is unavailable; no child changes or independent review were used. The relevant legacy-toolchain reference was read from `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md`. + +The recorded `_sre/sre.c` frontier was re-probed before editing and remained true: 18 sources compiled, then VC6 reported three C99 designated initializers in `pattern_spec`, `match_spec`, and `scanner_spec` at lines 2826, 2894, and 2924. This run made only that designated-initializer defect-family fix. + +- `cpython/Modules/_sre/sre.c` — converted `pattern_spec`, `match_spec`, and `scanner_spec` from C99 designated initializers to positional `PyType_Spec` initializers in declared field order (`name`, `basicsize`, `itemsize`, `flags`, `slots`). The omitted `scanner_spec.itemsize` is explicitly `0`, preserving C99 zero-initialization; values and behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring all three positional initializer blocks and rejecting the old designated form. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 18 sources compiled; `_sre/sre.c` first reported `error C2059: syntax error : '.'` at lines 2826, 2894, and 2924, followed by parser fallout at lines 3010+; summary `total=19 compiled=18 cached=0 skipped=0`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the focused assertion, before the source edit | exit 1 as required by TDD; the new positional-`PyType_Spec` assertion failed with `pattern_spec` while prior assertions passed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after the source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after the source edit | exit 2; the three `_sre` `PyType_Spec` designated-initializer diagnostics cleared. The next stable blocker is the `_sre/sre.c` `ADD_ULONG_CONSTANT` macro's C89 mixed declarations at lines 2982 and 2985, followed by the `sremodule` `PyModuleDef` designated initializers; summary `total=19 compiled=18 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh` plus public/core/PathCch/getpath/stdint/frontier regression suites and `git -C cpython diff --check` | exit 0; every regression suite reported `ALL TESTS PASSED`, and the nested source diff was clean. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; compatibility patch regenerated. | +| regenerated patch applied with `git apply --check` to a pristine temporary detached `v3.11.16` worktree | exit 0; temporary worktree removed. | +| `WINEPREFIX=/home/ubuntu/.wine-win9xport wine cmd /c 'call ...\\VCVARS32.BAT && cl'` | exit 0; compiler banner `Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86`. | + +**Current compile-frontier state:** the three `_sre/sre.c` `PyType_Spec` designated initializers now compile past VC6/MSVC 6.0 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the separate `sremodule` `PyModuleDef` designated-initializer family at lines 3030–3037. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`_sre/sre.c` GROUPREF_EXISTS `rc` C89 declaration-order slice) + +Date: 2026-09-13 04:58 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with its existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. The required focused coding-agent delegation was attempted, but the delegation runtime could not start because the `anthropic` package is unavailable; no child changes or independent review were used. The relevant local reference was read from `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md`. + +The recorded `_sre/sre_lib.h` frontier was re-probed before editing and remained true through that file. The first stable blocker was `_sre/sre.c(1925)`, a C89 declaration-order defect: `int rc = _validate_inner(...)` followed the executable `VTRACE` statement in the `SRE_OP_GROUPREF_EXISTS` case. This run made only that defect-family fix. + +- `cpython/Modules/_sre/sre.c` — hoisted `int rc` into `_validate_inner()`'s opening declaration group and changed the later declaration-with-initializer to `rc = _validate_inner(...)`. The assignment timing, validation branches, control flow, and behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added a focused TDD assertion requiring the function-level C89 declaration and assignment shape. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +|| Command | Result | +||---|---| +|| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; 18 sources compiled; `_sre/sre.c(1925)` reported `error C2143: syntax error : missing ';' before 'type'` for `int rc = ...`, followed by `rc` undeclared and later `_sre` diagnostics; summary `total=19 compiled=18 cached=0 skipped=0`. | +|| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the focused assertion, before the source edit | exit 1 as required by TDD; `_sre GROUPREF_EXISTS uses C89 declaration-order-safe rc local` failed while prior assertions passed. | +|| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after the source edit | exit 0; `ALL TESTS PASSED`. | +|| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after the source edit | exit 2; the `rc` blocker cleared and `_sre.c` reached the next distinct blockers: designated initializers at lines 2826, 2894, and 2924, followed by later declaration/designated-initializer diagnostics; summary `total=19 compiled=18 cached=0 skipped=0`. | +|| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0; all regression suites passed and the nested source diff was clean. | +|| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; compatibility patch regenerated. | +|| regenerated patch applied with `git apply --check` to a pristine detached `v3.11.16` worktree | exit 0; temporary verification worktree removed. | + +**Current compile-frontier state:** `_sre/sre.c` now compiles past the `GROUPREF_EXISTS` `rc` declaration-order defect under MSVC 6.0 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the separate C99 designated-initializer family at `_sre/sre.c` lines 2826, 2894, and 2924. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`_sre/sre_lib.h` MIN_UNTIL repeat local C89 declaration-order slice) + +Date: 2026-09-13 02:48 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with its existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. The required focused coding-agent delegation was attempted with the installed Codex launcher, but the delegation runtime could not start because the `anthropic` package is unavailable; no child changes or independent review were used. The relevant local reference was read from `/home/ubuntu/.hermes/profiles/maxwell/skills/software-development/legacy-toolchain-os-porting/references/python-3-win9x-msvc6.md`. + +The recorded `_sre/sre_lib.h` frontier was re-probed before editing and remained true: `_sre/sre.c` was the first failing source after 18 compiled sources, with `sre_lib.h(1215) : error C2275: 'SRE_REPEAT' : illegal use of this type as an expression` at `SRE_REPEAT *repeat_of_tail = state->repeat;`. This run made only that one C89 mixed-declaration defect-family fix. + +- `cpython/Modules/_sre/sre_lib.h` — hoisted `SRE_REPEAT *repeat_of_tail` into `SRE(match)`'s opening declaration group and changed the later declaration to `repeat_of_tail = state->repeat;`. Assignment timing, repeat restoration, mark-stack handling, control flow, and matching behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added a focused TDD assertion requiring the C89-safe declaration and assignment shape. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; `getpath.c`, `_abc.c`, `_bisectmodule.c`, both `_blake2` implementations, `_codecsmodule.c`, `_collectionsmodule.c`, `_contextvarsmodule.c`, `_csv.c`, `_functoolsmodule.c`, `_heapqmodule.c`, `_json.c`, `_localemodule.c`, `_lsprof.c`, `_pickle.c`, `_randommodule.c`, and `_sha3/sha3module.c` compiled; `_sre/sre_lib.h(1215)` reported `error C2275: 'SRE_REPEAT' : illegal use of this type as an expression`, followed by `repeat_of_tail` undeclared and later `_sre.c` diagnostics; summary `total=19 compiled=18 cached=0 skipped=0`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the focused assertion, before the source edit | exit 1 as required by TDD; `_sre MIN_UNTIL uses C89 declaration-order-safe repeat local` failed while prior assertions passed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after the source edit and assertion-boundary correction | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after the source edit | exit 2; the `sre_lib.h(1215)` blocker cleared. The next first stable blockers are `_sre/sre.c(1925)` C89 declaration-order (`rc`), then designated initializers at lines 2825, 2893, 2923, and later declaration/designated-initializer diagnostics; summary `total=19 compiled=18 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && git -C cpython diff --check` | exit 0. | +| `bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh` | exit 0; all regression suites reported `ALL TESTS PASSED`. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; compatibility patch regenerated. | +| regenerated patch applied with `git apply --check` to a pristine detached `v3.11.16` worktree | exit 0; temporary verification worktree removed. | + +**Current compile-frontier state:** `_sre/sre_lib.h` now compiles past the `MIN_UNTIL` `repeat_of_tail` C89 declaration-order defect under MSVC 6.0 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is `_sre/sre.c(1925)`, the separate C89 mixed-declaration `rc` defect. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`_sre/sre_lib.h` SRE(match) C89 declaration-order slice) + +Date: 2026-09-13 00:41 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with its existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. The required focused coding-agent delegation was attempted with Claude Code, but authentication failed with `401 OAuth access token has been revoked`; no child changes or independent review were used. The referenced local `python-3-win9x-msvc6.md` document was not present at the expected skill-reference path. + +The recorded `_blake2/blake2s_impl.c` state was re-probed before editing and remained clean, so the actual first stable blocker was followed instead: `_sre/sre_lib.h(586)`, where `SRE(match)` declared `const SRE_CHAR *ptr` after an executable statement and an `entrance:` label, violating VC6/C89 declaration ordering. This run made only that one defect-family fix. + +- `cpython/Modules/_sre/sre_lib.h` — added `const SRE_CHAR *ptr;` to `SRE(match)`'s opening declaration group and changed the later declaration to `ptr = (SRE_CHAR *)state->ptr;`. The label, assignment point, control flow, and matching behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added a focused TDD assertion requiring the C89-safe declaration and assignment shape. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; `_blake2/blake2s_impl.c` compiled cleanly, then `_sre/sre.c` reached `_sre/sre_lib.h(586) : error C2143: syntax error : missing ';' before 'const'`, with parser-cascade diagnostics; summary `total=19 compiled=18 cached=0 skipped=0`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the focused assertion, before the source edit | exit 1 as required by TDD after correcting the assertion's extraction boundary; `_sre SRE(match) uses C89 declaration-order-safe ptr local` failed while prior assertions passed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after the source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after the source edit | exit 2; `_sre/sre_lib.h` cleared the `ptr` declaration-order blocker. The next first stable blocker is `_sre/sre_lib.h(1215) : error C2275: 'SRE_REPEAT' : illegal use of this type as an expression` at `SRE_REPEAT *repeat_of_tail = state->repeat;`, followed by `_sre.c` declaration/designated-initializer errors; summary `total=19 compiled=18 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0; all regression suites and nested source diff checks passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; compatibility patch regenerated. | +| regenerated patch applied with `git apply --check` to a pristine detached `v3.11.16` worktree | exit 0; temporary verification worktree removed. | + +**Current compile-frontier state:** `SRE(match)` now compiles past the line-586 C89 declaration-order defect under MSVC 6.0 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is the separate C89 mixed-declaration `SRE_REPEAT *repeat_of_tail` at `_sre/sre_lib.h(1215)`. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + + +## Latest revision (`_sha3/sha3module.c` designated-initializer slice) + +Date: 2026-09-12 22:35 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with its existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. The required focused coding-agent delegation was attempted, but the delegation runtime could not start because the `anthropic` package is unavailable; no child changes or independent review were used. + +The recorded `_sha3/sha3module.c` state was re-probed before editing and remained true: `SHA3_dealloc()` was already clean, while seven C99 designated initializers in the `SHA3_TYPE_SPEC` macro and `_sha3module` produced VC6 `error C2059: syntax error : '.'` diagnostics. This run made only that designated-initializer defect-family fix. + +- `cpython/Modules/_sha3/sha3module.c` — converted `SHA3_TYPE_SPEC` to positional `PyType_Spec` initialization in declared field order (`name`, `basicsize`, explicit `itemsize` zero, `flags`, `slots`), and converted `_sha3module` to positional `PyModuleDef` initialization in declared field order. Values and field order are preserved; no runtime behavior or control flow changed. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring both `_sha3` initializer groups to be positional. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; `_sha3/sha3module.c` was reached after 17 compiled sources and reported seven `error C2059: syntax error : '.'` diagnostics at lines 444, 447, 450, 453, 569, 572, and 651; `total=18 compiled=17 cached=0 skipped=0`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the focused assertion, before the source edit | exit 1 as required by TDD; the new `_sha3` positional-initializer assertion failed while prior assertions passed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after the source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after the source edit | exit 2; `_sha3/sha3module.c` compiled with no diagnostics and the first blocker advanced to `_sre/sre.c`, beginning with `_sre/sre_lib.h(586) : error C2143: syntax error : missing ';' before 'const'`, followed by parser-cascade diagnostics; `total=19 compiled=18 cached=0 skipped=0`. | +| `bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh` | exit 0; all regression suites reported `ALL TESTS PASSED`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; compatibility patch regenerated. | +| regenerated patch applied with `git apply --check` to a pristine detached `v3.11.16` worktree | exit 0; temporary verification worktree removed. | + +**Current compile-frontier state:** `_sha3/sha3module.c` now compiles cleanly under MSVC 6.0 (`cl.exe` 12.00.8804) through Wine. The next narrow frontier is `_sre/sre.c`, whose first stable blocker is the C89 declaration-order defect in `sre_lib.h` at line 586. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`_sha3/sha3module.c` `SHA3_dealloc` C89 declaration-hoist slice) + +Date: 2026-09-12 20:28 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with its existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. One focused Codex delegation ran read-only with `codex-cli 0.153.4`; it confirmed the recorded `_blake2/blake2s_impl.c` state was already stale and made no changes. No independent review is claimed. + +The recorded `_blake2/blake2s_impl.c` state was re-probed before editing and was no longer the live frontier: `_blake2/blake2s_impl.c` compiled cleanly. The first stable blocker was instead `_sha3/sha3module.c(183)`, where `SHA3_dealloc()` declared `PyTypeObject *tp = Py_TYPE(self);` after executable lock cleanup, violating VC6/C89 declaration ordering. This run made only that one defect-family fix. + +- `cpython/Modules/_sha3/sha3module.c` — hoisted `PyTypeObject *tp` into `SHA3_dealloc()`'s opening declaration group and changed the original declaration to `tp = Py_TYPE(self);`. Lock freeing, type lookup timing, object freeing, and type decref order are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the C89-safe declaration and preserving the cleanup/type/refcount sequence. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +|| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; `_blake2/blake2s_impl.c` compiled cleanly, then `_sha3/sha3module.c(183) : error C2275: 'PyTypeObject' : illegal use of this type as an expression`; designated-initializer diagnostics followed at lines 442, 445, 448, 451, 567, 570, and 649; `total=18 compiled=17 cached=0 skipped=0`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the focused assertion, before the source edit | exit 1 as required by TDD; the new `SHA3_dealloc` assertion failed while prior assertions passed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after the source edit, before correcting the assertion's sequence matcher | exit 1; the source shape was correct but the newly added matcher incorrectly compared the function body without its signature. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after correcting the assertion | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after the source edit | exit 2; `_sha3/sha3module.c` cleared the `SHA3_dealloc()` blocker. New first blockers are the seven C99 designated initializers in the SHA3 type specs and `_sha3module` (`error C2059: syntax error : '.'`); `total=18 compiled=17 cached=0 skipped=0`. | +| `bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh` | exit 0; all regression suites reported `ALL TESTS PASSED`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; compatibility patch regenerated. | +| regenerated patch applied with `git apply --check` to a pristine detached `v3.11.16` worktree | exit 0; temporary verification worktree removed. | + +**Current compile-frontier state:** `SHA3_dealloc()` now compiles cleanly under MSVC 6.0 (`cl.exe` 12.00.8804) through Wine. The next blocker is the separate C99 designated-initializer family in `_sha3/sha3module.c`. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution. + +## Latest revision (`_randommodule.c` `_random_exec` C89 declaration-hoist slice) + +Date: 2026-09-12 18:22 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with its existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. The required single focused Codex delegation ran read-only with `codex-cli 0.153.4`; it produced analysis only and made no changes. No independent review is claimed. + +The recorded `_pickle.c` state was re-probed before editing and remained true through `_pickle.c`; the first stable blocker was the recorded `_randommodule.c(599)` C89 mixed-declaration defect. This run made only that one defect-family fix in `_random_exec()`. + +- `cpython/Modules/_randommodule.c` — hoisted `PyObject *longval` and `PyObject *longtype` into `_random_exec()`'s opening declaration group, then changed only their original initializers to assignments. Allocation, NULL checks, `Py_DECREF` order, and error returns are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring C89-safe declarations and preserving the `_random_exec()` allocation/error/refcount sequence. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff` and verified against a pristine `v3.11.16` worktree. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `codex exec -s read-only --skip-git-repo-check "In /home/ubuntu/projects/python-win9x, inspect the current CPython v3.11.16 Windows 98/MSVC6 port state without modifying any files. Focus only on the recorded frontier in Modules/_randommodule.c at _random_exec(), especially the C89 mixed-declaration blocker around longval/longtype. Report the smallest evidence-backed edit, the exact focused test assertion that should be added first under strict TDD, and any semantic risks. Do not edit, commit, reset, stash, or push."` | exit 0; read-only focused analysis reported the minimal two-local hoist and no semantic risk beyond preserving initializer timing. No files changed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before the source edit | exit 1 as required by TDD; `_random_exec uses C89 locals and preserves initialization order` failed while prior assertions passed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after the source edit | exit 0; `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after the source edit | exit 2; `_randommodule.c` compiled cleanly and the frontier advanced to `_sha3/sha3module.c(183)`, `error C2275: 'PyTypeObject' : illegal use of this type as an expression`, followed by designated-initializer `error C2059` diagnostics at lines 442, 445, 448, 451, 567, 570, and 649; `total=18 compiled=17 cached=0 skipped=0`. | +| `WINEPREFIX=/home/ubuntu/.wine-win9xport wine cmd /c 'call Z:\\home\\ubuntu\\projects\\python-win9x\\MSVC600\\VC98\\Bin\\VCVARS32.BAT && cl'` | exit 0; compiler banner: Microsoft 32-bit C/C++ Optimizing Compiler Version `12.00.8804` for 80x86. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0; all regression suites and nested source diff checks passed. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; compatibility patch regenerated. | +| `git -C cpython worktree add --detach /home/ubuntu/projects/python-win9x/build/verify-vc6-patch-worktree v3.11.16 && git -C /home/ubuntu/projects/python-win9x/build/verify-vc6-patch-worktree apply --check ../../compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; patch applied cleanly to a pristine detached baseline, and the temporary worktree was removed. | + +**Current compile-frontier state:** `_randommodule.c` now compiles cleanly under MSVC 6.0 (`cl.exe` 12.00.8804) through Wine. The next blocker is `_sha3/sha3module.c`'s C89 declaration-order and C99 designated-initializer defects. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution is claimed. + +## Latest revision (`_pickle.c` Unpickler_set_memo SIZE_MAX cleanup slice) + +Date: 2026-09-12 16:15 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with its existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. The required coding-agent delegation was attempted with the installed Codex CLI, but this CLI rejects the requested `--full-auto` option (exit 2); no child changes or independent review were used. + +The recorded `_blake2/blake2s_impl.c` state was re-probed before editing and was no longer the live frontier: the full source-list probe reached `_pickle.c` and reported the distinct missing `SIZE_MAX` blocker. This run therefore made only the actual first-frontier `_pickle.c` fix. + +- `cpython/Modules/_pickle.c` — changed `Unpickler_set_memo()` cleanup from `for (i = new_memo_size - 1; i != SIZE_MAX; i--)` to `for (i = new_memo_size; i-- > 0;)`. The loop still decrements through exactly `new_memo_size - 1` to `0`, preserving decref order and cleanup behavior without relying on the unavailable VC6 `SIZE_MAX` definition. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion for the no-`SIZE_MAX` cleanup loop and updated the existing `Unpickler_set_memo()` assertion to require the new C89-safe form. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff` and verified against a pristine `v3.11.16` worktree. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; `total=16 compiled=15 cached=0 skipped=0`; `_pickle.c(7638)`, `error C2065: 'SIZE_MAX' : undeclared identifier`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the new assertion, before the source edit | exit 1 as required by TDD; the new cleanup assertion failed, while prior assertions passed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after the source edit and test adjustment | exit 0, `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after the source edit | exit 2; `_pickle.c` compiled cleanly and the frontier advanced to `_randommodule.c(599)`, `error C2275: 'PyObject' : illegal use of this type as an expression`; `total=17 compiled=16 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh && git -C cpython diff --check` | exit 0; all regression suites passed and the nested source diff is clean. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; compatibility patch regenerated. | +| pristine detached `v3.11.16` worktree `git -C build/verify-vc6-patch-worktree apply --check ../../compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; temporary verification worktree removed. | + +**Current compile-frontier state:** `_pickle.c` now compiles past `Unpickler_set_memo()` under MSVC 6.0 (`cl.exe` 12.00.8804) through Wine. The next blocker is `_randommodule.c` line 599, a C89 mixed-declaration defect. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution is claimed. + + +## Latest revision (`_pickle.c` Unpickler_set_memo C89 loop-counter slice) + +Date: 2026-09-12 14:08 UTC + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with its existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. The required single focused coding-agent delegation was attempted, but could not run because the delegation runtime lacks the `anthropic` package; no child changes or independent review were used. + +The recorded frontier was re-probed before editing and remained true: `_pickle.c` compiled through `Unpickler_traverse()`, and the first stable blockers were the two C99 `for (size_t i = ...)` initializers in `Unpickler_set_memo()` at lines 7589 and 7637. The cleanup loop also exposed a separate `SIZE_MAX` undeclared diagnostic after the C99 syntax was removed. + +- `cpython/Modules/_pickle.c` — added a function-scoped `size_t i;` declaration and changed only the two `Unpickler_set_memo()` loop initializers to `for (i = ...)`. Loop bounds, decrement behavior, cleanup, refcounting, and assignment timing are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion requiring the shared loop counter and both C89-safe loop forms. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`; it applies cleanly to pristine `v3.11.16`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; `total=16 compiled=15 cached=0 skipped=0`; first blockers `_pickle.c(7589)` and `(7637)` C99 loop declarations, with `SIZE_MAX` also undeclared. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before the source edit | exit 1 as required by TDD; the new `Unpickler_set_memo` assertion failed while prior assertions passed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after the source edit | exit 0, `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after the source edit | exit 2; both C99 loop diagnostics cleared. New first blocker is `_pickle.c(7638)`, `error C2065: 'SIZE_MAX' : undeclared identifier`; `total=16 compiled=15 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh` plus public/core/PathCch/getpath/stdint/frontier regression suites | exit 0; all suites reported `ALL TESTS PASSED`. | +| `git -C cpython diff --check` | exit 0. | +| `git -C cpython diff > compat/msvc600/cpython-3.11.16-vc6-headers.patch` followed by patch whitespace check | regeneration succeeded; generated patch check exits 2 because existing diff payload contains trailing-whitespace lines, while the nested source diff check is clean. | +| pristine detached `v3.11.16` worktree `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; temporary verification worktree removed. | + +**Current compile-frontier state:** `Unpickler_set_memo()` now compiles past the C99 loop-initializer family under VC6. The next blocker is the distinct missing/unsupported `SIZE_MAX` definition at the cleanup loop. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution is claimed. + +## Latest revision (`_pickle.c` Unpickler_traverse C89 declaration-order slice) + +Date: 2026-09-12 + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with its existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. The required single focused Claude Code delegation was attempted in the existing checkout without permitting edits, but authentication failed with `401 OAuth access token has been revoked`; no child changes or independent review were used. + +The live forced VC6 probe was run before editing. It reached `_pickle.c` as the first blocker, not the older recorded `_blake2` frontier: `Unpickler_traverse()` at line 7266 declared `PyObject **memo = self->memo;` after executable `Py_VISIT()` statements, violating VC6/C89 declaration ordering. This run therefore advanced the actual live frontier and did not touch `_blake2`. + +- `cpython/Modules/_pickle.c` — hoisted `PyObject **memo` to `Unpickler_traverse()`'s opening declaration group and changed the original declaration to `memo = self->memo;`. Assignment timing and traversal/refcount behavior are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion for `Unpickler_traverse()` declaration ordering. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`; it applies cleanly to pristine `v3.11.16`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; `total=16 compiled=15 cached=0 skipped=0`; first blocker `_pickle.c(7266)`, `error C2143`, mixed declaration `PyObject **memo = self->memo;`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before the source edit | exit 1 as required by TDD; the new `Unpickler_traverse` assertion failed while prior assertions passed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after the source edit | exit 0, `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after the source edit | exit 2; `Unpickler_traverse()` cleared. New first blockers are `_pickle.c(7589)` C99 `for (size_t i = ...)` and `_pickle.c(7637)` C99 `for (size_t i = ...)` with `SIZE_MAX` undeclared; `total=16 compiled=15 cached=0`. | +| `bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh` | exit 0; all regression suites reported `ALL TESTS PASSED`. | +| `git -C cpython diff --check && bash -n scripts/vc6-probe-pythoncore-frontier.test.sh` | exit 0. | +| pristine detached `v3.11.16` worktree `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; temporary verification worktree removed. | + +**Current compile-frontier state:** `_pickle.c` now compiles past `Unpickler_traverse()` under VC6. The next narrow frontier is the distinct C99 `for`-initializer family in `Unpickler_set_memo()` at the two loop sites, with the `SIZE_MAX` diagnostic at the cleanup loop. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution is claimed. + + +## Latest revision (`_pickle.c` load_readonly_buffer C89 declaration-order slice) + +Date: 2026-09-12 + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. The focused coding-agent delegation was attempted but could not start because the runtime lacks the `anthropic` package; no child changes or independent review were used. + +The recorded `_pickle.c` frontier was re-probed before editing and remained true: `load_next_buffer()` compiles cleanly. The first stable blocker was `load_readonly_buffer()` at lines 5687–5688, where `PyObject *obj = ...` and `PyObject *view = ...` follow executable statements and violate VC6/C89 declaration ordering. + +- `cpython/Modules/_pickle.c` — hoisted `PyObject *obj` and `PyObject *view` beside `Py_ssize_t len`; changed the three initializers to assignments at their original execution points. No control flow or refcount ordering changed. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion for `load_readonly_buffer()` declaration ordering. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`; it applies cleanly to pristine `v3.11.16`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; `total=16 compiled=15 cached=0 skipped=0`; first blocker `_pickle.c(5687)`, `error C2275` for `PyObject *obj`, followed by the same declaration-order error for `view`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before the source edit | exit 1 as required by TDD; the new `load_readonly_buffer` assertion failed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after the source edit | exit 0, `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after the source edit | exit 2; `_pickle.c` cleared `load_readonly_buffer()`. New first stable blockers are `_pickle.c(7266)` C89 declaration-order fallout for `memo`, then C99 `for`-init/declaration fallout at lines 7587 and 7635 (`SIZE_MAX` also reported). Summary remains `total=16 compiled=15 cached=0 skipped=0`. | +| `bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh` | exit 0; every regression suite reported `ALL TESTS PASSED`. | +| `git -C cpython diff --check && bash -n scripts/vc6-probe-pythoncore-frontier.test.sh` | exit 0. | +| pristine detached `v3.11.16` worktree `git apply --check ../../compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; temporary worktree removed. | + +**Current compile-frontier state:** `_pickle.c` now compiles past `load_readonly_buffer()` under VC6. The next narrow frontier is the later `_pickle.c` declaration-order/C99 syntax group beginning at line 7266. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution is claimed. + +## Latest revision (`_pickle.c` load_next_buffer C89 declaration-order slice) + +Date: 2026-09-12 + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549`; the nested `cpython/` checkout remains detached with existing uncommitted port edits preserved. Nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. The required focused coding-agent delegation was attempted but could not start because the delegation runtime lacks the `anthropic` package; no child changes or independent review were used. + +The recorded frontier was re-probed before editing and remained true through `_pickle_PicklerMemoProxy_copy_impl()`. The first stable blocker was `load_next_buffer()` at `_pickle.c(5662)`, a C99 mixed declaration after the `self->buffers == NULL` executable check. + +- `cpython/Modules/_pickle.c` — hoisted `PickleState *st` and `PyObject *buf` into the function declaration group; preserved both `_Pickle_GetGlobalState()` assignment points and the iterator assignment order. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused TDD assertion for `load_next_buffer()` declaration ordering. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the complete nested `git -C cpython diff`; it applies cleanly to pristine `v3.11.16`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; `total=16 compiled=15 cached=0 skipped=0`; first blocker `_pickle.c(5662)`, `error C2275`, `PyObject *buf = PyIter_Next(...)`, with same-function declaration fallout. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the assertion, before the source edit | exit 1 as required by TDD; the new `load_next_buffer` assertion failed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after the source edit | exit 0, `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after the source edit | exit 2; `load_next_buffer()` cleared. New first blocker is `load_readonly_buffer()` at `_pickle.c(5687)`, C89 mixed declarations for `PyObject *obj` and `PyObject *view`; `total=16 compiled=15 cached=0 skipped=0`. | +| `bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh` | exit 0; every regression suite reported `ALL TESTS PASSED`. | +| `git -C cpython diff --check && bash -n scripts/vc6-probe-pythoncore-frontier.test.sh` | exit 0. | +| pristine detached `v3.11.16` worktree `git apply --check ../../compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0; temporary worktree removed. | +| regenerated patch included in top-level `git diff --check` | exit 2 due trailing-whitespace diagnostics in generated patch hunks; these are diff payload whitespace lines from existing CPython changes, not source-file diagnostics. | + +**Current compile-frontier state:** `_pickle.c` now compiles past `load_next_buffer()` under VC6. The next narrow frontier is `load_readonly_buffer()`'s two C89 mixed declarations at lines 5687–5688. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, no Wine execution of Python, and no real Windows 98 SE execution is claimed. + +Date: 2026-09-12 + +## Latest revision (`_pickle.c` PicklerMemoProxy.copy C89 for-init slice) + +Baseline remains CPython `v3.11.16` at commit `41388c9cb160d0886d5ca00d2e6c8782608a4549` in the pristine tag worktree. Existing uncommitted port edits were preserved; nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. + +The recorded frontier state was re-probed before editing and remained true: `getpath.c`, `_abc.c`, `_bisectmodule.c`, `_blake2` sources, and `_pickle.c` through `Pickler_traverse()` compiled cleanly. The first stable blocker was `_pickle.c(4895)`, the C99 `for (size_t i = ...)` initializer in `_pickle_PicklerMemoProxy_copy_impl()`. + +- `cpython/Modules/_pickle.c` — added `size_t i;` to the function declaration group and changed only the loop initializer to `for (i = 0; ...)`; behavior and assignment timing are unchanged. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused regression assertion before the source edit, as required by TDD. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the nested `git -C cpython diff`; it applies cleanly to pristine `v3.11.16`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; `total=16 compiled=15 cached=0 skipped=0`; first blocker `_pickle.c(4895)`, `error C2143`, C99 `for (size_t i = ...)`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the focused assertion, before the source edit | exit 1 as required by TDD; the new `PicklerMemoProxy.copy` assertion failed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after the source edit | exit 0, `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after the source edit | exit 2; `_pickle.c(4895)` is cleared and the first stable blocker advances to `load_next_buffer()` at line 5662: C89 mixed declaration `PyObject *buf = PyIter_Next(...)`; `total=16 compiled=15 cached=0 skipped=0`. | +| shell syntax plus public/core/PathCch/getpath/stdint/frontier regression suites | exit 0; every suite reported `ALL TESTS PASSED`. | +| `git -C cpython diff --check` and `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh` | exit 0. | +| pristine detached `v3.11.16` worktree `git apply --check` for regenerated patch | exit 0; temporary worktree removed. | +| focused Claude Code delegation | not completed: `401 OAuth access token has been revoked`; no child changes were used and no independent review is claimed. | + +**Current compile-frontier state:** `_pickle_PicklerMemoProxy_copy_impl()` now compiles past the C99 loop initializer under VC6. The next narrow frontier is `load_next_buffer()`'s C89 declaration-order defect at `_pickle.c(5662)`. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, Wine execution of Python, or real Windows 98 SE execution is claimed. + +## Latest revision (`_pickle.c` Pickler_traverse C89 declaration slice) + +Baseline remains CPython `v3.11.16` (commit `41388c9` in the pristine tag worktree). All port edits remain uncommitted in the nested `cpython/` checkout; nothing was reset, cleaned, stashed, discarded, committed, pushed, or published. + +The recorded `_pickle.c` frontier was re-probed before editing. `save_set()` remained clean; the first stable blocker was `Pickler_traverse()` at the later `PyMemoTable *memo = self->memo;` declaration after executable `Py_VISIT()` statements. + +- `cpython/Modules/_pickle.c` — hoisted `PyMemoTable *memo;` before the `Py_VISIT()` statements and changed the original declaration to `memo = self->memo;`. No later `_pickle.c` defect family was changed. +- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added the focused regression assertion for `Pickler_traverse()` declaration order. +- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from the nested `git -C cpython diff`; it applies cleanly to pristine `v3.11.16`. +- `PORT_STATUS.md` — this report. + +**Exact command results:** + +| Command | Result | +|---|---| +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` before this slice | exit 2; `total=16 compiled=15 cached=0 skipped=0`; first blocker `_pickle.c(4725)`, `error C2143`, `PyMemoTable *memo = self->memo`. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after adding the focused assertion, before the source edit | exit 1 as required by TDD; the new `Pickler_traverse` assertion failed. | +| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` after the source edit | exit 0, `ALL TESTS PASSED`. | +| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` after the source edit | exit 2; `Pickler_traverse()` is clean and the first blocker advances to `_pickle.c(4895)`, the C99 `for (size_t i = ...)` declaration in the next `_pickle.c` function; `total=16 compiled=15 cached=0 skipped=0`. | +| `bash -n scripts/vc6-probe-pythoncore-frontier.test.sh` plus public, core, PathCch, getpath, stdint, and frontier regression suites | exit 0; every suite reported `ALL TESTS PASSED`. | +| `git -C cpython diff --check` | exit 0. | +| pristine detached `v3.11.16` worktree `git apply --check` for the regenerated patch | exit 0; temporary worktree removed. | + +**Current compile-frontier state:** `_pickle.c` through `Pickler_traverse()` compiles cleanly under VC6. The next frontier is `_pickle.c(4895)`, a distinct C89 declaration-order defect in a later `for` initializer. This remains compiler-probe progress only: no linked `pythoncore.dll`/`python.exe`, Wine execution of Python, or real Windows 98 SE execution is claimed. + +**Delegation note:** the focused Claude Code lane was launched with the required no-commit/no-reset scope but exited without producing a usable report or changes; implementation and verification were performed directly, with no independent review claimed. + + Baseline: CPython `v3.11.16` Compiler: MSVC 6.0 (`cl.exe` 12.00.8804), from external `MSVC600` Host test environment: Linux + Wine diff --git a/compat/msvc600/cpython-3.11.16-vc6-headers.patch b/compat/msvc600/cpython-3.11.16-vc6-headers.patch index 0082edc..5ee0c09 100644 --- a/compat/msvc600/cpython-3.11.16-vc6-headers.patch +++ b/compat/msvc600/cpython-3.11.16-vc6-headers.patch @@ -1,3 +1,19 @@ +diff --git a/Include/cpython/object.h b/Include/cpython/object.h +index b018dab..8691994 100644 +--- a/Include/cpython/object.h ++++ b/Include/cpython/object.h +@@ -45,7 +45,11 @@ typedef struct _Py_Identifier { + // For now we are keeping _Py_IDENTIFIER for continued use + // in non-builtin extensions (and naughty PyPI modules). + ++#if defined(_MSC_VER) && _MSC_VER < 1300 ++#define _Py_static_string_init(value) { value, -1 } ++#else + #define _Py_static_string_init(value) { .string = value, .index = -1 } ++#endif + #define _Py_static_string(varname, value) static _Py_Identifier varname = _Py_static_string_init(value) + #define _Py_IDENTIFIER(varname) _Py_static_string(PyId_##varname, #varname) + diff --git a/Include/internal/pycore_atomic.h b/Include/internal/pycore_atomic.h index 425d69f..748de28 100644 --- a/Include/internal/pycore_atomic.h @@ -476,8 +492,28 @@ index a676e16..017e86d 100644 XML_Bool (*SetBillionLaughsAttackProtectionMaximumAmplification)( XML_Parser parser, float maxAmplificationFactor); /* might be NULL for expat < 2.8.0 */ +diff --git a/Include/pymath.h b/Include/pymath.h +index 772b67e..7b90016 100644 +--- a/Include/pymath.h ++++ b/Include/pymath.h +@@ -52,10 +52,13 @@ + + // Py_NAN: Value that evaluates to a quiet Not-a-Number (NaN). + #if !defined(Py_NAN) +-# if _Py__has_builtin(__builtin_nan) ++# if defined(_MSC_VER) && _MSC_VER < 1300 ++ // VC6 has no C99 NAN macro. IEEE infinity times zero produces NaN. ++# define Py_NAN (Py_HUGE_VAL * 0.0) ++# elif _Py__has_builtin(__builtin_nan) + // Built-in implementation of the ISO C99 function nan(): quiet NaN. + # define Py_NAN (__builtin_nan("")) +-#else ++# else + // Use C99 NAN constant: quiet Not-A-Number. + // NAN is a float, Py_NAN is a double: cast to double. + # define Py_NAN ((double)NAN) diff --git a/Include/pyport.h b/Include/pyport.h -index b3b8b6f..ae930fc 100644 +index b3b8b6f..938d131 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -97,6 +97,13 @@ Used in: Py_SAFE_DOWNCAST @@ -524,6 +560,15 @@ index b3b8b6f..ae930fc 100644 #else #define _Py_COMP_DIAG_PUSH #define _Py_COMP_DIAG_IGNORE_DEPR_DECLS +@@ -425,7 +439,7 @@ extern "C" { + // Py_NO_INLINE static int random(void) { return 4; } + #if defined(__GNUC__) || defined(__clang__) || defined(__INTEL_COMPILER) + # define Py_NO_INLINE __attribute__ ((noinline)) +-#elif defined(_MSC_VER) ++#elif defined(_MSC_VER) && _MSC_VER >= 1300 + # define Py_NO_INLINE __declspec(noinline) + #else + # define Py_NO_INLINE diff --git a/Include/pythread.h b/Include/pythread.h index a483290..defdaf1 100644 --- a/Include/pythread.h @@ -1070,6 +1115,59 @@ index 93478f5..afd2e33 100644 }; PyMODINIT_FUNC +diff --git a/Modules/_blake2/blake2s_impl.c b/Modules/_blake2/blake2s_impl.c +index 1c47328..6104437 100644 +--- a/Modules/_blake2/blake2s_impl.c ++++ b/Modules/_blake2/blake2s_impl.c +@@ -91,7 +91,7 @@ static PyObject * + py_blake2s_new_impl(PyTypeObject *type, PyObject *data, int digest_size, + Py_buffer *key, Py_buffer *salt, Py_buffer *person, + int fanout, int depth, unsigned long leaf_size, +- unsigned long long node_offset, int node_depth, ++ unsigned PY_LONG_LONG node_offset, int node_depth, + int inner_size, int last_node, int usedforsecurity) + /*[clinic end generated code: output=556181f73905c686 input=4dda87723f23abb0]*/ + { +@@ -160,7 +160,7 @@ py_blake2s_new_impl(PyTypeObject *type, PyObject *data, int digest_size, + store32(&(self->param.leaf_length), leaf_size); + + #ifdef HAVE_BLAKE2S +- if (node_offset > 0xFFFFFFFFFFFFULL) { ++ if (node_offset > PY_ULL(0xFFFFFFFFFFFF)) { + /* maximum 2**48 - 1 */ + PyErr_SetString(PyExc_OverflowError, "node_offset is too large"); + goto error; +@@ -385,6 +385,7 @@ static void + py_blake2s_dealloc(PyObject *self) + { + BLAKE2sObject *obj = (BLAKE2sObject *)self; ++ PyTypeObject *type; + + /* Try not to leave state in memory. */ + secure_zero_memory(&obj->param, sizeof(obj->param)); +@@ -394,7 +395,7 @@ py_blake2s_dealloc(PyObject *self) + obj->lock = NULL; + } + +- PyTypeObject *type = Py_TYPE(self); ++ type = Py_TYPE(self); + PyObject_Free(self); + Py_DECREF(type); + } +@@ -409,8 +410,9 @@ static PyType_Slot blake2s_type_slots[] = { + }; + + PyType_Spec blake2s_type_spec = { +- .name = "_blake2.blake2s", +- .basicsize = sizeof(BLAKE2sObject), +- .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE, +- .slots = blake2s_type_slots ++ "_blake2.blake2s", ++ sizeof(BLAKE2sObject), ++ 0, ++ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE, ++ blake2s_type_slots + }; diff --git a/Modules/_blake2/clinic/blake2b_impl.c.h b/Modules/_blake2/clinic/blake2b_impl.c.h index 4e74e08..4b079b3 100644 --- a/Modules/_blake2/clinic/blake2b_impl.c.h @@ -1088,6 +1186,28 @@ index 4e74e08..4b079b3 100644 int depth = 1; unsigned long leaf_size = 0; - unsigned long long node_offset = 0; ++ unsigned PY_LONG_LONG node_offset = 0; + int node_depth = 0; + int inner_size = 0; + int last_node = 0; +diff --git a/Modules/_blake2/clinic/blake2s_impl.c.h b/Modules/_blake2/clinic/blake2s_impl.c.h +index 0f0d983..a25b6cb 100644 +--- a/Modules/_blake2/clinic/blake2s_impl.c.h ++++ b/Modules/_blake2/clinic/blake2s_impl.c.h +@@ -15,7 +15,7 @@ static PyObject * + py_blake2s_new_impl(PyTypeObject *type, PyObject *data, int digest_size, + Py_buffer *key, Py_buffer *salt, Py_buffer *person, + int fanout, int depth, unsigned long leaf_size, +- unsigned long long node_offset, int node_depth, ++ unsigned PY_LONG_LONG node_offset, int node_depth, + int inner_size, int last_node, int usedforsecurity); + + static PyObject * +@@ -36,7 +36,7 @@ py_blake2s_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) + int fanout = 1; + int depth = 1; + unsigned long leaf_size = 0; +- unsigned long long node_offset = 0; + unsigned PY_LONG_LONG node_offset = 0; int node_depth = 0; int inner_size = 0; @@ -1175,6 +1295,3644 @@ index e58c436..b386ac5 100644 S->h[i] ^= load64( p + sizeof( S->h[i] ) * i ); S->outlen = P->digest_length; +diff --git a/Modules/_blake2/impl/blake2s-ref.c b/Modules/_blake2/impl/blake2s-ref.c +index ab86cc1..12b89d9 100644 +--- a/Modules/_blake2/impl/blake2s-ref.c ++++ b/Modules/_blake2/impl/blake2s-ref.c +@@ -131,9 +131,11 @@ static inline int blake2s_param_set_personal( blake2s_param *P, const uint8_t pe + + static inline int blake2s_init0( blake2s_state *S ) + { ++ int i; ++ + memset( S, 0, sizeof( blake2s_state ) ); + +- for( int i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i]; ++ for( i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i]; + + return 0; + } +@@ -154,11 +156,14 @@ extern "C" { + /* init2 xors IV with input parameter block */ + int blake2s_init_param( blake2s_state *S, const blake2s_param *P ) + { ++ uint32_t *p; ++ size_t i; ++ + blake2s_init0( S ); +- uint32_t *p = ( uint32_t * )( P ); ++ p = ( uint32_t * )( P ); + + /* IV XOR ParamBlock */ +- for( size_t i = 0; i < 8; ++i ) ++ for( i = 0; i < 8; ++i ) + S->h[i] ^= load32( &p[i] ); + + S->outlen = P->digest_length; +@@ -224,11 +229,12 @@ static int blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCK + { + uint32_t m[16]; + uint32_t v[16]; ++ size_t i; + +- for( size_t i = 0; i < 16; ++i ) ++ for( i = 0; i < 16; ++i ) + m[i] = load32( block + i * sizeof( m[i] ) ); + +- for( size_t i = 0; i < 8; ++i ) ++ for( i = 0; i < 8; ++i ) + v[i] = S->h[i]; + + v[ 8] = blake2s_IV[0]; +@@ -272,7 +278,7 @@ static int blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCK + ROUND( 8 ); + ROUND( 9 ); + +- for( size_t i = 0; i < 8; ++i ) ++ for( i = 0; i < 8; ++i ) + S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; + + #undef G +diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c +index 900d906..1cba998 100644 +--- a/Modules/_collectionsmodule.c ++++ b/Modules/_collectionsmodule.c +@@ -2138,6 +2138,7 @@ static PyObject* + defdict_or(PyObject* left, PyObject* right) + { + PyObject *self, *other; ++ PyObject *new; + if (PyObject_TypeCheck(left, &defdict_type)) { + self = left; + other = right; +@@ -2151,7 +2152,7 @@ defdict_or(PyObject* left, PyObject* right) + } + // Like copy(), this calls the object's class. + // Override __or__/__ror__ for subclasses with different constructors. +- PyObject *new = new_defdict((defdictobject*)self, left); ++ new = new_defdict((defdictobject*)self, left); + if (!new) { + return NULL; + } +@@ -2162,9 +2163,7 @@ defdict_or(PyObject* left, PyObject* right) + return new; + } + +-static PyNumberMethods defdict_as_number = { +- .nb_or = defdict_or, +-}; ++static PyNumberMethods defdict_as_number; + + static int + defdict_traverse(PyObject *self, visitproc visit, void *arg) +@@ -2295,6 +2294,7 @@ _collections__count_elements_impl(PyObject *module, PyObject *mapping, + PyObject *mapping_setitem; + PyObject *dict_setitem; + PyObject *one = _PyLong_GetOne(); // borrowed reference ++ PyObject *zero; + + it = PyObject_GetIter(iterable); + if (it == NULL) +@@ -2359,7 +2359,7 @@ _collections__count_elements_impl(PyObject *module, PyObject *mapping, + if (bound_get == NULL) + goto done; + +- PyObject *zero = _PyLong_GetZero(); // borrowed reference ++ zero = _PyLong_GetZero(); // borrowed reference + while (1) { + key = PyIter_Next(it); + if (key == NULL) +@@ -2580,10 +2580,12 @@ collections_exec(PyObject *module) { + &dequereviter_type, + &tuplegetter_type + }; ++ size_t i; + ++ defdict_as_number.nb_or = defdict_or; + defdict_type.tp_base = &PyDict_Type; + +- for (size_t i = 0; i < Py_ARRAY_LENGTH(typelist); i++) { ++ for (i = 0; i < Py_ARRAY_LENGTH(typelist); i++) { + if (PyModule_AddType(module, typelist[i]) < 0) { + return -1; + } +diff --git a/Modules/_csv.c b/Modules/_csv.c +index 045b71a..3c16361 100644 +--- a/Modules/_csv.c ++++ b/Modules/_csv.c +@@ -242,6 +242,7 @@ _set_int(const char *name, int *target, PyObject *src, int dflt) + static int + _set_char_or_none(const char *name, Py_UCS4 *target, PyObject *src, Py_UCS4 dflt) + { ++ Py_ssize_t len; + if (src == NULL) { + *target = dflt; + } +@@ -254,7 +255,7 @@ _set_char_or_none(const char *name, Py_UCS4 *target, PyObject *src, Py_UCS4 dflt + Py_TYPE(src)->tp_name); + return -1; + } +- Py_ssize_t len = PyUnicode_GetLength(src); ++ len = PyUnicode_GetLength(src); + if (len < 0) { + return -1; + } +@@ -274,6 +275,7 @@ _set_char_or_none(const char *name, Py_UCS4 *target, PyObject *src, Py_UCS4 dflt + static int + _set_char(const char *name, Py_UCS4 *target, PyObject *src, Py_UCS4 dflt) + { ++ Py_ssize_t len; + if (src == NULL) { + *target = dflt; + } +@@ -284,7 +286,7 @@ _set_char(const char *name, Py_UCS4 *target, PyObject *src, Py_UCS4 dflt) + Py_TYPE(src)->tp_name); + return -1; + } +- Py_ssize_t len = PyUnicode_GetLength(src); ++ len = PyUnicode_GetLength(src); + if (len < 0) { + return -1; + } +@@ -381,10 +383,11 @@ static _csvstate * + _csv_state_from_type(PyTypeObject *type, const char *name) + { + PyObject *module = PyType_GetModuleByDef(type, &_csvmodule); ++ _csvstate *module_state; + if (module == NULL) { + return NULL; + } +- _csvstate *module_state = PyModule_GetState(module); ++ module_state = PyModule_GetState(module); + if (module_state == NULL) { + PyErr_Format(PyExc_SystemError, + "%s: No _csv module state found", name); +@@ -398,6 +401,7 @@ dialect_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) + { + DialectObj *self; + PyObject *ret = NULL; ++ _csvstate *module_state; + PyObject *dialect = NULL; + PyObject *delimiter = NULL; + PyObject *doublequote = NULL; +@@ -421,7 +425,7 @@ dialect_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) + &strict)) + return NULL; + +- _csvstate *module_state = _csv_state_from_type(type, "dialect_new"); ++ module_state = _csv_state_from_type(type, "dialect_new"); + if (module_state == NULL) { + return NULL; + } +@@ -581,11 +585,12 @@ static PyType_Slot Dialect_Type_slots[] = { + }; + + PyType_Spec Dialect_Type_spec = { +- .name = "_csv.Dialect", +- .basicsize = sizeof(DialectObj), +- .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | +- Py_TPFLAGS_IMMUTABLETYPE), +- .slots = Dialect_Type_slots, ++ "_csv.Dialect", ++ sizeof(DialectObj), ++ 0, ++ (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | ++ Py_TPFLAGS_IMMUTABLETYPE), ++ Dialect_Type_slots + }; + + +@@ -639,10 +644,12 @@ parse_save_field(ReaderObj *self) + static int + parse_grow_buff(ReaderObj *self) + { ++ Py_ssize_t field_size_new; ++ Py_UCS4 *field_new; + assert((size_t)self->field_size <= PY_SSIZE_T_MAX / sizeof(Py_UCS4)); + +- Py_ssize_t field_size_new = self->field_size ? 2 * self->field_size : 4096; +- Py_UCS4 *field_new = self->field; ++ field_size_new = self->field_size ? 2 * self->field_size : 4096; ++ field_new = self->field; + PyMem_Resize(field_new, Py_UCS4, field_size_new); + if (field_new == NULL) { + PyErr_NoMemory(); +@@ -998,11 +1005,12 @@ static PyType_Slot Reader_Type_slots[] = { + }; + + PyType_Spec Reader_Type_spec = { +- .name = "_csv.reader", +- .basicsize = sizeof(ReaderObj), +- .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | +- Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION), +- .slots = Reader_Type_slots ++ "_csv.reader", ++ sizeof(ReaderObj), ++ 0, ++ (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | ++ Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION), ++ Reader_Type_slots + }; + + +@@ -1435,11 +1443,12 @@ static PyType_Slot Writer_Type_slots[] = { + }; + + PyType_Spec Writer_Type_spec = { +- .name = "_csv.writer", +- .basicsize = sizeof(WriterObj), +- .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | +- Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION), +- .slots = Writer_Type_slots, ++ "_csv.writer", ++ sizeof(WriterObj), ++ 0, ++ (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | ++ Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION), ++ Writer_Type_slots + }; + + +@@ -1616,9 +1625,11 @@ static PyType_Slot error_slots[] = { + }; + + PyType_Spec error_spec = { +- .name = "_csv.Error", +- .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, +- .slots = error_slots, ++ "_csv.Error", ++ 0, ++ 0, ++ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, ++ error_slots + }; + + /* +@@ -1734,6 +1745,7 @@ static int + csv_exec(PyObject *module) { + const StyleDesc *style; + PyObject *temp; ++ PyObject *bases; + _csvstate *module_state = get_csv_state(module); + + temp = PyType_FromModuleAndSpec(module, &Dialect_Type_spec, NULL); +@@ -1777,7 +1789,7 @@ csv_exec(PyObject *module) { + } + + /* Add the CSV exception object to the module. */ +- PyObject *bases = PyTuple_Pack(1, PyExc_Exception); ++ bases = PyTuple_Pack(1, PyExc_Exception); + if (bases == NULL) { + return -1; + } +diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c +index df0ce72..dc29ee8 100644 +--- a/Modules/_datetimemodule.c ++++ b/Modules/_datetimemodule.c +@@ -398,6 +398,9 @@ iso_week1_monday(int year) + static int + iso_to_ymd(const int iso_year, const int iso_week, const int iso_day, + int *year, int *month, int *day) { ++ int day_1; ++ int day_offset; ++ + if (iso_week <= 0 || iso_week >= 53) { + int out_of_range = 1; + if (iso_week == 53) { +@@ -419,9 +422,9 @@ iso_to_ymd(const int iso_year, const int iso_week, const int iso_day, + } + + // Convert (Y, W, D) to (Y, M, D) in-place +- int day_1 = iso_week1_monday(iso_year); ++ day_1 = iso_week1_monday(iso_year); + +- int day_offset = (iso_week - 1)*7 + iso_day - 1; ++ day_offset = (iso_week - 1)*7 + iso_day - 1; + + ord_to_ymd(day_1 + day_offset, year, month, day); + return 0; +@@ -721,7 +724,9 @@ is_digit(const char c) { + static const char * + parse_digits(const char *ptr, int *var, size_t num_digits) + { +- for (size_t i = 0; i < num_digits; ++i) { ++ size_t i; ++ ++ for (i = 0; i < num_digits; ++i) { + unsigned int tmp = (unsigned int)(*(ptr++) - '0'); + if (tmp > 9) { + return NULL; +@@ -747,12 +752,16 @@ parse_isoformat_date(const char *dtstr, const size_t len, int *year, int *month, + * -5, -6: Failure in iso_to_ymd + */ + const char *p = dtstr; ++ unsigned char uses_separator; ++ int iso_week; ++ int iso_day; ++ int rv; + p = parse_digits(p, year, 4); + if (NULL == p) { + return -1; + } + +- const unsigned char uses_separator = (*p == '-'); ++ uses_separator = (*p == '-'); + if (uses_separator) { + ++p; + } +@@ -760,8 +769,8 @@ parse_isoformat_date(const char *dtstr, const size_t len, int *year, int *month, + if(*p == 'W') { + // This is an isocalendar-style date string + p++; +- int iso_week = 0; +- int iso_day = 0; ++ iso_week = 0; ++ iso_day = 0; + + p = parse_digits(p, &iso_week, 2); + if (NULL == p) { +@@ -782,7 +791,7 @@ parse_isoformat_date(const char *dtstr, const size_t len, int *year, int *month, + iso_day = 1; + } + +- int rv = iso_to_ymd(*year, iso_week, iso_day, year, month, day); ++ rv = iso_to_ymd(*year, iso_week, iso_day, year, month, day); + if (rv) { + return -3 + rv; + } else { +@@ -809,21 +818,32 @@ static int + parse_hh_mm_ss_ff(const char *tstr, const char *tstr_end, int *hour, + int *minute, int *second, int *microsecond) + { +- *hour = *minute = *second = *microsecond = 0; + const char *p = tstr; + const char *p_end = tstr_end; +- int *vals[3] = {hour, minute, second}; ++ int *vals[3]; + // This is initialized to satisfy an erroneous compiler warning. + unsigned char has_separator = 1; ++ size_t i; ++ size_t len_remains; ++ size_t to_parse; ++ static int correction[] = { ++ 100000, 10000, 1000, 100, 10 ++ }; ++ ++ *hour = *minute = *second = *microsecond = 0; ++ vals[0] = hour; ++ vals[1] = minute; ++ vals[2] = second; + + // Parse [HH[:?MM[:?SS]]] +- for (size_t i = 0; i < 3; ++i) { ++ for (i = 0; i < 3; ++i) { ++ char c; + p = parse_digits(p, vals[i], 2); + if (NULL == p) { + return -3; + } + +- char c = *(p++); ++ c = *(p++); + if (i == 0) { + has_separator = (c == ':'); + } +@@ -844,8 +864,8 @@ parse_hh_mm_ss_ff(const char *tstr, const char *tstr_end, int *hour, + } + + // Parse fractional components +- size_t len_remains = p_end - p; +- size_t to_parse = len_remains; ++ len_remains = p_end - p; ++ to_parse = len_remains; + if (len_remains >= 6) { + to_parse = 6; + } +@@ -855,10 +875,6 @@ parse_hh_mm_ss_ff(const char *tstr, const char *tstr_end, int *hour, + return -3; + } + +- static int correction[] = { +- 100000, 10000, 1000, 100, 10 +- }; +- + if (to_parse < 6) { + *microsecond *= correction[to_parse-1]; + } +@@ -889,14 +905,20 @@ parse_isoformat_time(const char *dtstr, size_t dtlen, int *hour, int *minute, + const char *p_end = dtstr + dtlen; + + const char *tzinfo_pos = p; ++ int rv; ++ int tzsign; ++ int tzhour; ++ int tzminute; ++ int tzsecond; ++ + do { + if (*tzinfo_pos == 'Z' || *tzinfo_pos == '+' || *tzinfo_pos == '-') { + break; + } + } while (++tzinfo_pos < p_end); + +- int rv = parse_hh_mm_ss_ff(dtstr, tzinfo_pos, hour, minute, second, +- microsecond); ++ rv = parse_hh_mm_ss_ff(dtstr, tzinfo_pos, hour, minute, second, ++ microsecond); + + if (rv < 0) { + return rv; +@@ -924,9 +946,11 @@ parse_isoformat_time(const char *dtstr, size_t dtlen, int *hour, int *minute, + } + } + +- int tzsign = (*tzinfo_pos == '-') ? -1 : 1; ++ tzsign = (*tzinfo_pos == '-') ? -1 : 1; + tzinfo_pos++; +- int tzhour = 0, tzminute = 0, tzsecond = 0; ++ tzhour = 0; ++ tzminute = 0; ++ tzsecond = 0; + rv = parse_hh_mm_ss_ff(tzinfo_pos, p_end, &tzhour, &tzminute, &tzsecond, + tzmicrosecond); + +@@ -1401,6 +1425,7 @@ static inline PyObject * + tzinfo_from_isoformat_results(int rv, int tzoffset, int tz_useconds) + { + PyObject *tzinfo; ++ PyObject *delta; + if (rv == 1) { + // Create a timezone from offset in seconds (0 returns UTC) + if (tzoffset == 0) { +@@ -1408,7 +1433,7 @@ tzinfo_from_isoformat_results(int rv, int tzoffset, int tz_useconds) + return PyDateTime_TimeZone_UTC; + } + +- PyObject *delta = new_delta(0, tzoffset, tz_useconds, 1); ++ delta = new_delta(0, tzoffset, tz_useconds, 1); + if (delta == NULL) { + return NULL; + } +@@ -2629,13 +2654,15 @@ delta_bool(PyDateTime_Delta *self) + static PyObject * + delta_repr(PyDateTime_Delta *self) + { ++ const char *sep; ++ PyObject *repr; + PyObject *args = PyUnicode_FromString(""); + + if (args == NULL) { + return NULL; + } + +- const char *sep = ""; ++ sep = ""; + + if (GET_TD_DAYS(self) != 0) { + Py_SETREF(args, PyUnicode_FromFormat("days=%d", GET_TD_DAYS(self))); +@@ -2669,8 +2696,8 @@ delta_repr(PyDateTime_Delta *self) + } + } + +- PyObject *repr = PyUnicode_FromFormat("%s(%S)", Py_TYPE(self)->tp_name, +- args); ++ repr = PyUnicode_FromFormat("%s(%S)", Py_TYPE(self)->tp_name, ++ args); + Py_DECREF(args); + return repr; + } +@@ -3057,6 +3084,11 @@ date_fromordinal(PyObject *cls, PyObject *args) + static PyObject * + date_fromisoformat(PyObject *cls, PyObject *dtstr) + { ++ Py_ssize_t len; ++ const char *dt_ptr; ++ int year, month, day; ++ int rv; ++ + assert(dtstr != NULL); + + if (!PyUnicode_Check(dtstr)) { +@@ -3065,16 +3097,14 @@ date_fromisoformat(PyObject *cls, PyObject *dtstr) + return NULL; + } + +- Py_ssize_t len; +- +- const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr, &len); ++ dt_ptr = PyUnicode_AsUTF8AndSize(dtstr, &len); + if (dt_ptr == NULL) { + goto invalid_string_error; + } + +- int year = 0, month = 0, day = 0; +- +- int rv; ++ year = 0; ++ month = 0; ++ day = 0; + if (len == 7 || len == 8 || len == 10) { + rv = parse_isoformat_date(dt_ptr, len, &year, &month, &day); + } +@@ -3102,6 +3132,8 @@ date_fromisocalendar(PyObject *cls, PyObject *args, PyObject *kw) + }; + + int year, week, day; ++ int month; ++ int rv; + if (PyArg_ParseTupleAndKeywords(args, kw, "iii:fromisocalendar", + keywords, + &year, &week, &day) == 0) { +@@ -3119,8 +3151,7 @@ date_fromisocalendar(PyObject *cls, PyObject *args, PyObject *kw) + return NULL; + } + +- int month; +- int rv = iso_to_ymd(year, week, day, &year, &month, &day); ++ rv = iso_to_ymd(year, week, day, &year, &month, &day); + + + if (rv == -2) { +@@ -3312,14 +3343,16 @@ static PyObject * + iso_calendar_date_repr(PyDateTime_IsoCalendarDate *self) + { + PyObject* year = PyTuple_GetItem((PyObject *)self, 0); ++ PyObject* week; ++ PyObject* weekday; + if (year == NULL) { + return NULL; + } +- PyObject* week = PyTuple_GetItem((PyObject *)self, 1); ++ week = PyTuple_GetItem((PyObject *)self, 1); + if (week == NULL) { + return NULL; + } +- PyObject* weekday = PyTuple_GetItem((PyObject *)self, 2); ++ weekday = PyTuple_GetItem((PyObject *)self, 2); + if (weekday == NULL) { + return NULL; + } +@@ -3390,15 +3423,44 @@ static PyMethodDef iso_calendar_date_methods[] = { + + static PyTypeObject PyDateTime_IsoCalendarDateType = { + PyVarObject_HEAD_INIT(NULL, 0) +- .tp_name = "datetime.IsoCalendarDate", +- .tp_basicsize = sizeof(PyDateTime_IsoCalendarDate), +- .tp_repr = (reprfunc) iso_calendar_date_repr, +- .tp_flags = Py_TPFLAGS_DEFAULT, +- .tp_doc = iso_calendar_date__doc__, +- .tp_methods = iso_calendar_date_methods, +- .tp_getset = iso_calendar_date_getset, +- // .tp_base = &PyTuple_Type, // filled in PyInit__datetime +- .tp_new = iso_calendar_date_new, ++ "datetime.IsoCalendarDate", ++ sizeof(PyDateTime_IsoCalendarDate), ++ 0, ++ 0, ++ 0, ++ 0, ++ 0, ++ 0, ++ (reprfunc) iso_calendar_date_repr, ++ 0, ++ 0, ++ 0, ++ 0, ++ 0, ++ 0, ++ PyObject_GenericGetAttr, ++ 0, ++ 0, ++ Py_TPFLAGS_DEFAULT, ++ iso_calendar_date__doc__, ++ 0, ++ 0, ++ 0, ++ 0, ++ 0, ++ 0, ++ iso_calendar_date_methods, ++ 0, ++ iso_calendar_date_getset, ++ 0, ++ 0, ++ 0, ++ 0, ++ 0, ++ 0, ++ 0, ++ iso_calendar_date_new, ++ 0, + }; + + /*[clinic input] +@@ -3431,6 +3493,7 @@ iso_calendar_date_new_impl(PyTypeObject *type, int year, int week, + static PyObject * + date_isocalendar(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) + { ++ PyObject* v; + int year = GET_YEAR(self); + int week1_monday = iso_week1_monday(year); + int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self)); +@@ -3448,7 +3511,7 @@ date_isocalendar(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) + week = 0; + } + +- PyObject* v = iso_calendar_date_new_impl(&PyDateTime_IsoCalendarDateType, ++ v = iso_calendar_date_new_impl(&PyDateTime_IsoCalendarDateType, + year, week + 1, day + 1); + if (v == NULL) { + return NULL; +@@ -4626,6 +4689,14 @@ time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw) + + static PyObject * + time_fromisoformat(PyObject *cls, PyObject *tstr) { ++ Py_ssize_t len; ++ const char *p; ++ int hour, minute, second, microsecond; ++ int tzoffset, tzimicrosecond; ++ int rv; ++ PyObject *tzinfo; ++ PyObject *t; ++ + assert(tstr != NULL); + + if (!PyUnicode_Check(tstr)) { +@@ -4633,8 +4704,7 @@ time_fromisoformat(PyObject *cls, PyObject *tstr) { + return NULL; + } + +- Py_ssize_t len; +- const char *p = PyUnicode_AsUTF8AndSize(tstr, &len); ++ p = PyUnicode_AsUTF8AndSize(tstr, &len); + + if (p == NULL) { + goto invalid_string_error; +@@ -4648,24 +4718,23 @@ time_fromisoformat(PyObject *cls, PyObject *tstr) { + len -= 1; + } + +- int hour = 0, minute = 0, second = 0, microsecond = 0; +- int tzoffset = 0, tzimicrosecond = 0; +- int rv = parse_isoformat_time(p, len, +- &hour, &minute, &second, µsecond, +- &tzoffset, &tzimicrosecond); ++ hour = minute = second = microsecond = 0; ++ tzoffset = tzimicrosecond = 0; ++ rv = parse_isoformat_time(p, len, ++ &hour, &minute, &second, µsecond, ++ &tzoffset, &tzimicrosecond); + + if (rv < 0) { + goto invalid_string_error; + } + +- PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset, +- tzimicrosecond); ++ tzinfo = tzinfo_from_isoformat_results(rv, tzoffset, ++ tzimicrosecond); + + if (tzinfo == NULL) { + return NULL; + } + +- PyObject *t; + if ( (PyTypeObject *)cls == &PyDateTime_TimeType ) { + t = new_time(hour, minute, second, microsecond, tzinfo, 0); + } else { +@@ -4981,15 +5050,15 @@ typedef int (*TM_FUNC)(time_t timer, struct tm*); + + /* As of version 2015f max fold in IANA database is + * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */ +-static long long max_fold_seconds = 24 * 3600; ++static PY_LONG_LONG max_fold_seconds = 24 * 3600; + /* NB: date(1970,1,1).toordinal() == 719163 */ +-static long long epoch = 719163LL * 24 * 60 * 60; ++static PY_LONG_LONG epoch = PY_LL(719163) * 24 * 60 * 60; + +-static long long ++static PY_LONG_LONG + utc_to_seconds(int year, int month, int day, + int hour, int minute, int second) + { +- long long ordinal; ++ PY_LONG_LONG ordinal; + + /* ymd_to_ord() doesn't support year <= 0 */ + if (year < MINYEAR || year > MAXYEAR) { +@@ -5001,8 +5070,8 @@ utc_to_seconds(int year, int month, int day, + return ((ordinal * 24 + hour) * 60 + minute) * 60 + second; + } + +-static long long +-local(long long u) ++static PY_LONG_LONG ++local(PY_LONG_LONG u) + { + struct tm local_time; + time_t t; +@@ -5067,7 +5136,7 @@ datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us, + && (timet - max_fold_seconds > 0) + #endif + ) { +- long long probe_seconds, result_seconds, transition; ++ PY_LONG_LONG probe_seconds, result_seconds, transition; + + result_seconds = utc_to_seconds(year, month, day, + hour, minute, second); +@@ -5272,6 +5341,12 @@ datetime_combine(PyObject *cls, PyObject *args, PyObject *kw) + static PyObject * + _sanitize_isoformat_str(PyObject *dtstr) + { ++ static const size_t potential_separators[3] = {7, 8, 10}; ++ const void *unicode_data; ++ unsigned int kind; ++ size_t surrogate_separator; ++ size_t idx; ++ PyObject *str_out; + Py_ssize_t len = PyUnicode_GetLength(dtstr); + if (len < 7) { // All valid ISO 8601 strings are at least 7 characters long + return NULL; +@@ -5283,17 +5358,16 @@ _sanitize_isoformat_str(PyObject *dtstr) + // replaces any surrogate character separators with `T`. + // + // The result of this, if not NULL, returns a new reference +- const void* const unicode_data = PyUnicode_DATA(dtstr); +- const unsigned int kind = PyUnicode_KIND(dtstr); ++ unicode_data = PyUnicode_DATA(dtstr); ++ kind = PyUnicode_KIND(dtstr); + + // Depending on the format of the string, the separator can only ever be + // in positions 7, 8 or 10. We'll check each of these for a surrogate and + // if we find one, replace it with `T`. If there is more than one surrogate, + // we don't have to bother sanitizing it, because the function will later + // fail when we try to encode the string as ASCII. +- static const size_t potential_separators[3] = {7, 8, 10}; +- size_t surrogate_separator = 0; +- for(size_t idx = 0; ++ surrogate_separator = 0; ++ for (idx = 0; + idx < sizeof(potential_separators) / sizeof(*potential_separators); + ++idx) { + size_t pos = potential_separators[idx]; +@@ -5312,7 +5386,7 @@ _sanitize_isoformat_str(PyObject *dtstr) + return dtstr; + } + +- PyObject *str_out = _PyUnicode_Copy(dtstr); ++ str_out = _PyUnicode_Copy(dtstr); + if (str_out == NULL) { + return NULL; + } +@@ -5428,6 +5502,18 @@ _find_isoformat_datetime_separator(const char *dtstr, Py_ssize_t len) { + static PyObject * + datetime_fromisoformat(PyObject *cls, PyObject *dtstr) + { ++ PyObject *dtstr_clean; ++ Py_ssize_t len; ++ const char *dt_ptr; ++ Py_ssize_t separator_location; ++ const char *p; ++ int year, month, day; ++ int hour, minute, second, microsecond; ++ int tzoffset, tzusec; ++ int rv; ++ PyObject *tzinfo; ++ PyObject *dt; ++ + assert(dtstr != NULL); + + if (!PyUnicode_Check(dtstr)) { +@@ -5441,13 +5527,12 @@ datetime_fromisoformat(PyObject *cls, PyObject *dtstr) + // we don't have to sanitize it anything because that can only happen when + // the separator is either '-' or a number. This should mostly be a noop + // but it makes the reference counting easier if we still sanitize. +- PyObject *dtstr_clean = _sanitize_isoformat_str(dtstr); ++ dtstr_clean = _sanitize_isoformat_str(dtstr); + if (dtstr_clean == NULL) { + goto invalid_string_error; + } + +- Py_ssize_t len; +- const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr_clean, &len); ++ dt_ptr = PyUnicode_AsUTF8AndSize(dtstr_clean, &len); + + if (dt_ptr == NULL) { + if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) { +@@ -5459,18 +5544,18 @@ datetime_fromisoformat(PyObject *cls, PyObject *dtstr) + } + } + +- const Py_ssize_t separator_location = _find_isoformat_datetime_separator( ++ separator_location = _find_isoformat_datetime_separator( + dt_ptr, len); + + +- const char *p = dt_ptr; ++ p = dt_ptr; + +- int year = 0, month = 0, day = 0; +- int hour = 0, minute = 0, second = 0, microsecond = 0; +- int tzoffset = 0, tzusec = 0; ++ year = 0; month = 0; day = 0; ++ hour = 0; minute = 0; second = 0; microsecond = 0; ++ tzoffset = 0; tzusec = 0; + + // date runs up to separator_location +- int rv = parse_isoformat_date(p, separator_location, &year, &month, &day); ++ rv = parse_isoformat_date(p, separator_location, &year, &month, &day); + + if (!rv && len > separator_location) { + // In UTF-8, the length of multi-byte characters is encoded in the MSB +@@ -5500,13 +5585,13 @@ datetime_fromisoformat(PyObject *cls, PyObject *dtstr) + goto invalid_string_error; + } + +- PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset, tzusec); ++ tzinfo = tzinfo_from_isoformat_results(rv, tzoffset, tzusec); + if (tzinfo == NULL) { + goto error; + } + +- PyObject *dt = new_datetime_subclass_ex(year, month, day, hour, minute, +- second, microsecond, tzinfo, cls); ++ dt = new_datetime_subclass_ex(year, month, day, hour, minute, ++ second, microsecond, tzinfo, cls); + + Py_DECREF(tzinfo); + Py_DECREF(dtstr_clean); +@@ -6172,14 +6257,14 @@ local_timezone(PyDateTime_DateTime *utc_time) + return local_timezone_from_timestamp(timestamp); + } + +-static long long ++static PY_LONG_LONG + local_to_seconds(int year, int month, int day, + int hour, int minute, int second, int fold); + + static PyObject * + local_timezone_from_local(PyDateTime_DateTime *local_dt) + { +- long long seconds; ++ PY_LONG_LONG seconds; + time_t timestamp; + seconds = local_to_seconds(GET_YEAR(local_dt), + GET_MONTH(local_dt), +@@ -6324,11 +6409,11 @@ datetime_timetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) + dstflag); + } + +-static long long ++static PY_LONG_LONG + local_to_seconds(int year, int month, int day, + int hour, int minute, int second, int fold) + { +- long long t, a, b, u1, u2, t1, t2, lt; ++ PY_LONG_LONG t, a, b, u1, u2, t1, t2, lt; + t = utc_to_seconds(year, month, day, hour, minute, second); + /* Our goal is to solve t = local(u) for u. */ + lt = local(t); +@@ -6372,7 +6457,7 @@ local_to_seconds(int year, int month, int day, + } + + /* date(1970,1,1).toordinal() == 719163 */ +-#define EPOCH_SECONDS (719163LL * 24 * 60 * 60) ++#define EPOCH_SECONDS (PY_LL(719163) * 24 * 60 * 60) + + static PyObject * + datetime_timestamp(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) +@@ -6388,7 +6473,7 @@ datetime_timestamp(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) + Py_DECREF(delta); + } + else { +- long long seconds; ++ PY_LONG_LONG seconds; + seconds = local_to_seconds(GET_YEAR(self), + GET_MONTH(self), + GET_DAY(self), +@@ -6719,13 +6804,6 @@ datetime_destructor(PyObject *op) + static int + _datetime_exec(PyObject *module) + { +- // `&...` is not a constant expression according to a strict reading +- // of C standards. Fill tp_base at run-time rather than statically. +- // See https://bugs.python.org/issue40777 +- PyDateTime_IsoCalendarDateType.tp_base = &PyTuple_Type; +- PyDateTime_TimeZoneType.tp_base = &PyDateTime_TZInfoType; +- PyDateTime_DateTimeType.tp_base = &PyDateTime_DateType; +- + PyTypeObject *types[] = { + &PyDateTime_DateType, + &PyDateTime_DateTimeType, +@@ -6734,8 +6812,20 @@ _datetime_exec(PyObject *module) + &PyDateTime_TZInfoType, + &PyDateTime_TimeZoneType, + }; ++ size_t i; ++ PyObject *d; ++ PyObject *delta; ++ PyObject *x; ++ PyDateTime_CAPI *capi; ++ ++ // `&...` is not a constant expression according to a strict reading ++ // of C standards. Fill tp_base at run-time rather than statically. ++ // See https://bugs.python.org/issue40777 ++ PyDateTime_IsoCalendarDateType.tp_base = &PyTuple_Type; ++ PyDateTime_TimeZoneType.tp_base = &PyDateTime_TZInfoType; ++ PyDateTime_DateTimeType.tp_base = &PyDateTime_DateType; + +- for (size_t i = 0; i < Py_ARRAY_LENGTH(types); i++) { ++ for (i = 0; i < Py_ARRAY_LENGTH(types); i++) { + if (PyModule_AddType(module, types[i]) < 0) { + return -1; + } +@@ -6759,7 +6849,7 @@ _datetime_exec(PyObject *module) + } while(0) + + /* timedelta values */ +- PyObject *d = PyDateTime_DeltaType.tp_dict; ++ d = PyDateTime_DeltaType.tp_dict; + DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0)); + DATETIME_ADD_MACRO(d, "min", new_delta(-MAX_DELTA_DAYS, 0, 0, 0)); + DATETIME_ADD_MACRO(d, "max", +@@ -6787,12 +6877,12 @@ _datetime_exec(PyObject *module) + + /* timezone values */ + d = PyDateTime_TimeZoneType.tp_dict; +- PyObject *delta = new_delta(0, 0, 0, 0); ++ delta = new_delta(0, 0, 0, 0); + if (delta == NULL) { + return -1; + } + +- PyObject *x = create_timezone(delta, NULL); ++ x = create_timezone(delta, NULL); + Py_DECREF(delta); + if (x == NULL) { + return -1; +@@ -6840,7 +6930,7 @@ _datetime_exec(PyObject *module) + return -1; + } + +- PyDateTime_CAPI *capi = get_datetime_capi(); ++ capi = get_datetime_capi(); + if (capi == NULL) { + return -1; + } +@@ -6925,10 +7015,11 @@ _datetime_exec(PyObject *module) + + static struct PyModuleDef datetimemodule = { + PyModuleDef_HEAD_INIT, +- .m_name = "_datetime", +- .m_doc = "Fast implementation of the datetime type.", +- .m_size = -1, +- .m_methods = module_methods, ++ "_datetime", ++ "Fast implementation of the datetime type.", ++ -1, ++ module_methods, ++ NULL + }; + + PyMODINIT_FUNC +diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c +index 3abb7fd..072c07f 100644 +--- a/Modules/_functoolsmodule.c ++++ b/Modules/_functoolsmodule.c +@@ -192,8 +192,9 @@ partial_vectorcall_fallback(PyThreadState *tstate, partialobject *pto, + PyObject *const *args, size_t nargsf, + PyObject *kwnames) + { ++ Py_ssize_t nargs; + pto->vectorcall = NULL; +- Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); ++ nargs = PyVectorcall_NARGS(nargsf); + return _PyObject_MakeTpCall(tstate, (PyObject *)pto, + args, nargs, kwnames); + } +@@ -202,21 +203,33 @@ static PyObject * + partial_vectorcall(partialobject *pto, PyObject *const *args, + size_t nargsf, PyObject *kwnames) + { +- PyThreadState *tstate = _PyThreadState_GET(); ++ PyThreadState *tstate; ++ Py_ssize_t nargs; ++ Py_ssize_t nargs_total; ++ PyObject **pto_args; ++ Py_ssize_t pto_nargs; ++ PyObject **newargs; ++ PyObject *tmp; ++ PyObject *ret; ++ Py_ssize_t newnargs_total; ++ PyObject *small_stack[_PY_FASTCALL_SMALL_STACK]; ++ PyObject **stack; ++ ++ tstate = _PyThreadState_GET(); + + /* pto->kw is mutable, so need to check every time */ + if (PyDict_GET_SIZE(pto->kw)) { + return partial_vectorcall_fallback(tstate, pto, args, nargsf, kwnames); + } + +- Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); +- Py_ssize_t nargs_total = nargs; ++ nargs = PyVectorcall_NARGS(nargsf); ++ nargs_total = nargs; + if (kwnames != NULL) { + nargs_total += PyTuple_GET_SIZE(kwnames); + } + +- PyObject **pto_args = _PyTuple_ITEMS(pto->args); +- Py_ssize_t pto_nargs = PyTuple_GET_SIZE(pto->args); ++ pto_args = _PyTuple_ITEMS(pto->args); ++ pto_nargs = PyTuple_GET_SIZE(pto->args); + + /* Fast path if we're called without arguments */ + if (nargs_total == 0) { +@@ -227,20 +240,16 @@ partial_vectorcall(partialobject *pto, PyObject *const *args, + /* Fast path using PY_VECTORCALL_ARGUMENTS_OFFSET to prepend a single + * positional argument */ + if (pto_nargs == 1 && (nargsf & PY_VECTORCALL_ARGUMENTS_OFFSET)) { +- PyObject **newargs = (PyObject **)args - 1; +- PyObject *tmp = newargs[0]; ++ newargs = (PyObject **)args - 1; ++ tmp = newargs[0]; + newargs[0] = pto_args[0]; +- PyObject *ret = _PyObject_VectorcallTstate(tstate, pto->fn, ++ ret = _PyObject_VectorcallTstate(tstate, pto->fn, + newargs, nargs + 1, kwnames); + newargs[0] = tmp; + return ret; + } + +- Py_ssize_t newnargs_total = pto_nargs + nargs_total; +- +- PyObject *small_stack[_PY_FASTCALL_SMALL_STACK]; +- PyObject *ret; +- PyObject **stack; ++ newnargs_total = pto_nargs + nargs_total; + + if (newnargs_total <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) { + stack = small_stack; +@@ -285,12 +294,15 @@ partial_setvectorcall(partialobject *pto) + static PyObject * + partial_call(partialobject *pto, PyObject *args, PyObject *kwargs) + { ++ PyObject *kwargs2; ++ PyObject *args2; ++ PyObject *res; ++ + assert(PyCallable_Check(pto->fn)); + assert(PyTuple_Check(pto->args)); + assert(PyDict_Check(pto->kw)); + + /* Merge keywords */ +- PyObject *kwargs2; + if (PyDict_GET_SIZE(pto->kw) == 0) { + /* kwargs can be NULL */ + kwargs2 = kwargs; +@@ -315,13 +327,13 @@ partial_call(partialobject *pto, PyObject *args, PyObject *kwargs) + + /* Merge positional arguments */ + /* Note: tupleconcat() is optimized for empty tuples */ +- PyObject *args2 = PySequence_Concat(pto->args, args); ++ args2 = PySequence_Concat(pto->args, args); + if (args2 == NULL) { + Py_XDECREF(kwargs2); + return NULL; + } + +- PyObject *res = PyObject_Call(pto->fn, args2, kwargs2); ++ res = PyObject_Call(pto->fn, args2, kwargs2); + Py_DECREF(args2); + Py_XDECREF(kwargs2); + return res; +@@ -489,12 +501,13 @@ static PyType_Slot partial_type_slots[] = { + }; + + static PyType_Spec partial_type_spec = { +- .name = "functools.partial", +- .basicsize = sizeof(partialobject), +- .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | +- Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_VECTORCALL | +- Py_TPFLAGS_IMMUTABLETYPE, +- .slots = partial_type_slots ++ "functools.partial", ++ sizeof(partialobject), ++ 0, ++ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | ++ Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_VECTORCALL | ++ Py_TPFLAGS_IMMUTABLETYPE, ++ partial_type_slots + }; + + +@@ -558,11 +571,12 @@ static PyType_Slot keyobject_type_slots[] = { + }; + + static PyType_Spec keyobject_type_spec = { +- .name = "functools.KeyWrapper", +- .basicsize = sizeof(keyobject), +- .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | +- Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE), +- .slots = keyobject_type_slots ++ "functools.KeyWrapper", ++ sizeof(keyobject), ++ 0, ++ (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | ++ Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE), ++ keyobject_type_slots + }; + + static PyObject * +@@ -781,11 +795,12 @@ static PyType_Slot lru_list_elem_type_slots[] = { + }; + + static PyType_Spec lru_list_elem_type_spec = { +- .name = "functools._lru_list_elem", +- .basicsize = sizeof(lru_list_elem), +- .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | +- Py_TPFLAGS_IMMUTABLETYPE, +- .slots = lru_list_elem_type_slots ++ "functools._lru_list_elem", ++ sizeof(lru_list_elem), ++ 0, ++ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | ++ Py_TPFLAGS_IMMUTABLETYPE, ++ lru_list_elem_type_slots + }; + + +@@ -993,6 +1008,7 @@ bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds + { + lru_list_elem *link; + PyObject *key, *result, *testresult; ++ PyObject *oldkey, *oldresult, *popresult; + Py_hash_t hash; + + key = lru_cache_make_key(self->kwd_mark, args, kwds, self->typed); +@@ -1086,8 +1102,6 @@ bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds + make sense to reinsert the link, so we leave it out + and the cache will no longer register as full. + */ +- PyObject *oldkey, *oldresult, *popresult; +- + /* Extract the oldest item. */ + assert(self->root.next != &self->root); + link = self->root.next; +@@ -1345,10 +1359,13 @@ lru_cache_deepcopy(PyObject *self, PyObject *unused) + static int + lru_cache_tp_traverse(lru_cache_object *self, visitproc visit, void *arg) + { ++ lru_list_elem *link; ++ lru_list_elem *next; ++ + Py_VISIT(Py_TYPE(self)); +- lru_list_elem *link = self->root.next; ++ link = self->root.next; + while (link != &self->root) { +- lru_list_elem *next = link->next; ++ next = link->next; + Py_VISIT(link->key); + Py_VISIT(link->result); + Py_VISIT(Py_TYPE(link)); +@@ -1417,11 +1434,12 @@ static PyType_Slot lru_cache_type_slots[] = { + }; + + static PyType_Spec lru_cache_type_spec = { +- .name = "functools._lru_cache_wrapper", +- .basicsize = sizeof(lru_cache_object), +- .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | +- Py_TPFLAGS_METHOD_DESCRIPTOR | Py_TPFLAGS_IMMUTABLETYPE, +- .slots = lru_cache_type_slots ++ "functools._lru_cache_wrapper", ++ sizeof(lru_cache_object), ++ 0, ++ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | ++ Py_TPFLAGS_METHOD_DESCRIPTOR | Py_TPFLAGS_IMMUTABLETYPE, ++ lru_cache_type_slots + }; + + +@@ -1441,6 +1459,7 @@ static int + _functools_exec(PyObject *module) + { + _functools_state *state = get_functools_state(module); ++ PyObject *lru_cache_type; + state->kwd_mark = _PyObject_CallNoArgs((PyObject *)&PyBaseObject_Type); + if (state->kwd_mark == NULL) { + return -1; +@@ -1455,7 +1474,7 @@ _functools_exec(PyObject *module) + return -1; + } + +- PyObject *lru_cache_type = PyType_FromModuleAndSpec(module, ++ lru_cache_type = PyType_FromModuleAndSpec(module, + &lru_cache_type_spec, NULL); + if (lru_cache_type == NULL) { + return -1; +@@ -1520,14 +1539,14 @@ static struct PyModuleDef_Slot _functools_slots[] = { + + static struct PyModuleDef _functools_module = { + PyModuleDef_HEAD_INIT, +- .m_name = "_functools", +- .m_doc = _functools_doc, +- .m_size = sizeof(_functools_state), +- .m_methods = _functools_methods, +- .m_slots = _functools_slots, +- .m_traverse = _functools_traverse, +- .m_clear = _functools_clear, +- .m_free = _functools_free, ++ "_functools", ++ _functools_doc, ++ sizeof(_functools_state), ++ _functools_methods, ++ _functools_slots, ++ _functools_traverse, ++ _functools_clear, ++ _functools_free + }; + + PyMODINIT_FUNC +diff --git a/Modules/_heapqmodule.c b/Modules/_heapqmodule.c +index 3dbaaa0..5b17473 100644 +--- a/Modules/_heapqmodule.c ++++ b/Modules/_heapqmodule.c +@@ -250,6 +250,7 @@ _heapq_heappushpop_impl(PyObject *module, PyObject *heap, PyObject *item) + /*[clinic end generated code: output=67231dc98ed5774f input=5dc701f1eb4a4aa7]*/ + { + PyObject *returnitem; ++ PyObject *top; + int cmp; + + if (PyList_GET_SIZE(heap) == 0) { +@@ -257,7 +258,7 @@ _heapq_heappushpop_impl(PyObject *module, PyObject *heap, PyObject *item) + return item; + } + +- PyObject* top = PyList_GET_ITEM(heap, 0); ++ top = PyList_GET_ITEM(heap, 0); + Py_INCREF(top); + cmp = PyObject_RichCompareBool(top, item, Py_LT); + Py_DECREF(top); +diff --git a/Modules/_json.c b/Modules/_json.c +index 9464b9f..eada42f 100644 +--- a/Modules/_json.c ++++ b/Modules/_json.c +@@ -317,21 +317,24 @@ escape_unicode(PyObject *pystr) + static void + raise_errmsg(const char *msg, PyObject *s, Py_ssize_t end) + { ++ PyObject *decoder; ++ PyObject *JSONDecodeError; ++ PyObject *exc; ++ _Py_IDENTIFIER(JSONDecodeError); ++ + /* Use JSONDecodeError exception to raise a nice looking ValueError subclass */ + _Py_static_string(PyId_decoder, "json.decoder"); +- PyObject *decoder = _PyImport_GetModuleId(&PyId_decoder); ++ decoder = _PyImport_GetModuleId(&PyId_decoder); + if (decoder == NULL) { + return; + } + +- _Py_IDENTIFIER(JSONDecodeError); +- PyObject *JSONDecodeError = _PyObject_GetAttrId(decoder, &PyId_JSONDecodeError); ++ JSONDecodeError = _PyObject_GetAttrId(decoder, &PyId_JSONDecodeError); + Py_DECREF(decoder); + if (JSONDecodeError == NULL) { + return; + } + +- PyObject *exc; + exc = PyObject_CallFunction(JSONDecodeError, "zOn", msg, s, end); + Py_DECREF(JSONDecodeError); + if (exc) { +@@ -394,11 +397,11 @@ scanstring_unicode(PyObject *pystr, Py_ssize_t end, int strict, Py_ssize_t *next + Py_ssize_t next /* = begin */; + const void *buf; + int kind; ++ _PyUnicodeWriter writer; + + if (PyUnicode_READY(pystr) == -1) + return 0; + +- _PyUnicodeWriter writer; + _PyUnicodeWriter_Init(&writer); + writer.overallocate = 1; + +@@ -1227,11 +1230,11 @@ static PyType_Slot PyScannerType_slots[] = { + }; + + static PyType_Spec PyScannerType_spec = { +- .name = "_json.Scanner", +- .basicsize = sizeof(PyScannerObject), +- .itemsize = 0, +- .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, +- .slots = PyScannerType_slots, ++ "_json.Scanner", ++ sizeof(PyScannerObject), ++ 0, ++ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, ++ PyScannerType_slots + }; + + static PyObject * +@@ -1786,11 +1789,11 @@ static PyType_Slot PyEncoderType_slots[] = { + }; + + static PyType_Spec PyEncoderType_spec = { +- .name = "_json.Encoder", +- .basicsize = sizeof(PyEncoderObject), +- .itemsize = 0, +- .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, +- .slots = PyEncoderType_slots ++ "_json.Encoder", ++ sizeof(PyEncoderObject), ++ 0, ++ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, ++ PyEncoderType_slots + }; + + static PyMethodDef speedups_methods[] = { +diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c +index ac9709c..edbd0a9 100644 +--- a/Modules/_localemodule.c ++++ b/Modules/_localemodule.c +@@ -191,10 +191,13 @@ locale_decode_monetary(PyObject *dict, struct lconv *lc) + } + } + +-#define GET_LOCALE_STRING(ATTR) PyUnicode_DecodeLocale(lc->ATTR, NULL) + #else /* MS_WINDOWS */ ++#if defined(_MSC_VER) && _MSC_VER < 1300 ++#define GET_LOCALE_STRING(ATTR) PyUnicode_DecodeLocale(lc->ATTR, NULL) ++#else + /* Use _W_* fields of Windows struct lconv */ + #define GET_LOCALE_STRING(ATTR) PyUnicode_FromWideChar(lc->_W_ ## ATTR, -1) ++#endif + #endif /* MS_WINDOWS */ + + int res = -1; +@@ -245,6 +248,7 @@ _locale_localeconv_impl(PyObject *module) + PyObject* result; + struct lconv *lc; + PyObject *x; ++ PyObject *decimal_point = NULL, *thousands_sep = NULL; + + result = PyDict_New(); + if (!result) { +@@ -268,7 +272,9 @@ _locale_localeconv_impl(PyObject *module) + Py_DECREF(obj); \ + } while (0) + +-#ifdef MS_WINDOWS ++#if defined(MS_WINDOWS) && defined(_MSC_VER) && _MSC_VER < 1300 ++#define GET_LOCALE_STRING(ATTR) PyUnicode_DecodeLocale(lc->ATTR, NULL) ++#elif defined(MS_WINDOWS) + /* Use _W_* fields of Windows struct lconv */ + #define GET_LOCALE_STRING(ATTR) PyUnicode_FromWideChar(lc->_W_ ## ATTR, -1) + #else +@@ -305,7 +311,6 @@ _locale_localeconv_impl(PyObject *module) + RESULT_INT(n_sign_posn); + + /* Numeric information: LC_NUMERIC encoding */ +- PyObject *decimal_point = NULL, *thousands_sep = NULL; + if (_Py_GetLocaleconvNumeric(lc, &decimal_point, &thousands_sep) < 0) { + Py_XDECREF(decimal_point); + Py_XDECREF(thousands_sep); +@@ -828,6 +833,7 @@ _locale_exec(PyObject *module) + } \ + } while (0) + ++ _locale_state *state; + ADD_INT(module, LC_CTYPE); + ADD_INT(module, LC_TIME); + ADD_INT(module, LC_COLLATE); +@@ -841,7 +847,7 @@ _locale_exec(PyObject *module) + ADD_INT(module, LC_ALL); + ADD_INT(module, CHAR_MAX); + +- _locale_state *state = get_locale_state(module); ++ state = get_locale_state(module); + state->Error = PyErr_NewException("locale.Error", NULL, NULL); + if (state->Error == NULL) { + return -1; +diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c +index a0e262b..f785e94 100644 +--- a/Modules/_lsprof.c ++++ b/Modules/_lsprof.c +@@ -82,14 +82,16 @@ _lsprof_get_state(PyObject *module) + + static _PyTime_t CallExternalTimer(ProfilerObject *pObj) + { +- PyObject *o = _PyObject_CallNoArgs(pObj->externalTimer); ++ PyObject *o; ++ _PyTime_t result; ++ int err; ++ ++ o = _PyObject_CallNoArgs(pObj->externalTimer); + if (o == NULL) { + PyErr_WriteUnraisable(pObj->externalTimer); + return 0; + } + +- _PyTime_t result; +- int err; + if (pObj->externalTimerUnit > 0.0) { + /* interpret the result as an integer that will be scaled + in profiler_getstats() */ +@@ -494,17 +496,17 @@ static PyStructSequence_Field profiler_subentry_fields[] = { + }; + + static PyStructSequence_Desc profiler_entry_desc = { +- .name = "_lsprof.profiler_entry", +- .fields = profiler_entry_fields, +- .doc = NULL, +- .n_in_sequence = 6 ++ "_lsprof.profiler_entry", ++ NULL, ++ profiler_entry_fields, ++ 6 + }; + + static PyStructSequence_Desc profiler_subentry_desc = { +- .name = "_lsprof.profiler_subentry", +- .fields = profiler_subentry_fields, +- .doc = NULL, +- .n_in_sequence = 5 ++ "_lsprof.profiler_subentry", ++ NULL, ++ profiler_subentry_fields, ++ 5 + }; + + typedef struct { +@@ -670,6 +672,7 @@ profiler_enable(ProfilerObject *self, PyObject *args, PyObject *kwds) + int subcalls = -1; + int builtins = -1; + static char *kwlist[] = {"subcalls", "builtins", 0}; ++ PyThreadState *tstate; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:enable", + kwlist, &subcalls, &builtins)) + return NULL; +@@ -677,7 +680,7 @@ profiler_enable(ProfilerObject *self, PyObject *args, PyObject *kwds) + return NULL; + } + +- PyThreadState *tstate = _PyThreadState_GET(); ++ tstate = _PyThreadState_GET(); + if (_PyEval_SetProfile(tstate, profiler_callback, (PyObject*)self) < 0) { + return NULL; + } +@@ -747,9 +750,11 @@ profiler_traverse(ProfilerObject *op, visitproc visit, void *arg) + static void + profiler_dealloc(ProfilerObject *op) + { ++ PyTypeObject *tp; ++ PyThreadState *tstate; + PyObject_GC_UnTrack(op); + if (op->flags & POF_ENABLED) { +- PyThreadState *tstate = _PyThreadState_GET(); ++ tstate = _PyThreadState_GET(); + if (_PyEval_SetProfile(tstate, NULL, NULL) < 0) { + _PyErr_WriteUnraisableMsg("When destroying _lsprof profiler", NULL); + } +@@ -758,7 +763,7 @@ profiler_dealloc(ProfilerObject *op) + flush_unmatched(op); + clearEntries(op); + Py_XDECREF(op->externalTimer); +- PyTypeObject *tp = Py_TYPE(op); ++ tp = Py_TYPE(op); + tp->tp_free(op); + Py_DECREF(tp); + } +@@ -817,11 +822,12 @@ static PyType_Slot _lsprof_profiler_type_spec_slots[] = { + }; + + static PyType_Spec _lsprof_profiler_type_spec = { +- .name = "_lsprof.Profiler", +- .basicsize = sizeof(ProfilerObject), +- .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | +- Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE), +- .slots = _lsprof_profiler_type_spec_slots, ++ "_lsprof.Profiler", ++ sizeof(ProfilerObject), ++ 0, ++ (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | ++ Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE), ++ _lsprof_profiler_type_spec_slots + }; + + static PyMethodDef moduleMethods[] = { +@@ -895,14 +901,14 @@ static PyModuleDef_Slot _lsprofslots[] = { + + static struct PyModuleDef _lsprofmodule = { + PyModuleDef_HEAD_INIT, +- .m_name = "_lsprof", +- .m_doc = "Fast profiler", +- .m_size = sizeof(_lsprof_state), +- .m_methods = moduleMethods, +- .m_slots = _lsprofslots, +- .m_traverse = _lsprof_traverse, +- .m_clear = _lsprof_clear, +- .m_free = _lsprof_free ++ "_lsprof", ++ "Fast profiler", ++ sizeof(_lsprof_state), ++ moduleMethods, ++ _lsprofslots, ++ _lsprof_traverse, ++ _lsprof_clear, ++ _lsprof_free + }; + + PyMODINIT_FUNC +diff --git a/Modules/_pickle.c b/Modules/_pickle.c +index f0cb302..47ba9e5 100644 +--- a/Modules/_pickle.c ++++ b/Modules/_pickle.c +@@ -761,7 +761,10 @@ PyMemoTable_New(void) + static PyMemoTable * + PyMemoTable_Copy(PyMemoTable *self) + { +- PyMemoTable *new = PyMemoTable_New(); ++ PyMemoTable *new; ++ size_t i; ++ ++ new = PyMemoTable_New(); + if (new == NULL) + return NULL; + +@@ -777,7 +780,7 @@ PyMemoTable_Copy(PyMemoTable *self) + PyErr_NoMemory(); + return NULL; + } +- for (size_t i = 0; i < self->mt_allocated; i++) { ++ for (i = 0; i < self->mt_allocated; i++) { + Py_XINCREF(self->mt_table[i].me_key); + } + memcpy(new->mt_table, self->mt_table, +@@ -911,6 +914,7 @@ static int + PyMemoTable_Set(PyMemoTable *self, PyObject *key, Py_ssize_t value) + { + PyMemoEntry *entry; ++ size_t desired_size; + + assert(key != NULL); + +@@ -934,11 +938,11 @@ PyMemoTable_Set(PyMemoTable *self, PyObject *key, Py_ssize_t value) + * Very large memo tables (over 50K items) use doubling instead. + * This may help applications with severe memory constraints. + */ +- if (SIZE_MAX / 3 >= self->mt_used && self->mt_used * 3 < self->mt_allocated * 2) { ++ if (((size_t)-1) / 3 >= self->mt_used && self->mt_used * 3 < self->mt_allocated * 2) { + return 0; + } + // self->mt_used is always < PY_SSIZE_T_MAX, so this can't overflow. +- size_t desired_size = (self->mt_used > 50000 ? 2 : 4) * self->mt_used; ++ desired_size = (self->mt_used > 50000 ? 2 : 4) * self->mt_used; + return _PyMemoTable_ResizeTable(self, desired_size); + } + +@@ -1116,18 +1120,22 @@ _Pickler_Write(PicklerObject *self, const char *s, Py_ssize_t data_len) + static PicklerObject * + _Pickler_New(void) + { +- PyMemoTable *memo = PyMemoTable_New(); ++ PyMemoTable *memo; ++ const Py_ssize_t max_output_len = WRITE_BUF_SIZE; ++ PyObject *output_buffer; ++ PicklerObject *self; ++ ++ memo = PyMemoTable_New(); + if (memo == NULL) { + return NULL; + } + +- const Py_ssize_t max_output_len = WRITE_BUF_SIZE; +- PyObject *output_buffer = PyBytes_FromStringAndSize(NULL, max_output_len); ++ output_buffer = PyBytes_FromStringAndSize(NULL, max_output_len); + if (output_buffer == NULL) { + goto error; + } + +- PicklerObject *self = PyObject_GC_New(PicklerObject, &Pickler_Type); ++ self = PyObject_GC_New(PicklerObject, &Pickler_Type); + if (self == NULL) { + goto error; + } +@@ -1377,12 +1385,20 @@ _Unpickler_ReadImpl(UnpicklerObject *self, char **s, Py_ssize_t n) + static Py_ssize_t + _Unpickler_ReadInto(UnpicklerObject *self, char *buf, Py_ssize_t n) + { ++ Py_ssize_t in_buffer; ++ Py_ssize_t to_read; ++ PyObject *len; ++ PyObject *data; ++ PyObject *buf_obj; ++ PyObject *read_size_obj; ++ Py_ssize_t read_size; ++ + assert(n != READ_WHOLE_LINE); + + /* Read from available buffer data, if any */ +- Py_ssize_t in_buffer = self->input_len - self->next_read_idx; ++ in_buffer = self->input_len - self->next_read_idx; + if (in_buffer > 0) { +- Py_ssize_t to_read = Py_MIN(in_buffer, n); ++ to_read = Py_MIN(in_buffer, n); + memcpy(buf, self->input_buffer + self->next_read_idx, to_read); + self->next_read_idx += to_read; + buf += to_read; +@@ -1405,11 +1421,11 @@ _Unpickler_ReadInto(UnpicklerObject *self, char *buf, Py_ssize_t n) + if (!self->readinto) { + /* readinto() not supported on file-like object, fall back to read() + * and copy into destination buffer (bpo-39681) */ +- PyObject* len = PyLong_FromSsize_t(n); ++ len = PyLong_FromSsize_t(n); + if (len == NULL) { + return -1; + } +- PyObject* data = _Pickle_FastCall(self->read, len); ++ data = _Pickle_FastCall(self->read, len); + if (data == NULL) { + return -1; + } +@@ -1420,7 +1436,7 @@ _Unpickler_ReadInto(UnpicklerObject *self, char *buf, Py_ssize_t n) + Py_DECREF(data); + return -1; + } +- Py_ssize_t read_size = PyBytes_GET_SIZE(data); ++ read_size = PyBytes_GET_SIZE(data); + if (read_size < n) { + Py_DECREF(data); + return bad_readline(); +@@ -1431,15 +1447,15 @@ _Unpickler_ReadInto(UnpicklerObject *self, char *buf, Py_ssize_t n) + } + + /* Call readinto() into user buffer */ +- PyObject *buf_obj = PyMemoryView_FromMemory(buf, n, PyBUF_WRITE); ++ buf_obj = PyMemoryView_FromMemory(buf, n, PyBUF_WRITE); + if (buf_obj == NULL) { + return -1; + } +- PyObject *read_size_obj = _Pickle_FastCall(self->readinto, buf_obj); ++ read_size_obj = _Pickle_FastCall(self->readinto, buf_obj); + if (read_size_obj == NULL) { + return -1; + } +- Py_ssize_t read_size = PyLong_AsSsize_t(read_size_obj); ++ read_size = PyLong_AsSsize_t(read_size_obj); + Py_DECREF(read_size_obj); + + if (read_size < 0) { +@@ -1527,10 +1543,11 @@ static int + _Unpickler_ResizeMemoList(UnpicklerObject *self, size_t new_size) + { + size_t i; ++ PyObject **memo_new; + + assert(new_size > self->memo_size); + +- PyObject **memo_new = self->memo; ++ memo_new = self->memo; + PyMem_RESIZE(memo_new, PyObject *, new_size); + if (memo_new == NULL) { + PyErr_NoMemory(); +@@ -1610,17 +1627,21 @@ static UnpicklerObject * + _Unpickler_New(void) + { + const int MEMO_SIZE = 32; +- PyObject **memo = _Unpickler_NewMemo(MEMO_SIZE); ++ PyObject **memo; ++ PyObject *stack; ++ UnpicklerObject *self; ++ ++ memo = _Unpickler_NewMemo(MEMO_SIZE); + if (memo == NULL) { + return NULL; + } + +- PyObject *stack = Pdata_New(); ++ stack = Pdata_New(); + if (stack == NULL) { + goto error; + } + +- UnpicklerObject *self = PyObject_GC_New(UnpicklerObject, &Unpickler_Type); ++ self = PyObject_GC_New(UnpicklerObject, &Unpickler_Type); + if (self == NULL) { + goto error; + } +@@ -1914,6 +1935,8 @@ static int + _checkmodule(PyObject *module_name, PyObject *module, + PyObject *global, PyObject *dotted_path) + { ++ PyObject *candidate; ++ + if (module == Py_None) { + return -1; + } +@@ -1922,7 +1945,7 @@ _checkmodule(PyObject *module_name, PyObject *module, + return -1; + } + +- PyObject *candidate = get_deep_attribute(module, dotted_path, NULL); ++ candidate = get_deep_attribute(module, dotted_path, NULL); + if (candidate == NULL) { + return -1; + } +@@ -1940,6 +1963,7 @@ whichmodule(PyObject *global, PyObject *dotted_path) + PyObject *module_name; + PyObject *module = NULL; + Py_ssize_t i; ++ PyThreadState *tstate; + PyObject *modules; + + if (_PyObject_LookupAttr(global, &_Py_ID(__module__), &module_name) < 0) { +@@ -1956,7 +1980,7 @@ whichmodule(PyObject *global, PyObject *dotted_path) + assert(module_name == NULL); + + /* Fallback on walking sys.modules */ +- PyThreadState *tstate = _PyThreadState_GET(); ++ tstate = _PyThreadState_GET(); + modules = _PySys_GetAttr(tstate, &_Py_ID(modules)); + if (modules == NULL) { + PyErr_SetString(PyExc_RuntimeError, "unable to get sys.modules"); +@@ -2018,6 +2042,8 @@ whichmodule(PyObject *global, PyObject *dotted_path) + static int + fast_save_enter(PicklerObject *self, PyObject *obj) + { ++ int r; ++ + /* if fast_nesting < 0, we're doing an error exit. */ + if (++self->fast_nesting >= FAST_NESTING_LIMIT) { + PyObject *key = NULL; +@@ -2033,7 +2059,7 @@ fast_save_enter(PicklerObject *self, PyObject *obj) + self->fast_nesting = -1; + return 0; + } +- int r = PyDict_Contains(self->fast_memo, key); ++ r = PyDict_Contains(self->fast_memo, key); + if (r > 0) { + PyErr_Format(PyExc_ValueError, + "fast mode: can't pickle cyclic objects " +@@ -2381,11 +2407,11 @@ static int + _save_bytes_data(PicklerObject *self, PyObject *obj, const char *data, + Py_ssize_t size) + { +- assert(self->proto >= 3); +- + char header[9]; + Py_ssize_t len; + ++ assert(self->proto >= 3); ++ + if (size < 0) + return -1; + +@@ -2479,11 +2505,11 @@ static int + _save_bytearray_data(PicklerObject *self, PyObject *obj, const char *data, + Py_ssize_t size) + { +- assert(self->proto >= 5); +- + char header[9]; + Py_ssize_t len; + ++ assert(self->proto >= 5); ++ + if (size < 0) + return -1; + +@@ -2541,13 +2567,16 @@ save_bytearray(PicklerObject *self, PyObject *obj) + static int + save_picklebuffer(PicklerObject *self, PyObject *obj) + { ++ const Py_buffer *view; ++ int in_band; ++ + if (self->proto < 5) { + PickleState *st = _Pickle_GetGlobalState(); + PyErr_SetString(st->PicklingError, + "PickleBuffer can only pickled with protocol >= 5"); + return -1; + } +- const Py_buffer* view = PyPickleBuffer_GetBuffer(obj); ++ view = PyPickleBuffer_GetBuffer(obj); + if (view == NULL) { + return -1; + } +@@ -2558,7 +2587,7 @@ save_picklebuffer(PicklerObject *self, PyObject *obj) + "pointing to a non-contiguous buffer"); + return -1; + } +- int in_band = 1; ++ in_band = 1; + if (self->buffer_callback != NULL) { + PyObject *ret = PyObject_CallOneArg(self->buffer_callback, obj); + if (ret == NULL) { +@@ -3021,6 +3050,7 @@ batch_list_exact(PicklerObject *self, PyObject *obj) + { + PyObject *item = NULL; + Py_ssize_t this_batch, total; ++ int err; + + const char append_op = APPEND; + const char appends_op = APPENDS; +@@ -3033,7 +3063,7 @@ batch_list_exact(PicklerObject *self, PyObject *obj) + if (PyList_GET_SIZE(obj) == 1) { + item = PyList_GET_ITEM(obj, 0); + Py_INCREF(item); +- int err = save(self, item, 0); ++ err = save(self, item, 0); + Py_DECREF(item); + if (err < 0) + return -1; +@@ -3051,7 +3081,7 @@ batch_list_exact(PicklerObject *self, PyObject *obj) + while (total < PyList_GET_SIZE(obj)) { + item = PyList_GET_ITEM(obj, total); + Py_INCREF(item); +- int err = save(self, item, 0); ++ err = save(self, item, 0); + Py_DECREF(item); + if (err < 0) + return -1; +@@ -3414,6 +3444,7 @@ save_set(PicklerObject *self, PyObject *obj) + { + PyObject *item; + int i; ++ int err; + Py_ssize_t set_size, ppos = 0; + Py_hash_t hash; + +@@ -3458,7 +3489,7 @@ save_set(PicklerObject *self, PyObject *obj) + return -1; + while (_PySet_NextEntry(obj, &ppos, &item, &hash)) { + Py_INCREF(item); +- int err = save(self, item, 0); ++ err = save(self, item, 0); + Py_CLEAR(item); + if (err < 0) + return -1; +@@ -4685,13 +4716,15 @@ Pickler_dealloc(PicklerObject *self) + static int + Pickler_traverse(PicklerObject *self, visitproc visit, void *arg) + { ++ PyMemoTable *memo; ++ + Py_VISIT(self->write); + Py_VISIT(self->pers_func); + Py_VISIT(self->dispatch_table); + Py_VISIT(self->fast_memo); + Py_VISIT(self->reducer_override); + Py_VISIT(self->buffer_callback); +- PyMemoTable *memo = self->memo; ++ memo = self->memo; + if (memo && memo->mt_table) { + Py_ssize_t i = memo->mt_allocated; + while (--i >= 0) { +@@ -4855,11 +4888,12 @@ _pickle_PicklerMemoProxy_copy_impl(PicklerMemoProxyObject *self) + { + PyMemoTable *memo; + PyObject *new_memo = PyDict_New(); ++ size_t i; + if (new_memo == NULL) + return NULL; + + memo = self->pickler->memo; +- for (size_t i = 0; i < memo->mt_allocated; ++i) { ++ for (i = 0; i < memo->mt_allocated; ++i) { + PyMemoEntry entry = memo->mt_table[i]; + if (entry.me_key != NULL) { + int status; +@@ -5618,17 +5652,20 @@ load_counted_bytearray(UnpicklerObject *self) + static int + load_next_buffer(UnpicklerObject *self) + { ++ PickleState *st; ++ PyObject *buf; ++ + if (self->buffers == NULL) { +- PickleState *st = _Pickle_GetGlobalState(); ++ st = _Pickle_GetGlobalState(); + PyErr_SetString(st->UnpicklingError, + "pickle stream refers to out-of-band data " + "but no *buffers* argument was given"); + return -1; + } +- PyObject *buf = PyIter_Next(self->buffers); ++ buf = PyIter_Next(self->buffers); + if (buf == NULL) { + if (!PyErr_Occurred()) { +- PickleState *st = _Pickle_GetGlobalState(); ++ st = _Pickle_GetGlobalState(); + PyErr_SetString(st->UnpicklingError, + "not enough out-of-band buffers"); + } +@@ -5642,13 +5679,17 @@ load_next_buffer(UnpicklerObject *self) + static int + load_readonly_buffer(UnpicklerObject *self) + { +- Py_ssize_t len = Py_SIZE(self->stack); ++ Py_ssize_t len; ++ PyObject *obj; ++ PyObject *view; ++ ++ len = Py_SIZE(self->stack); + if (len <= self->stack->fence) { + return Pdata_stack_underflow(self->stack); + } + +- PyObject *obj = self->stack->data[len - 1]; +- PyObject *view = PyMemoryView_FromObject(obj); ++ obj = self->stack->data[len - 1]; ++ view = PyMemoryView_FromObject(obj); + if (view == NULL) { + return -1; + } +@@ -7215,6 +7256,8 @@ Unpickler_dealloc(UnpicklerObject *self) + static int + Unpickler_traverse(UnpicklerObject *self, visitproc visit, void *arg) + { ++ PyObject **memo; ++ + Py_VISIT(self->readline); + Py_VISIT(self->readinto); + Py_VISIT(self->read); +@@ -7222,7 +7265,7 @@ Unpickler_traverse(UnpicklerObject *self, visitproc visit, void *arg) + Py_VISIT(self->stack); + Py_VISIT(self->pers_func); + Py_VISIT(self->buffers); +- PyObject **memo = self->memo; ++ memo = self->memo; + if (memo) { + Py_ssize_t i = self->memo_size; + while (--i >= 0) { +@@ -7527,6 +7570,7 @@ Unpickler_set_memo(UnpicklerObject *self, PyObject *obj, void *Py_UNUSED(ignored + { + PyObject **new_memo; + size_t new_memo_size = 0; ++ size_t i; + + if (obj == NULL) { + PyErr_SetString(PyExc_TypeError, +@@ -7543,7 +7587,7 @@ Unpickler_set_memo(UnpicklerObject *self, PyObject *obj, void *Py_UNUSED(ignored + if (new_memo == NULL) + return -1; + +- for (size_t i = 0; i < new_memo_size; i++) { ++ for (i = 0; i < new_memo_size; i++) { + Py_XINCREF(unpickler->memo[i]); + new_memo[i] = unpickler->memo[i]; + } +@@ -7591,7 +7635,7 @@ Unpickler_set_memo(UnpicklerObject *self, PyObject *obj, void *Py_UNUSED(ignored + + error: + if (new_memo_size) { +- for (size_t i = new_memo_size - 1; i != SIZE_MAX; i--) { ++ for (i = new_memo_size; i-- > 0;) { + Py_XDECREF(new_memo[i]); + } + PyMem_Free(new_memo); +diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c +index d96c037..26bbb56 100644 +--- a/Modules/_randommodule.c ++++ b/Modules/_randommodule.c +@@ -585,6 +585,8 @@ static int + _random_exec(PyObject *module) + { + _randomstate *state = get_random_state(module); ++ PyObject *longval; ++ PyObject *longtype; + + state->Random_Type = PyType_FromModuleAndSpec( + module, &Random_Type_spec, NULL); +@@ -596,12 +598,12 @@ _random_exec(PyObject *module) + } + + /* Look up and save int.__abs__, which is needed in random_seed(). */ +- PyObject *longval = PyLong_FromLong(0); ++ longval = PyLong_FromLong(0); + if (longval == NULL) { + return -1; + } + +- PyObject *longtype = PyObject_Type(longval); ++ longtype = PyObject_Type(longval); + Py_DECREF(longval); + if (longtype == NULL) { + return -1; +diff --git a/Modules/_sha3/sha3module.c b/Modules/_sha3/sha3module.c +index bd1dd59..7abc300 100644 +--- a/Modules/_sha3/sha3module.c ++++ b/Modules/_sha3/sha3module.c +@@ -176,11 +176,13 @@ py_sha3_new_impl(PyTypeObject *type, PyObject *data, int usedforsecurity) + static void + SHA3_dealloc(SHA3object *self) + { ++ PyTypeObject *tp; ++ + if (self->lock) { + PyThread_free_lock(self->lock); + } + +- PyTypeObject *tp = Py_TYPE(self); ++ tp = Py_TYPE(self); + PyObject_Free(self); + Py_DECREF(tp); + } +@@ -412,10 +414,11 @@ static PyGetSetDef SHA3_getseters[] = { + // cannot be subclassed: it does not have the Py_TPFLAGS_BASETYPE flag. + #define SHA3_TYPE_SPEC(type_spec_obj, type_name, type_slots) \ + static PyType_Spec type_spec_obj = { \ +- .name = "_sha3." type_name, \ +- .basicsize = sizeof(SHA3object), \ +- .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE, \ +- .slots = type_slots \ ++ "_sha3." type_name, \ ++ sizeof(SHA3object), \ ++ 0, \ ++ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE, \ ++ type_slots \ + } + + PyDoc_STRVAR(sha3_224__doc__, +@@ -646,12 +649,14 @@ static PyModuleDef_Slot _sha3_slots[] = { + /* Initialize this module. */ + static struct PyModuleDef _sha3module = { + PyModuleDef_HEAD_INIT, +- .m_name = "_sha3", +- .m_size = sizeof(SHA3State), +- .m_slots = _sha3_slots, +- .m_traverse = _sha3_traverse, +- .m_clear = _sha3_clear, +- .m_free = _sha3_free, ++ "_sha3", ++ NULL, ++ sizeof(SHA3State), ++ NULL, ++ _sha3_slots, ++ _sha3_traverse, ++ _sha3_clear, ++ _sha3_free, + }; + + +diff --git a/Modules/_sre/sre.c b/Modules/_sre/sre.c +index 3bad9d8..53c8ce0 100644 +--- a/Modules/_sre/sre.c ++++ b/Modules/_sre/sre.c +@@ -1655,6 +1655,7 @@ _validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) + SRE_CODE op; + SRE_CODE arg; + SRE_CODE skip; ++ int rc; + + VTRACE(("code=%p, end=%p\n", code, end)); + +@@ -1922,7 +1923,7 @@ _validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) + for a JUMP opcode preceding our skip target. + */ + VTRACE(("then part:\n")); +- int rc = _validate_inner(code+1, code+skip-1, groups); ++ rc = _validate_inner(code+1, code+skip-1, groups); + if (rc == 1) { + VTRACE(("else part:\n")); + code += skip-2; /* Position after JUMP, at */ +@@ -2822,12 +2823,12 @@ static PyType_Slot pattern_slots[] = { + }; + + static PyType_Spec pattern_spec = { +- .name = "re.Pattern", +- .basicsize = sizeof(PatternObject), +- .itemsize = sizeof(SRE_CODE), +- .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | +- Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_HAVE_GC), +- .slots = pattern_slots, ++ "re.Pattern", ++ sizeof(PatternObject), ++ sizeof(SRE_CODE), ++ (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | ++ Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_HAVE_GC), ++ pattern_slots, + }; + + static PyMethodDef match_methods[] = { +@@ -2890,12 +2891,12 @@ static PyType_Slot match_slots[] = { + }; + + static PyType_Spec match_spec = { +- .name = "re.Match", +- .basicsize = sizeof(MatchObject), +- .itemsize = sizeof(Py_ssize_t), +- .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | +- Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_HAVE_GC), +- .slots = match_slots, ++ "re.Match", ++ sizeof(MatchObject), ++ sizeof(Py_ssize_t), ++ (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | ++ Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_HAVE_GC), ++ match_slots, + }; + + static PyMethodDef scanner_methods[] = { +@@ -2920,11 +2921,12 @@ static PyType_Slot scanner_slots[] = { + }; + + static PyType_Spec scanner_spec = { +- .name = "_" SRE_MODULE ".SRE_Scanner", +- .basicsize = sizeof(ScannerObject), +- .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | +- Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_HAVE_GC), +- .slots = scanner_slots, ++ "_" SRE_MODULE ".SRE_Scanner", ++ sizeof(ScannerObject), ++ 0, ++ (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | ++ Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_HAVE_GC), ++ scanner_slots, + }; + + static PyMethodDef _functions[] = { +@@ -2978,9 +2980,10 @@ do { \ + #define ADD_ULONG_CONSTANT(module, name, value) \ + do { \ + PyObject *o = PyLong_FromUnsignedLong(value); \ ++ int res; \ + if (!o) \ + goto error; \ +- int res = PyModule_AddObjectRef(module, name, o); \ ++ res = PyModule_AddObjectRef(module, name, o); \ + Py_DECREF(o); \ + if (res < 0) { \ + goto error; \ +@@ -3025,14 +3028,15 @@ static PyModuleDef_Slot sre_slots[] = { + }; + + static struct PyModuleDef sremodule = { +- .m_base = PyModuleDef_HEAD_INIT, +- .m_name = "_" SRE_MODULE, +- .m_size = sizeof(_sremodulestate), +- .m_methods = _functions, +- .m_slots = sre_slots, +- .m_traverse = sre_traverse, +- .m_free = sre_free, +- .m_clear = sre_clear, ++ PyModuleDef_HEAD_INIT, ++ "_" SRE_MODULE, ++ NULL, ++ sizeof(_sremodulestate), ++ _functions, ++ sre_slots, ++ sre_traverse, ++ sre_clear, ++ sre_free, + }; + + PyMODINIT_FUNC +diff --git a/Modules/_sre/sre_lib.h b/Modules/_sre/sre_lib.h +index 95c1ada..e73bccf 100644 +--- a/Modules/_sre/sre_lib.h ++++ b/Modules/_sre/sre_lib.h +@@ -560,6 +560,8 @@ LOCAL(Py_ssize_t) + SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel) + { + const SRE_CHAR* end = (const SRE_CHAR *)state->end; ++ const SRE_CHAR *ptr; ++ SRE_REPEAT *repeat_of_tail; + Py_ssize_t alloc_pos, ctx_pos = -1; + Py_ssize_t ret = 0; + int jump; +@@ -583,7 +585,7 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel) + entrance: + + ; // Fashion statement. +- const SRE_CHAR *ptr = (SRE_CHAR *)state->ptr; ++ ptr = (SRE_CHAR *)state->ptr; + + if (pattern[0] == SRE_OP_INFO) { + /* optimization info block */ +@@ -1211,7 +1213,7 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel) + MARK_PUSH(ctx->lastmark); + + DO_JUMP(JUMP_MIN_UNTIL_2, jump_min_until_2, pattern); +- SRE_REPEAT *repeat_of_tail = state->repeat; ++ repeat_of_tail = state->repeat; + state->repeat = ctx->u.rep; // restore repeat before return + + if (ret) { +diff --git a/Modules/_stat.c b/Modules/_stat.c +index 6e0d690..20f6e58 100644 +--- a/Modules/_stat.c ++++ b/Modules/_stat.c +@@ -30,6 +30,19 @@ extern "C" { + #include + typedef unsigned short mode_t; + ++/* These constants are not present in the VC6 Windows headers. */ ++#ifndef FILE_ATTRIBUTE_DEVICE ++# define FILE_ATTRIBUTE_DEVICE 0x0040 ++#endif ++ ++#ifndef FILE_ATTRIBUTE_VIRTUAL ++# define FILE_ATTRIBUTE_VIRTUAL 0x10000 ++#endif ++ ++#ifndef IO_REPARSE_TAG_SYMLINK ++# define IO_REPARSE_TAG_SYMLINK 0xA000000CL ++#endif ++ + /* FILE_ATTRIBUTE_INTEGRITY_STREAM and FILE_ATTRIBUTE_NO_SCRUB_DATA + are not present in VC2010, so define them manually */ + #ifndef FILE_ATTRIBUTE_INTEGRITY_STREAM +@@ -499,6 +512,20 @@ ST_CTIME\n\ + static int + stat_exec(PyObject *module) + { ++ const char* st_constants[] = { ++ "ST_MODE", ++ "ST_INO", ++ "ST_DEV", ++ "ST_NLINK", ++ "ST_UID", ++ "ST_GID", ++ "ST_SIZE", ++ "ST_ATIME", ++ "ST_MTIME", ++ "ST_CTIME" ++ }; ++ int i; ++ + #define ADD_INT_MACRO(module, macro) \ + do { \ + if (PyModule_AddIntConstant(module, #macro, macro) < 0) { \ +@@ -554,20 +581,7 @@ stat_exec(PyObject *module) + ADD_INT_MACRO(module, SF_NOUNLINK); + ADD_INT_MACRO(module, SF_SNAPSHOT); + +- const char* st_constants[] = { +- "ST_MODE", +- "ST_INO", +- "ST_DEV", +- "ST_NLINK", +- "ST_UID", +- "ST_GID", +- "ST_SIZE", +- "ST_ATIME", +- "ST_MTIME", +- "ST_CTIME" +- }; +- +- for (int i = 0; i < (int)Py_ARRAY_LENGTH(st_constants); i++) { ++ for (i = 0; i < (int)Py_ARRAY_LENGTH(st_constants); i++) { + if (PyModule_AddIntConstant(module, st_constants[i], i) < 0) { + return -1; + } +@@ -618,11 +632,14 @@ static PyModuleDef_Slot stat_slots[] = { + + static struct PyModuleDef statmodule = { + PyModuleDef_HEAD_INIT, +- .m_name = "_stat", +- .m_doc = module_doc, +- .m_size = 0, +- .m_methods = stat_methods, +- .m_slots = stat_slots, ++ "_stat", ++ module_doc, ++ 0, ++ stat_methods, ++ stat_slots, ++ NULL, ++ NULL, ++ NULL, + }; + + +diff --git a/Modules/_struct.c b/Modules/_struct.c +index 9d66568..97921b1 100644 +--- a/Modules/_struct.c ++++ b/Modules/_struct.c +@@ -14,6 +14,11 @@ + #include "structmember.h" // PyMemberDef + #include + ++#if defined(_MSC_VER) && _MSC_VER < 1300 ++/* MSVC6 has no C99 _Bool; preserve the one-byte layout used by struct. */ ++typedef unsigned char _Bool; ++#endif ++ + /*[clinic input] + class Struct "PyStructObject *" "&PyStructType" + [clinic start generated code]*/ +@@ -95,8 +100,8 @@ typedef struct { char c; _Bool x; } st_bool; + + /* We can't support q and Q in native mode unless the compiler does; + in std mode, they're 8 bytes on all platforms. */ +-typedef struct { char c; long long x; } s_long_long; +-#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(long long)) ++typedef struct { char c; PY_LONG_LONG x; } s_long_long; ++#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG)) + + #ifdef __powerc + #pragma options align=reset +@@ -203,9 +208,9 @@ get_ulong(_structmodulestate *state, PyObject *v, unsigned long *p) + /* Same, but handling native long long. */ + + static int +-get_longlong(_structmodulestate *state, PyObject *v, long long *p) ++get_longlong(_structmodulestate *state, PyObject *v, PY_LONG_LONG *p) + { +- long long x; ++ PY_LONG_LONG x; + + v = get_pylong(state, v); + if (v == NULL) +@@ -213,7 +218,7 @@ get_longlong(_structmodulestate *state, PyObject *v, long long *p) + assert(PyLong_Check(v)); + x = PyLong_AsLongLong(v); + Py_DECREF(v); +- if (x == (long long)-1 && PyErr_Occurred()) { ++ if (x == (PY_LONG_LONG)-1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) + PyErr_SetString(state->StructError, + "argument out of range"); +@@ -226,9 +231,9 @@ get_longlong(_structmodulestate *state, PyObject *v, long long *p) + /* Same, but handling native unsigned long long. */ + + static int +-get_ulonglong(_structmodulestate *state, PyObject *v, unsigned long long *p) ++get_ulonglong(_structmodulestate *state, PyObject *v, unsigned PY_LONG_LONG *p) + { +- unsigned long long x; ++ unsigned PY_LONG_LONG x; + + v = get_pylong(state, v); + if (v == NULL) +@@ -236,7 +241,7 @@ get_ulonglong(_structmodulestate *state, PyObject *v, unsigned long long *p) + assert(PyLong_Check(v)); + x = PyLong_AsUnsignedLongLong(v); + Py_DECREF(v); +- if (x == (unsigned long long)-1 && PyErr_Occurred()) { ++ if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) + PyErr_SetString(state->StructError, + "argument out of range"); +@@ -485,7 +490,7 @@ nu_size_t(_structmodulestate *state, const char *p, const formatdef *f) + static PyObject * + nu_longlong(_structmodulestate *state, const char *p, const formatdef *f) + { +- long long x; ++ PY_LONG_LONG x; + memcpy((char *)&x, p, sizeof x); + return PyLong_FromLongLong(x); + } +@@ -493,7 +498,7 @@ nu_longlong(_structmodulestate *state, const char *p, const formatdef *f) + static PyObject * + nu_ulonglong(_structmodulestate *state, const char *p, const formatdef *f) + { +- unsigned long long x; ++ unsigned PY_LONG_LONG x; + memcpy((char *)&x, p, sizeof x); + return PyLong_FromUnsignedLongLong(x); + } +@@ -694,7 +699,7 @@ np_size_t(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) + static int + np_longlong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) + { +- long long x; ++ PY_LONG_LONG x; + if (get_longlong(state, v, &x) < 0) + return -1; + memcpy(p, (char *)&x, sizeof x); +@@ -704,7 +709,7 @@ np_longlong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) + static int + np_ulonglong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) + { +- unsigned long long x; ++ unsigned PY_LONG_LONG x; + if (get_ulonglong(state, v, &x) < 0) + return -1; + memcpy(p, (char *)&x, sizeof x); +@@ -793,8 +798,8 @@ static const formatdef native_table[] = { + {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong}, + {'n', sizeof(size_t), SIZE_T_ALIGN, nu_ssize_t, np_ssize_t}, + {'N', sizeof(size_t), SIZE_T_ALIGN, nu_size_t, np_size_t}, +- {'q', sizeof(long long), LONG_LONG_ALIGN, nu_longlong, np_longlong}, +- {'Q', sizeof(long long), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong}, ++ {'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong}, ++ {'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong}, + {'?', sizeof(_Bool), BOOL_ALIGN, nu_bool, np_bool}, + {'e', sizeof(short), SHORT_ALIGN, nu_halffloat, np_halffloat}, + {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float}, +@@ -835,7 +840,7 @@ bu_uint(_structmodulestate *state, const char *p, const formatdef *f) + static PyObject * + bu_longlong(_structmodulestate *state, const char *p, const formatdef *f) + { +- long long x = 0; ++ PY_LONG_LONG x = 0; + Py_ssize_t i = f->size; + const unsigned char *bytes = (const unsigned char *)p; + do { +@@ -843,14 +848,14 @@ bu_longlong(_structmodulestate *state, const char *p, const formatdef *f) + } while (--i > 0); + /* Extend the sign bit. */ + if (SIZEOF_LONG_LONG > f->size) +- x |= -(x & ((long long)1 << ((8 * f->size) - 1))); ++ x |= -(x & ((PY_LONG_LONG)1 << ((8 * f->size) - 1))); + return PyLong_FromLongLong(x); + } + + static PyObject * + bu_ulonglong(_structmodulestate *state, const char *p, const formatdef *f) + { +- unsigned long long x = 0; ++ unsigned PY_LONG_LONG x = 0; + Py_ssize_t i = f->size; + const unsigned char *bytes = (const unsigned char *)p; + do { +@@ -1056,7 +1061,7 @@ lu_uint(_structmodulestate *state, const char *p, const formatdef *f) + static PyObject * + lu_longlong(_structmodulestate *state, const char *p, const formatdef *f) + { +- long long x = 0; ++ PY_LONG_LONG x = 0; + Py_ssize_t i = f->size; + const unsigned char *bytes = (const unsigned char *)p; + do { +@@ -1064,14 +1069,14 @@ lu_longlong(_structmodulestate *state, const char *p, const formatdef *f) + } while (i > 0); + /* Extend the sign bit. */ + if (SIZEOF_LONG_LONG > f->size) +- x |= -(x & ((long long)1 << ((8 * f->size) - 1))); ++ x |= -(x & ((PY_LONG_LONG)1 << ((8 * f->size) - 1))); + return PyLong_FromLongLong(x); + } + + static PyObject * + lu_ulonglong(_structmodulestate *state, const char *p, const formatdef *f) + { +- unsigned long long x = 0; ++ unsigned PY_LONG_LONG x = 0; + Py_ssize_t i = f->size; + const unsigned char *bytes = (const unsigned char *)p; + do { +@@ -1437,9 +1442,10 @@ static PyObject * + s_new(PyTypeObject *type, PyObject *args, PyObject *kwds) + { + PyObject *self; ++ allocfunc alloc_func; + + assert(type != NULL); +- allocfunc alloc_func = PyType_GetSlot(type, Py_tp_alloc); ++ alloc_func = PyType_GetSlot(type, Py_tp_alloc); + assert(alloc_func != NULL); + + self = alloc_func(type, 0); +@@ -1514,7 +1520,10 @@ s_traverse(PyStructObject *s, visitproc visit, void *arg) + static void + s_dealloc(PyStructObject *s) + { +- PyTypeObject *tp = Py_TYPE(s); ++ PyTypeObject *tp; ++ freefunc free_func; ++ ++ tp = Py_TYPE(s); + PyObject_GC_UnTrack(s); + if (s->weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *)s); +@@ -1522,7 +1531,7 @@ s_dealloc(PyStructObject *s) + PyMem_Free(s->s_codes); + } + Py_XDECREF(s->s_format); +- freefunc free_func = PyType_GetSlot(Py_TYPE(s), Py_tp_free); ++ free_func = PyType_GetSlot(Py_TYPE(s), Py_tp_free); + free_func(s); + Py_DECREF(tp); + } +@@ -1902,6 +1911,7 @@ s_pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs) + char *buf; + PyStructObject *soself; + _structmodulestate *state = get_struct_state_structinst(self); ++ _PyBytesWriter writer; + + /* Validate arguments. */ + soself = (PyStructObject *)self; +@@ -1915,7 +1925,6 @@ s_pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs) + } + + /* Allocate a new string */ +- _PyBytesWriter writer; + _PyBytesWriter_Init(&writer); + buf = _PyBytesWriter_Alloc(&writer, soself->s_size); + if (buf == NULL) { +@@ -2472,14 +2481,14 @@ static PyModuleDef_Slot _structmodule_slots[] = { + + static struct PyModuleDef _structmodule = { + PyModuleDef_HEAD_INIT, +- .m_name = "_struct", +- .m_doc = module_doc, +- .m_size = sizeof(_structmodulestate), +- .m_methods = module_functions, +- .m_slots = _structmodule_slots, +- .m_traverse = _structmodule_traverse, +- .m_clear = _structmodule_clear, +- .m_free = _structmodule_free, ++ "_struct", ++ module_doc, ++ sizeof(_structmodulestate), ++ module_functions, ++ _structmodule_slots, ++ _structmodule_traverse, ++ _structmodule_clear, ++ _structmodule_free, + }; + + PyMODINIT_FUNC +diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c +index 7699b19..f05985a 100644 +--- a/Modules/arraymodule.c ++++ b/Modules/arraymodule.c +@@ -258,18 +258,19 @@ static int + u_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) + { + PyObject *u; ++ Py_ssize_t len; ++ wchar_t w; + if (!PyArg_Parse(v, "U;array item must be unicode character", &u)) { + return -1; + } + +- Py_ssize_t len = PyUnicode_AsWideChar(u, NULL, 0); ++ len = PyUnicode_AsWideChar(u, NULL, 0); + if (len != 2) { + PyErr_SetString(PyExc_TypeError, + "array item must be unicode character"); + return -1; + } + +- wchar_t w; + len = PyUnicode_AsWideChar(u, &w, 1); + assert(len == 1); + +@@ -445,17 +446,17 @@ LL_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) + static PyObject * + q_getitem(arrayobject *ap, Py_ssize_t i) + { +- return PyLong_FromLongLong(((long long *)ap->ob_item)[i]); ++ return PyLong_FromLongLong(((PY_LONG_LONG *)ap->ob_item)[i]); + } + + static int + q_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) + { +- long long x; ++ PY_LONG_LONG x; + if (!PyArg_Parse(v, "L;array item must be integer", &x)) + return -1; + if (i >= 0) +- ((long long *)ap->ob_item)[i] = x; ++ ((PY_LONG_LONG *)ap->ob_item)[i] = x; + return 0; + } + +@@ -463,13 +464,13 @@ static PyObject * + QQ_getitem(arrayobject *ap, Py_ssize_t i) + { + return PyLong_FromUnsignedLongLong( +- ((unsigned long long *)ap->ob_item)[i]); ++ ((unsigned PY_LONG_LONG *)ap->ob_item)[i]); + } + + static int + QQ_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) + { +- unsigned long long x; ++ unsigned PY_LONG_LONG x; + int do_decref = 0; /* if nb_int was called */ + + if (!PyLong_Check(v)) { +@@ -480,14 +481,14 @@ QQ_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) + do_decref = 1; + } + x = PyLong_AsUnsignedLongLong(v); +- if (x == (unsigned long long)-1 && PyErr_Occurred()) { ++ if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred()) { + if (do_decref) { + Py_DECREF(v); + } + return -1; + } + if (i >= 0) +- ((unsigned long long *)ap->ob_item)[i] = x; ++ ((unsigned PY_LONG_LONG *)ap->ob_item)[i] = x; + + if (do_decref) { + Py_DECREF(v); +@@ -534,7 +535,8 @@ d_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) + code##_compareitems(const void *lhs, const void *rhs, Py_ssize_t length) \ + { \ + const type *a = lhs, *b = rhs; \ +- for (Py_ssize_t i = 0; i < length; ++i) \ ++ Py_ssize_t i; \ ++ for (i = 0; i < length; ++i) \ + if (a[i] != b[i]) \ + return a[i] < b[i] ? -1 : 1; \ + return 0; \ +@@ -549,8 +551,8 @@ DEFINE_COMPAREITEMS(i, int) + DEFINE_COMPAREITEMS(II, unsigned int) + DEFINE_COMPAREITEMS(l, long) + DEFINE_COMPAREITEMS(LL, unsigned long) +-DEFINE_COMPAREITEMS(q, long long) +-DEFINE_COMPAREITEMS(QQ, unsigned long long) ++DEFINE_COMPAREITEMS(q, PY_LONG_LONG) ++DEFINE_COMPAREITEMS(QQ, unsigned PY_LONG_LONG) + + /* Description of types. + * +@@ -567,8 +569,8 @@ static const struct arraydescr descriptors[] = { + {'I', sizeof(int), II_getitem, II_setitem, II_compareitems, "I", 1, 0}, + {'l', sizeof(long), l_getitem, l_setitem, l_compareitems, "l", 1, 1}, + {'L', sizeof(long), LL_getitem, LL_setitem, LL_compareitems, "L", 1, 0}, +- {'q', sizeof(long long), q_getitem, q_setitem, q_compareitems, "q", 1, 1}, +- {'Q', sizeof(long long), QQ_getitem, QQ_setitem, QQ_compareitems, "Q", 1, 0}, ++ {'q', sizeof(PY_LONG_LONG), q_getitem, q_setitem, q_compareitems, "q", 1, 1}, ++ {'Q', sizeof(PY_LONG_LONG), QQ_getitem, QQ_setitem, QQ_compareitems, "Q", 1, 0}, + {'f', sizeof(float), f_getitem, f_setitem, NULL, "f", 0, 0}, + {'d', sizeof(double), d_getitem, d_setitem, NULL, "d", 0, 0}, + {'\0', 0, 0, 0, 0, 0, 0} /* Sentinel */ +@@ -623,11 +625,11 @@ newarrayobject(PyTypeObject *type, Py_ssize_t size, const struct arraydescr *des + static PyObject * + getarrayitem(PyObject *op, Py_ssize_t i) + { ++ arrayobject *ap; + #ifndef NDEBUG + array_state *state = find_array_state_by_type(Py_TYPE(op)); + assert(array_Check(op, state)); + #endif +- arrayobject *ap; + ap = (arrayobject *)op; + assert(i>=0 && iob_descr->getitem)(ap, i); +@@ -693,8 +695,9 @@ array_richcompare(PyObject *v, PyObject *w, int op) + arrayobject *va, *wa; + PyObject *vi = NULL; + PyObject *wi = NULL; +- Py_ssize_t i, k; ++ Py_ssize_t i, k, vs, ws; + PyObject *res; ++ int cmp; + + if (!array_Check(v, state) || !array_Check(w, state)) + Py_RETURN_NOTIMPLEMENTED; +@@ -721,7 +724,6 @@ array_richcompare(PyObject *v, PyObject *w, int op) + if (result == 0) + goto compare_sizes; + +- int cmp; + switch (op) { + case Py_LT: cmp = result < 0; break; + case Py_LE: cmp = result <= 0; break; +@@ -731,7 +733,7 @@ array_richcompare(PyObject *v, PyObject *w, int op) + case Py_GE: cmp = result >= 0; break; + default: return NULL; /* cannot happen */ + } +- PyObject *res = cmp ? Py_True : Py_False; ++ res = cmp ? Py_True : Py_False; + Py_INCREF(res); + return res; + } +@@ -761,9 +763,8 @@ array_richcompare(PyObject *v, PyObject *w, int op) + if (k) { + /* No more items to compare -- compare sizes */ + compare_sizes: ; +- Py_ssize_t vs = Py_SIZE(va); +- Py_ssize_t ws = Py_SIZE(wa); +- int cmp; ++ vs = Py_SIZE(va); ++ ws = Py_SIZE(wa); + switch (op) { + case Py_LT: cmp = vs < ws; break; + case Py_LE: cmp = vs <= ws; break; +@@ -913,22 +914,27 @@ static PyObject * + array_repeat(arrayobject *a, Py_ssize_t n) + { + array_state *state = find_array_state_by_type(Py_TYPE(a)); ++ Py_ssize_t array_length; ++ Py_ssize_t size; ++ arrayobject *np; ++ Py_ssize_t oldbytes; ++ Py_ssize_t newbytes; + + if (n < 0) + n = 0; +- const Py_ssize_t array_length = Py_SIZE(a); ++ array_length = Py_SIZE(a); + if ((array_length != 0) && (n > PY_SSIZE_T_MAX / array_length)) { + return PyErr_NoMemory(); + } +- Py_ssize_t size = array_length * n; +- arrayobject* np = (arrayobject *) newarrayobject(state->ArrayType, size, a->ob_descr); ++ size = array_length * n; ++ np = (arrayobject *) newarrayobject(state->ArrayType, size, a->ob_descr); + if (np == NULL) + return NULL; + if (size == 0) + return (PyObject *)np; + +- const Py_ssize_t oldbytes = array_length * a->ob_descr->itemsize; +- const Py_ssize_t newbytes = oldbytes * n; ++ oldbytes = array_length * a->ob_descr->itemsize; ++ newbytes = oldbytes * n; + _PyBytes_Repeat(np->ob_item, newbytes, a->ob_item, oldbytes); + + return (PyObject *)np; +@@ -1069,6 +1075,7 @@ static PyObject * + array_inplace_repeat(arrayobject *self, Py_ssize_t n) + { + const Py_ssize_t array_size = Py_SIZE(self); ++ Py_ssize_t size; + + if (array_size > 0 && n != 1 ) { + if (n < 0) +@@ -1077,7 +1084,7 @@ array_inplace_repeat(arrayobject *self, Py_ssize_t n) + (array_size > PY_SSIZE_T_MAX / self->ob_descr->itemsize)) { + return PyErr_NoMemory(); + } +- Py_ssize_t size = array_size * self->ob_descr->itemsize; ++ size = array_size * self->ob_descr->itemsize; + if (n > 0 && size > PY_SSIZE_T_MAX / n) { + return PyErr_NoMemory(); + } +@@ -1151,6 +1158,8 @@ array_array_index_impl(arrayobject *self, PyObject *v, Py_ssize_t start, + Py_ssize_t stop) + /*[clinic end generated code: output=c45e777880c99f52 input=089dff7baa7e5a7e]*/ + { ++ Py_ssize_t i; ++ + if (start < 0) { + start += Py_SIZE(self); + if (start < 0) { +@@ -1162,7 +1171,7 @@ array_array_index_impl(arrayobject *self, PyObject *v, Py_ssize_t start, + } + // Use Py_SIZE() for every iteration in case the array is mutated + // during PyObject_RichCompareBool() +- for (Py_ssize_t i = start; i < stop && i < Py_SIZE(self); i++) { ++ for (i = start; i < stop && i < Py_SIZE(self); i++) { + PyObject *selfi; + int cmp; + +@@ -1474,6 +1483,7 @@ array_array_fromfile_impl(arrayobject *self, PyTypeObject *cls, PyObject *f, + Py_ssize_t itemsize = self->ob_descr->itemsize; + Py_ssize_t nbytes; + int not_enough_bytes; ++ array_state *state; + + if (n < 0) { + PyErr_SetString(PyExc_ValueError, "negative count"); +@@ -1485,7 +1495,7 @@ array_array_fromfile_impl(arrayobject *self, PyTypeObject *cls, PyObject *f, + } + + +- array_state *state = get_array_state_by_class(cls); ++ state = get_array_state_by_class(cls); + assert(state != NULL); + + nbytes = n * itemsize; +@@ -1538,12 +1548,13 @@ array_array_tofile_impl(arrayobject *self, PyTypeObject *cls, PyObject *f) + int BLOCKSIZE = 64*1024; + Py_ssize_t nblocks = (nbytes + BLOCKSIZE - 1) / BLOCKSIZE; + Py_ssize_t i; ++ array_state *state; + + if (Py_SIZE(self) == 0) + goto done; + + +- array_state *state = get_array_state_by_class(cls); ++ state = get_array_state_by_class(cls); + assert(state != NULL); + + for (i = 0; i < nblocks; i++) { +@@ -1725,6 +1736,8 @@ static PyObject * + array_array_fromunicode_impl(arrayobject *self, PyObject *ustr) + /*[clinic end generated code: output=24359f5e001a7f2b input=025db1fdade7a4ce]*/ + { ++ Py_ssize_t ustr_length; ++ + if (self->ob_descr->typecode != 'u') { + PyErr_SetString(PyExc_ValueError, + "fromunicode() may only be called on " +@@ -1732,11 +1745,13 @@ array_array_fromunicode_impl(arrayobject *self, PyObject *ustr) + return NULL; + } + +- Py_ssize_t ustr_length = PyUnicode_AsWideChar(ustr, NULL, 0); ++ ustr_length = PyUnicode_AsWideChar(ustr, NULL, 0); + assert(ustr_length > 0); + if (ustr_length > 1) { ++ Py_ssize_t old_size; ++ + ustr_length--; /* trim trailing NUL character */ +- Py_ssize_t old_size = Py_SIZE(self); ++ old_size = Py_SIZE(self); + if (array_resize(self, old_size + ustr_length) == -1) { + return NULL; + } +@@ -1893,11 +1908,11 @@ typecode_to_mformat_code(char typecode) + is_signed = 0; + break; + case 'q': +- intsize = sizeof(long long); ++ intsize = sizeof(PY_LONG_LONG); + is_signed = 1; + break; + case 'Q': +- intsize = sizeof(long long); ++ intsize = sizeof(PY_LONG_LONG); + is_signed = 0; + break; + default: +@@ -2788,8 +2803,8 @@ narrow builds this is 2-bytes on wide builds this is 4-bytes.\n\ + NOTE: The 'q' and 'Q' type codes are only available if the platform\n\ + C compiler used to build Python supports 'long long', or, on Windows,\n\ + '__int64'.\n\ +-\n\ +-Methods:\n\ ++\n" ++"Methods:\n\ + \n\ + append() -- append a new item to the end of the array\n\ + buffer_info() -- return information giving the current memory info\n\ +@@ -2858,12 +2873,13 @@ static PyType_Slot array_slots[] = { + }; + + static PyType_Spec array_spec = { +- .name = "array.array", +- .basicsize = sizeof(arrayobject), +- .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | +- Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC | +- Py_TPFLAGS_SEQUENCE), +- .slots = array_slots, ++ "array.array", ++ sizeof(arrayobject), ++ 0, ++ (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | ++ Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC | ++ Py_TPFLAGS_SEQUENCE), ++ array_slots, + }; + + /*********************** Array Iterator **************************/ +@@ -2900,10 +2916,11 @@ static PyObject * + arrayiter_next(arrayiterobject *it) + { + arrayobject *ao; ++ array_state *state; + + assert(it != NULL); + #ifndef NDEBUG +- array_state *state = find_array_state_by_type(Py_TYPE(it)); ++ state = find_array_state_by_type(Py_TYPE(it)); + assert(PyObject_TypeCheck(it, state->ArrayIterType)); + #endif + ao = it->ao; +@@ -2953,10 +2970,12 @@ static PyObject * + array_arrayiterator___reduce___impl(arrayiterobject *self, PyTypeObject *cls) + /*[clinic end generated code: output=4b032417a2c8f5e6 input=ac64e65a87ad452e]*/ + { ++ array_state *state; ++ PyObject *func; + +- array_state *state = get_array_state_by_class(cls); ++ state = get_array_state_by_class(cls); + assert(state != NULL); +- PyObject *func = _PyEval_GetBuiltin(state->str_iter); ++ func = _PyEval_GetBuiltin(state->str_iter); + if (self->ao == NULL) { + return Py_BuildValue("N(())", func); + } +@@ -3004,11 +3023,12 @@ static PyType_Slot arrayiter_slots[] = { + }; + + static PyType_Spec arrayiter_spec = { +- .name = "array.arrayiterator", +- .basicsize = sizeof(arrayiterobject), +- .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | +- Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE), +- .slots = arrayiter_slots, ++ "array.arrayiterator", ++ sizeof(arrayiterobject), ++ 0, ++ (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | ++ Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE), ++ arrayiter_slots, + }; + + +@@ -3072,6 +3092,9 @@ array_modexec(PyObject *m) + array_state *state = get_array_state(m); + char buffer[Py_ARRAY_LENGTH(descriptors)], *p; + PyObject *typecodes; ++ PyObject *abc_mod; ++ PyObject *mutablesequence; ++ PyObject *res; + const struct arraydescr *descr; + + /* Add interned strings */ +@@ -3091,18 +3114,18 @@ array_modexec(PyObject *m) + return -1; + } + +- PyObject *abc_mod = PyImport_ImportModule("collections.abc"); ++ abc_mod = PyImport_ImportModule("collections.abc"); + if (!abc_mod) { + Py_DECREF((PyObject *)state->ArrayType); + return -1; + } +- PyObject *mutablesequence = PyObject_GetAttrString(abc_mod, "MutableSequence"); ++ mutablesequence = PyObject_GetAttrString(abc_mod, "MutableSequence"); + Py_DECREF(abc_mod); + if (!mutablesequence) { + Py_DECREF((PyObject *)state->ArrayType); + return -1; + } +- PyObject *res = PyObject_CallMethod(mutablesequence, "register", "O", ++ res = PyObject_CallMethod(mutablesequence, "register", "O", + (PyObject *)state->ArrayType); + Py_DECREF(mutablesequence); + if (!res) { +@@ -3135,15 +3158,15 @@ static PyModuleDef_Slot arrayslots[] = { + + + static struct PyModuleDef arraymodule = { +- .m_base = PyModuleDef_HEAD_INIT, +- .m_name = "array", +- .m_size = sizeof(array_state), +- .m_doc = module_doc, +- .m_methods = a_methods, +- .m_slots = arrayslots, +- .m_traverse = array_traverse, +- .m_clear = array_clear, +- .m_free = array_free, ++ PyModuleDef_HEAD_INIT, ++ "array", ++ module_doc, ++ sizeof(array_state), ++ a_methods, ++ arrayslots, ++ array_traverse, ++ array_clear, ++ array_free, + }; + + +diff --git a/Modules/atexitmodule.c b/Modules/atexitmodule.c +index a1c511e..08a5a53 100644 +--- a/Modules/atexitmodule.c ++++ b/Modules/atexitmodule.c +@@ -40,7 +40,8 @@ static void + atexit_cleanup(struct atexit_state *state) + { + atexit_callback *cb; +- for (int i = 0; i < state->ncallbacks; i++) { ++ int i; ++ for (i = 0; i < state->ncallbacks; i++) { + cb = state->callbacks[i]; + if (cb == NULL) + continue; +@@ -81,21 +82,24 @@ _PyAtExit_Fini(PyInterpreterState *interp) + static void + atexit_callfuncs(struct atexit_state *state) + { ++ int i; ++ PyObject *the_func; ++ PyObject *res; + assert(!PyErr_Occurred()); + + if (state->ncallbacks == 0) { + return; + } + +- for (int i = state->ncallbacks - 1; i >= 0; i--) { ++ for (i = state->ncallbacks - 1; i >= 0; i--) { + atexit_callback *cb = state->callbacks[i]; + if (cb == NULL) { + continue; + } + + // bpo-46025: Increment the refcount of cb->func as the call itself may unregister it +- PyObject* the_func = Py_NewRef(cb->func); +- PyObject *res = PyObject_Call(cb->func, cb->args, cb->kwargs); ++ the_func = Py_NewRef(cb->func); ++ res = PyObject_Call(cb->func, cb->args, cb->kwargs); + if (res == NULL) { + _PyErr_WriteUnraisableMsg("in atexit callback", the_func); + } +@@ -137,24 +141,29 @@ Register a function to be executed upon normal program termination\n\ + static PyObject * + atexit_register(PyObject *module, PyObject *args, PyObject *kwargs) + { ++ PyObject *func; ++ struct atexit_state *state; ++ atexit_callback **r; ++ size_t size; ++ atexit_callback *callback; ++ + if (PyTuple_GET_SIZE(args) == 0) { + PyErr_SetString(PyExc_TypeError, + "register() takes at least 1 argument (0 given)"); + return NULL; + } + +- PyObject *func = PyTuple_GET_ITEM(args, 0); ++ func = PyTuple_GET_ITEM(args, 0); + if (!PyCallable_Check(func)) { + PyErr_SetString(PyExc_TypeError, + "the first argument must be callable"); + return NULL; + } + +- struct atexit_state *state = get_atexit_state(); ++ state = get_atexit_state(); + if (state->ncallbacks >= state->callback_len) { +- atexit_callback **r; + state->callback_len += 16; +- size_t size = sizeof(atexit_callback*) * (size_t)state->callback_len; ++ size = sizeof(atexit_callback*) * (size_t)state->callback_len; + r = (atexit_callback**)PyMem_Realloc(state->callbacks, size); + if (r == NULL) { + return PyErr_NoMemory(); +@@ -162,7 +171,7 @@ atexit_register(PyObject *module, PyObject *args, PyObject *kwargs) + state->callbacks = r; + } + +- atexit_callback *callback = PyMem_Malloc(sizeof(atexit_callback)); ++ callback = PyMem_Malloc(sizeof(atexit_callback)); + if (callback == NULL) { + return PyErr_NoMemory(); + } +@@ -231,14 +240,18 @@ static PyObject * + atexit_unregister(PyObject *module, PyObject *func) + { + struct atexit_state *state = get_atexit_state(); +- for (int i = 0; i < state->ncallbacks; i++) ++ int i; ++ atexit_callback *cb; ++ int eq; ++ ++ for (i = 0; i < state->ncallbacks; i++) + { +- atexit_callback *cb = state->callbacks[i]; ++ cb = state->callbacks[i]; + if (cb == NULL) { + continue; + } + +- int eq = PyObject_RichCompareBool(cb->func, func, Py_EQ); ++ eq = PyObject_RichCompareBool(cb->func, func, Py_EQ); + if (eq < 0) { + return NULL; + } +@@ -277,10 +290,10 @@ Two public functions, register and unregister, are defined.\n\ + + static struct PyModuleDef atexitmodule = { + PyModuleDef_HEAD_INIT, +- .m_name = "atexit", +- .m_doc = atexit__doc__, +- .m_size = 0, +- .m_methods = atexit_methods, ++ "atexit", ++ atexit__doc__, ++ 0, ++ atexit_methods, + }; + + PyMODINIT_FUNC +diff --git a/Modules/audioop.c b/Modules/audioop.c +index 88bb4c1..73bee0d 100644 +--- a/Modules/audioop.c ++++ b/Modules/audioop.c +@@ -1372,7 +1372,7 @@ audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width, + weightA /= d; + weightB /= d; + +- if ((size_t)nchannels > SIZE_MAX/sizeof(int)) { ++ if ((size_t)nchannels > ((size_t)-1)/sizeof(int)) { + PyErr_SetString(PyExc_MemoryError, + "not enough memory for output buffer"); + return NULL; +diff --git a/Modules/binascii.c b/Modules/binascii.c +index de3c2d8..d1dfc0d 100644 +--- a/Modules/binascii.c ++++ b/Modules/binascii.c +@@ -388,21 +388,34 @@ static PyObject * + binascii_a2b_base64_impl(PyObject *module, Py_buffer *data, int strict_mode) + /*[clinic end generated code: output=5409557788d4f975 input=3a30c4e3528317c6]*/ + { ++ const unsigned char *ascii_data; ++ size_t ascii_len; ++ binascii_state *state; ++ char padding_started; ++ Py_ssize_t bin_len; ++ _PyBytesWriter writer; ++ unsigned char *bin_data; ++ unsigned char *bin_data_start; ++ int quad_pos; ++ unsigned char leftchar; ++ int pads; ++ size_t i; ++ unsigned char this_ch; ++ + assert(data->len >= 0); + +- const unsigned char *ascii_data = data->buf; +- size_t ascii_len = data->len; +- binascii_state *state = NULL; +- char padding_started = 0; ++ ascii_data = data->buf; ++ ascii_len = data->len; ++ state = NULL; ++ padding_started = 0; + + /* Allocate the buffer */ +- Py_ssize_t bin_len = ((ascii_len+3)/4)*3; /* Upper bound, corrected later */ +- _PyBytesWriter writer; ++ bin_len = ((ascii_len+3)/4)*3; /* Upper bound, corrected later */ + _PyBytesWriter_Init(&writer); +- unsigned char *bin_data = _PyBytesWriter_Alloc(&writer, bin_len); ++ bin_data = _PyBytesWriter_Alloc(&writer, bin_len); + if (bin_data == NULL) + return NULL; +- unsigned char *bin_data_start = bin_data; ++ bin_data_start = bin_data; + + if (strict_mode && ascii_len > 0 && ascii_data[0] == '=') { + state = get_binascii_state(module); +@@ -412,11 +425,11 @@ binascii_a2b_base64_impl(PyObject *module, Py_buffer *data, int strict_mode) + goto error_end; + } + +- int quad_pos = 0; +- unsigned char leftchar = 0; +- int pads = 0; +- for (size_t i = 0; i < ascii_len; i++) { +- unsigned char this_ch = ascii_data[i]; ++ quad_pos = 0; ++ leftchar = 0; ++ pads = 0; ++ for (i = 0; i < ascii_len; i++) { ++ this_ch = ascii_data[i]; + + /* Check for pad sequences and ignore + ** the invalid ones. +diff --git a/Modules/clinic/_codecsmodule.c.h b/Modules/clinic/_codecsmodule.c.h +index 29e9d5e..7bc9c5c 100644 +--- a/Modules/clinic/_codecsmodule.c.h ++++ b/Modules/clinic/_codecsmodule.c.h +@@ -43,12 +43,12 @@ _codecs_lookup(PyObject *module, PyObject *arg) + { + PyObject *return_value = NULL; + const char *encoding; ++ Py_ssize_t encoding_length; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("lookup", "argument", "str", arg); + goto exit; + } +- Py_ssize_t encoding_length; + encoding = PyUnicode_AsUTF8AndSize(arg, &encoding_length); + if (encoding == NULL) { + goto exit; +@@ -93,6 +93,8 @@ _codecs_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje + PyObject *obj; + const char *encoding = NULL; + const char *errors = NULL; ++ Py_ssize_t encoding_length; ++ Py_ssize_t errors_length; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { +@@ -107,7 +109,6 @@ _codecs_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje + _PyArg_BadArgument("encode", "argument 'encoding'", "str", args[1]); + goto exit; + } +- Py_ssize_t encoding_length; + encoding = PyUnicode_AsUTF8AndSize(args[1], &encoding_length); + if (encoding == NULL) { + goto exit; +@@ -124,7 +125,6 @@ _codecs_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje + _PyArg_BadArgument("encode", "argument 'errors'", "str", args[2]); + goto exit; + } +- Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[2], &errors_length); + if (errors == NULL) { + goto exit; +@@ -170,6 +170,8 @@ _codecs_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje + PyObject *obj; + const char *encoding = NULL; + const char *errors = NULL; ++ Py_ssize_t encoding_length; ++ Py_ssize_t errors_length; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { +@@ -184,7 +186,6 @@ _codecs_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje + _PyArg_BadArgument("decode", "argument 'encoding'", "str", args[1]); + goto exit; + } +- Py_ssize_t encoding_length; + encoding = PyUnicode_AsUTF8AndSize(args[1], &encoding_length); + if (encoding == NULL) { + goto exit; +@@ -201,7 +202,6 @@ _codecs_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje + _PyArg_BadArgument("decode", "argument 'errors'", "str", args[2]); + goto exit; + } +- Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[2], &errors_length); + if (errors == NULL) { + goto exit; +@@ -2730,6 +2730,7 @@ _codecs_register_error(PyObject *module, PyObject *const *args, Py_ssize_t nargs + PyObject *return_value = NULL; + const char *errors; + PyObject *handler; ++ Py_ssize_t errors_length; + + if (!_PyArg_CheckPositional("register_error", nargs, 2, 2)) { + goto exit; +@@ -2738,7 +2739,6 @@ _codecs_register_error(PyObject *module, PyObject *const *args, Py_ssize_t nargs + _PyArg_BadArgument("register_error", "argument 1", "str", args[0]); + goto exit; + } +- Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[0], &errors_length); + if (errors == NULL) { + goto exit; +@@ -2774,12 +2774,12 @@ _codecs_lookup_error(PyObject *module, PyObject *arg) + { + PyObject *return_value = NULL; + const char *name; ++ Py_ssize_t name_length; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("lookup_error", "argument", "str", arg); + goto exit; + } +- Py_ssize_t name_length; + name = PyUnicode_AsUTF8AndSize(arg, &name_length); + if (name == NULL) { + goto exit; +diff --git a/Modules/clinic/_pickle.c.h b/Modules/clinic/_pickle.c.h +index 5dc62fe..7f4e83f 100644 +--- a/Modules/clinic/_pickle.c.h ++++ b/Modules/clinic/_pickle.c.h +@@ -336,6 +336,8 @@ _pickle_Unpickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) + int fix_imports = 1; + const char *encoding = "ASCII"; + const char *errors = "strict"; ++ Py_ssize_t encoding_length; ++ Py_ssize_t errors_length; + PyObject *buffers = NULL; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf); +@@ -360,7 +362,6 @@ _pickle_Unpickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) + _PyArg_BadArgument("Unpickler", "argument 'encoding'", "str", fastargs[2]); + goto exit; + } +- Py_ssize_t encoding_length; + encoding = PyUnicode_AsUTF8AndSize(fastargs[2], &encoding_length); + if (encoding == NULL) { + goto exit; +@@ -378,7 +379,6 @@ _pickle_Unpickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) + _PyArg_BadArgument("Unpickler", "argument 'errors'", "str", fastargs[3]); + goto exit; + } +- Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(fastargs[3], &errors_length); + if (errors == NULL) { + goto exit; +@@ -671,6 +671,8 @@ _pickle_load(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject + int fix_imports = 1; + const char *encoding = "ASCII"; + const char *errors = "strict"; ++ Py_ssize_t encoding_length; ++ Py_ssize_t errors_length; + PyObject *buffers = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); +@@ -695,7 +697,6 @@ _pickle_load(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject + _PyArg_BadArgument("load", "argument 'encoding'", "str", args[2]); + goto exit; + } +- Py_ssize_t encoding_length; + encoding = PyUnicode_AsUTF8AndSize(args[2], &encoding_length); + if (encoding == NULL) { + goto exit; +@@ -713,7 +714,6 @@ _pickle_load(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject + _PyArg_BadArgument("load", "argument 'errors'", "str", args[3]); + goto exit; + } +- Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[3], &errors_length); + if (errors == NULL) { + goto exit; +@@ -774,6 +774,8 @@ _pickle_loads(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec + int fix_imports = 1; + const char *encoding = "ASCII"; + const char *errors = "strict"; ++ Py_ssize_t encoding_length; ++ Py_ssize_t errors_length; + PyObject *buffers = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); +@@ -798,7 +800,6 @@ _pickle_loads(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec + _PyArg_BadArgument("loads", "argument 'encoding'", "str", args[2]); + goto exit; + } +- Py_ssize_t encoding_length; + encoding = PyUnicode_AsUTF8AndSize(args[2], &encoding_length); + if (encoding == NULL) { + goto exit; +@@ -816,7 +817,6 @@ _pickle_loads(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec + _PyArg_BadArgument("loads", "argument 'errors'", "str", args[3]); + goto exit; + } +- Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[3], &errors_length); + if (errors == NULL) { + goto exit; +diff --git a/Modules/cmathmodule.c b/Modules/cmathmodule.c +index 7fffb31..51f5782 100644 +--- a/Modules/cmathmodule.c ++++ b/Modules/cmathmodule.c +@@ -1414,11 +1414,11 @@ static PyModuleDef_Slot cmath_slots[] = { + + static struct PyModuleDef cmathmodule = { + PyModuleDef_HEAD_INIT, +- .m_name = "cmath", +- .m_doc = module_doc, +- .m_size = 0, +- .m_methods = cmath_methods, +- .m_slots = cmath_slots ++ "cmath", ++ module_doc, ++ 0, ++ cmath_methods, ++ cmath_slots + }; + + PyMODINIT_FUNC +diff --git a/Modules/errnomodule.c b/Modules/errnomodule.c +index a63ac72..9a065af 100644 +--- a/Modules/errnomodule.c ++++ b/Modules/errnomodule.c +@@ -49,18 +49,22 @@ static PyMethodDef errno_methods[] = { + static int + _add_errcode(PyObject *module_dict, PyObject *error_dict, const char *name_str, int code_int) + { +- PyObject *name = PyUnicode_FromString(name_str); ++ PyObject *name; ++ PyObject *code; ++ int ret; ++ ++ name = PyUnicode_FromString(name_str); + if (!name) { + return -1; + } + +- PyObject *code = PyLong_FromLong(code_int); ++ code = PyLong_FromLong(code_int); + if (!code) { + Py_DECREF(name); + return -1; + } + +- int ret = -1; ++ ret = -1; + /* insert in modules dict */ + if (PyDict_SetItem(module_dict, name, code) < 0) { + goto end; +@@ -79,11 +83,14 @@ _add_errcode(PyObject *module_dict, PyObject *error_dict, const char *name_str, + static int + errno_exec(PyObject *module) + { +- PyObject *module_dict = PyModule_GetDict(module); // Borrowed ref. ++ PyObject *module_dict; ++ PyObject *error_dict; ++ ++ module_dict = PyModule_GetDict(module); // Borrowed ref. + if (module_dict == NULL) { + return -1; + } +- PyObject *error_dict = PyDict_New(); ++ error_dict = PyDict_New(); + if (error_dict == NULL) { + return -1; + } +@@ -960,11 +967,14 @@ e.g. os.strerror(2) could return 'No such file or directory'."); + + static struct PyModuleDef errnomodule = { + PyModuleDef_HEAD_INIT, +- .m_name = "errno", +- .m_doc = errno__doc__, +- .m_size = 0, +- .m_methods = errno_methods, +- .m_slots = errno_slots, ++ "errno", ++ errno__doc__, ++ 0, ++ errno_methods, ++ errno_slots, ++ NULL, ++ NULL, ++ NULL + }; + + PyMODINIT_FUNC +diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c +index 520b7b6..67d9fc1 100644 +--- a/Modules/faulthandler.c ++++ b/Modules/faulthandler.c +@@ -231,6 +231,7 @@ faulthandler_dump_traceback(int fd, int all_threads, + PyInterpreterState *interp) + { + static volatile int reentrant = 0; ++ PyThreadState *tstate; + + if (reentrant) + return; +@@ -245,7 +246,7 @@ faulthandler_dump_traceback(int fd, int all_threads, + fault if the thread released the GIL, and so this function cannot be + used. Read the thread specific storage (TSS) instead: call + PyGILState_GetThisThreadState(). */ +- PyThreadState *tstate = PyGILState_GetThisThreadState(); ++ tstate = PyGILState_GetThisThreadState(); + + if (all_threads) { + (void)_Py_DumpTracebackThreads(fd, NULL, tstate); +@@ -406,8 +407,13 @@ static LONG WINAPI + faulthandler_exc_handler(struct _EXCEPTION_POINTERS *exc_info) + { + const int fd = fatal_error.fd; +- DWORD code = exc_info->ExceptionRecord->ExceptionCode; +- DWORD flags = exc_info->ExceptionRecord->ExceptionFlags; ++ DWORD code; ++ DWORD flags; ++ size_t i; ++ fault_handler_t *handler; ++ ++ code = exc_info->ExceptionRecord->ExceptionCode; ++ flags = exc_info->ExceptionRecord->ExceptionFlags; + + if (faulthandler_ignore_exception(code)) { + /* ignore the exception: call the next exception handler */ +@@ -433,8 +439,8 @@ faulthandler_exc_handler(struct _EXCEPTION_POINTERS *exc_info) + + if (code == EXCEPTION_ACCESS_VIOLATION) { + /* disable signal handler for SIGSEGV */ +- for (size_t i=0; i < faulthandler_nsignals; i++) { +- fault_handler_t *handler = &faulthandler_handlers[i]; ++ for (i = 0; i < faulthandler_nsignals; i++) { ++ handler = &faulthandler_handlers[i]; + if (handler->signum == SIGSEGV) { + faulthandler_disable_fatal_handler(handler); + break; +@@ -455,6 +461,8 @@ faulthandler_exc_handler(struct _EXCEPTION_POINTERS *exc_info) + static int + faulthandler_allocate_stack(void) + { ++ int err; ++ + if (stack.ss_sp != NULL) { + return 0; + } +@@ -466,7 +474,7 @@ faulthandler_allocate_stack(void) + return -1; + } + +- int err = sigaltstack(&stack, &old_stack); ++ err = sigaltstack(&stack, &old_stack); + if (err) { + PyErr_SetFromErrno(PyExc_OSError); + /* Release the stack to retry sigaltstack() next time */ +@@ -484,6 +492,10 @@ faulthandler_allocate_stack(void) + static int + faulthandler_enable(void) + { ++ size_t i; ++ fault_handler_t *handler; ++ int err; ++ + if (fatal_error.enabled) { + return 0; + } +@@ -495,10 +507,7 @@ faulthandler_enable(void) + } + #endif + +- for (size_t i=0; i < faulthandler_nsignals; i++) { +- fault_handler_t *handler; +- int err; +- ++ for (i = 0; i < faulthandler_nsignals; i++) { + handler = &faulthandler_handlers[i]; + assert(!handler->enabled); + #ifdef HAVE_SIGACTION +@@ -572,10 +581,12 @@ faulthandler_py_enable(PyObject *self, PyObject *args, PyObject *kwargs) + static void + faulthandler_disable(void) + { ++ size_t i; ++ fault_handler_t *handler; ++ + if (fatal_error.enabled) { + fatal_error.enabled = 0; +- for (size_t i=0; i < faulthandler_nsignals; i++) { +- fault_handler_t *handler; ++ for (i = 0; i < faulthandler_nsignals; i++) { + handler = &faulthandler_handlers[i]; + faulthandler_disable_fatal_handler(handler); + } +@@ -1027,8 +1038,10 @@ faulthandler_suppress_crash_report(void) + #ifdef _MSC_VER + /* Visual Studio: configure abort() to not display an error message nor + open a popup asking to report the fault. */ ++#if defined(_WRITE_ABORT_MSG) && defined(_CALL_REPORTFAULT) + _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); + #endif ++#endif + } + + static PyObject* _Py_NO_SANITIZE_UNDEFINED +@@ -1087,7 +1100,7 @@ faulthandler_sigsegv(PyObject *self, PyObject *args) + static void _Py_NO_RETURN + faulthandler_fatal_error_thread(void *plock) + { +- Py_FatalError("in new thread"); ++ _Py_FatalErrorFunc("faulthandler_fatal_error_thread", "in new thread"); + } + + static PyObject * +@@ -1123,11 +1136,16 @@ faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args) + static PyObject* _Py_NO_SANITIZE_UNDEFINED + faulthandler_sigfpe(PyObject *self, PyObject *args) + { ++ volatile int x; ++ volatile int y; ++ volatile int z; ++ + faulthandler_suppress_crash_report(); + + /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on + PowerPC. Use volatile to disable compile-time optimizations. */ +- volatile int x = 1, y = 0, z; ++ x = 1; ++ y = 0; + z = x / y; + + /* If the division by zero didn't raise a SIGFPE (e.g. on PowerPC), +@@ -1332,11 +1350,14 @@ static PyModuleDef_Slot faulthandler_slots[] = { + + static struct PyModuleDef module_def = { + PyModuleDef_HEAD_INIT, +- .m_name = "faulthandler", +- .m_doc = module_doc, +- .m_methods = module_methods, +- .m_traverse = faulthandler_traverse, +- .m_slots = faulthandler_slots ++ "faulthandler", ++ module_doc, ++ -1, ++ module_methods, ++ faulthandler_slots, ++ faulthandler_traverse, ++ NULL, ++ NULL + }; + + PyMODINIT_FUNC +@@ -1348,12 +1369,15 @@ PyInit_faulthandler(void) + static int + faulthandler_init_enable(void) + { +- PyObject *module = PyImport_ImportModule("faulthandler"); ++ PyObject *module; ++ PyObject *res; ++ ++ module = PyImport_ImportModule("faulthandler"); + if (module == NULL) { + return -1; + } + +- PyObject *res = PyObject_CallMethodNoArgs(module, &_Py_ID(enable)); ++ res = PyObject_CallMethodNoArgs(module, &_Py_ID(enable)); + Py_DECREF(module); + if (res == NULL) { + return -1; diff --git a/Modules/getpath.c b/Modules/getpath.c index 61d6540..e7489ee 100644 --- a/Modules/getpath.c diff --git a/scripts/vc6-probe-pythoncore-frontier.sh b/scripts/vc6-probe-pythoncore-frontier.sh index 5a96ed1..70cdf57 100755 --- a/scripts/vc6-probe-pythoncore-frontier.sh +++ b/scripts/vc6-probe-pythoncore-frontier.sh @@ -127,6 +127,10 @@ def walk(node, inherited_condition=""): for child in node: if child.tag == ns + "PreprocessorDefinitions": defs.extend(split_definitions(child.text or "")) + if rel == "cpython/Modules/binascii.c": + # binascii.c has a complete local CRC32 fallback. Do not require + # the external zlib headers in the minimal VC6 frontier. + defs = [define for define in defs if define != "USE_ZLIB_CRC32"] action = classify(rel, inherited_condition, condition) reason = action if action == "compile" and norm_error: diff --git a/scripts/vc6-probe-pythoncore-frontier.test.sh b/scripts/vc6-probe-pythoncore-frontier.test.sh index 6c61939..c07cb17 100755 --- a/scripts/vc6-probe-pythoncore-frontier.test.sh +++ b/scripts/vc6-probe-pythoncore-frontier.test.sh @@ -62,6 +62,16 @@ case "$sysmodule_defs" in ;; esac +binascii_defs="$(printf '%s\n' "$out" | awk -F '\t' '$2 == "cpython/Modules/binascii.c" { print $4; exit }')" +case "$binascii_defs" in + *USE_ZLIB_CRC32*) + bad "frontier disables unavailable zlib CRC32 path for binascii.c (got: $binascii_defs)" + ;; + *) + pass "frontier disables unavailable zlib CRC32 path for binascii.c" + ;; +esac + # Source the probe after --list-only so the guarded helper definitions can be # tested without launching Wine or requiring MSVC600. # shellcheck source=scripts/vc6-probe-pythoncore-frontier.sh @@ -100,6 +110,2110 @@ else pass "frontier normalized source column contains no backslashes" fi +# Keep the current cmath.c VC6 frontier explicit: the old compiler has no C99 +# NAN macro, so pymath.h must provide Py_NAN without referring to NAN. +if python3 - "$REPO_ROOT/cpython/Include/pymath.h" <<'PY' +import sys +from pathlib import Path +source = Path(sys.argv[1]).read_text() +if "# if defined(_MSC_VER) && _MSC_VER < 1300" not in source: + raise SystemExit(1) +start = source.index("#if !defined(Py_NAN)") +end = source.index("#endif\n\n#endif /* Py_PYMATH_H */", start) +block = source[start:end] +if "# define Py_NAN (Py_HUGE_VAL * 0.0)" not in block: + raise SystemExit(1) +if "# define Py_NAN ((double)NAN)" not in block: + raise SystemExit(1) +PY +then + pass "pymath.h provides a VC6 Py_NAN fallback without C99 NAN" +else + bad "pymath.h provides a VC6 Py_NAN fallback without C99 NAN" +fi + +# Keep the first _pickle.c VC6/C89 slice explicit: batch_list_exact() must +# declare its shared error local before executable statements. +if python3 - "$REPO_ROOT/cpython/Modules/_pickle.c" <<'PY' +import sys +from pathlib import Path +source = Path(sys.argv[1]).read_text() +start = source.index("batch_list_exact(PicklerObject *self, PyObject *obj)") +end = source.index("\n}\n\nstatic int\nsave_list", start) + 2 +function = source[start:end] +if " int err;" not in function: + raise SystemExit(1) +if " int err = save(self, item, 0);" in function: + raise SystemExit(1) +if function.count(" err = save(self, item, 0);") != 2: + raise SystemExit(1) +PY +then + pass "_pickle batch_list_exact uses C89 declaration-order-safe error local" +else + bad "_pickle batch_list_exact uses C89 declaration-order-safe error local" +fi + +# Keep the next _pickle.c VC6/C89 slice explicit: save_set() must declare its +# shared error local before the loop's executable statements. +if python3 - "$REPO_ROOT/cpython/Modules/_pickle.c" <<'PY' +import sys +from pathlib import Path +source = Path(sys.argv[1]).read_text() +start = source.index("save_set(PicklerObject *self, PyObject *obj)") +end = source.index("\n}\n\nstatic int\nsave_frozenset", start) + 2 +function = source[start:end] +if " int err;" not in function: + raise SystemExit(1) +if " int err = save(self, item, 0);" in function: + raise SystemExit(1) +if function.count(" err = save(self, item, 0);") != 1: + raise SystemExit(1) +PY +then + pass "_pickle save_set uses C89 declaration-order-safe error local" +else + bad "_pickle save_set uses C89 declaration-order-safe error local" +fi + +# Keep the current _pickle.c VC6/C89 frontier explicit: Pickler_traverse() +# must declare memo before the preceding Py_VISIT executable statements. +if python3 - "$REPO_ROOT/cpython/Modules/_pickle.c" <<'PY' +import sys +from pathlib import Path +source = Path(sys.argv[1]).read_text() +start = source.index("Pickler_traverse(PicklerObject *self, visitproc visit, void *arg)") +end = source.index("\n}\n\nstatic int\nPickler_clear", start) + 2 +function = source[start:end] +if " PyMemoTable *memo;" not in function: + raise SystemExit(1) +if " PyMemoTable *memo = self->memo;" in function: + raise SystemExit(1) +if function.count(" memo = self->memo;") != 1: + raise SystemExit(1) +PY +then + pass "_pickle Pickler_traverse uses C89 declaration-order-safe memo local" +else + bad "_pickle Pickler_traverse uses C89 declaration-order-safe memo local" +fi + +# Keep the current _pickle.c VC6/C89 frontier explicit: Unpickler_traverse() +# must declare memo before the preceding Py_VISIT executable statements. +if python3 - "$REPO_ROOT/cpython/Modules/_pickle.c" <<'PY' +import sys +from pathlib import Path +source = Path(sys.argv[1]).read_text() +start = source.index("Unpickler_traverse(UnpicklerObject *self, visitproc visit, void *arg)") +end = source.index("\n}\n\nstatic int\nUnpickler_clear", start) + 2 +function = source[start:end] +if " PyObject **memo;" not in function: + raise SystemExit(1) +if " PyObject **memo = self->memo;" in function: + raise SystemExit(1) +if function.count(" memo = self->memo;") != 1: + raise SystemExit(1) +PY +then + pass "_pickle Unpickler_traverse uses C89 declaration-order-safe memo local" +else + bad "_pickle Unpickler_traverse uses C89 declaration-order-safe memo local" +fi + +# The next _pickle.c VC6/C89 slice is PicklerMemoProxy.copy(): its loop counter +# must be declared before executable statements and assigned in the for init. +if python3 - "$REPO_ROOT/cpython/Modules/_pickle.c" <<'PY' +import sys +from pathlib import Path +source = Path(sys.argv[1]).read_text() +start = source.index("_pickle_PicklerMemoProxy_copy_impl(PicklerMemoProxyObject *self)") +end = source.index("\n}\n\n/*[clinic input]", start) + 2 +function = source[start:end] +if " size_t i;" not in function: + raise SystemExit(1) +if "for (size_t i = 0;" in function: + raise SystemExit(1) +if function.count("for (i = 0;") != 1: + raise SystemExit(1) +PY +then + pass "_pickle PicklerMemoProxy.copy uses C89 declaration-order-safe loop counter" +else + bad "_pickle PicklerMemoProxy.copy uses C89 declaration-order-safe loop counter" +fi + +# Keep the current _pickle.c frontier explicit: load_readonly_buffer() must +# hoist its locals before the initial executable stack-underflow check. +if python3 - "$REPO_ROOT/cpython/Modules/_pickle.c" <<'PY' +import sys +from pathlib import Path +source = Path(sys.argv[1]).read_text() +start = source.index("load_readonly_buffer(UnpicklerObject *self)") +end = source.index("\n}\n\nstatic int\nload_unicode", start) + 2 +function = source[start:end] +if " Py_ssize_t len;" not in function: + raise SystemExit(1) +if " PyObject *obj;" not in function: + raise SystemExit(1) +if " PyObject *view;" not in function: + raise SystemExit(1) +if " Py_ssize_t len = Py_SIZE(self->stack);" in function: + raise SystemExit(1) +if " PyObject *obj = self->stack->data[len - 1];" in function: + raise SystemExit(1) +if " PyObject *view = PyMemoryView_FromObject(obj);" in function: + raise SystemExit(1) +if function.count(" len = Py_SIZE(self->stack);") != 1: + raise SystemExit(1) +if function.count(" obj = self->stack->data[len - 1];") != 1: + raise SystemExit(1) +if function.count(" view = PyMemoryView_FromObject(obj);") != 1: + raise SystemExit(1) +PY +then + pass "_pickle load_readonly_buffer uses C89 declaration-order-safe locals" +else + bad "_pickle load_readonly_buffer uses C89 declaration-order-safe locals" +fi + +# Keep the current _pickle.c frontier explicit: load_next_buffer() must hoist +# its locals before the initial executable NULL check. +if python3 - "$REPO_ROOT/cpython/Modules/_pickle.c" <<'PY' +import sys +from pathlib import Path +source = Path(sys.argv[1]).read_text() +start = source.index("load_next_buffer(UnpicklerObject *self)") +end = source.index("\n}\n\nstatic int\nload_readonly_buffer", start) + 2 +function = source[start:end] +if " PickleState *st;" not in function: + raise SystemExit(1) +if " PyObject *buf;" not in function: + raise SystemExit(1) +if " PickleState *st = _Pickle_GetGlobalState();" in function: + raise SystemExit(1) +if " PyObject *buf = PyIter_Next(self->buffers);" in function: + raise SystemExit(1) +if function.count(" st = _Pickle_GetGlobalState();") != 2: + raise SystemExit(1) +if " buf = PyIter_Next(self->buffers);" not in function: + raise SystemExit(1) +PY +then + pass "_pickle load_next_buffer uses C89 declaration-order-safe locals" +else + bad "_pickle load_next_buffer uses C89 declaration-order-safe locals" +fi + +# Keep the current _pickle.c VC6/C89 frontier explicit: Unpickler_set_memo() +# must hoist its loop counter before both executable loop sites. +if python3 - "$REPO_ROOT/cpython/Modules/_pickle.c" <<'PY' +import sys +from pathlib import Path +source = Path(sys.argv[1]).read_text() +start = source.index("Unpickler_set_memo(UnpicklerObject *self") +end = source.index("\n}\n\nstatic PyObject *\nUnpickler_get_persload", start) + 2 +function = source[start:end] +if " size_t i;" not in function: + raise SystemExit(1) +if "for (size_t i = new_memo_size - 1;" in function: + raise SystemExit(1) +if "for (size_t i = 0;" in function: + raise SystemExit(1) +if function.count("for (i = 0;") != 1: + raise SystemExit(1) +if function.count("for (i = new_memo_size; i-- > 0;)") != 1: + raise SystemExit(1) +PY +then + pass "_pickle Unpickler_set_memo uses C89 declaration-order-safe loop counter" +else + bad "_pickle Unpickler_set_memo uses C89 declaration-order-safe loop counter" +fi + +# The active _pickle.c frontier must not depend on SIZE_MAX, which VC6's +# standard headers do not provide. The cleanup loop must retain the same +# descending index sequence using a C89-safe post-decrement condition. +if python3 - "$REPO_ROOT/cpython/Modules/_pickle.c" <<'PY' +import sys +from pathlib import Path +source = Path(sys.argv[1]).read_text() +start = source.index("Unpickler_set_memo(UnpicklerObject *self") +end = source.index("\n}\n\nstatic PyObject *\nUnpickler_get_persload", start) + 2 +function = source[start:end] +if "SIZE_MAX" in function: + raise SystemExit(1) +if "for (i--; i != 0; i--)" in function: + raise SystemExit(1) +if "for (i = new_memo_size; i-- > 0;)" not in function: + raise SystemExit(1) +PY +then + pass "_pickle Unpickler_set_memo cleanup avoids unavailable SIZE_MAX" +else + bad "_pickle Unpickler_set_memo cleanup avoids unavailable SIZE_MAX" +fi + +# Keep the current _sha3 VC6/C89 frontier explicit: SHA3_dealloc() +# must hoist tp before the preceding executable cleanup statements. +if python3 - "$REPO_ROOT/cpython/Modules/_sha3/sha3module.c" <<'PY' +import sys +from pathlib import Path +source = Path(sys.argv[1]).read_text() +start = source.index("SHA3_dealloc(SHA3object *self)") +end = source.index("\n}\n", start) + 2 +function = source[start:end] +if " PyTypeObject *tp;" not in function: + raise SystemExit(1) +if " PyTypeObject *tp = Py_TYPE(self);" in function: + raise SystemExit(1) +if function.count(" tp = Py_TYPE(self);") != 1: + raise SystemExit(1) +sequence = ( + "SHA3_dealloc(SHA3object *self) { PyTypeObject *tp; " + "if (self->lock) { PyThread_free_lock(self->lock); } " + "tp = Py_TYPE(self); PyObject_Free(self); Py_DECREF(tp); }" +) +if sequence not in " ".join(function.split()): + raise SystemExit(1) +PY +then + pass "_sha3 SHA3_dealloc uses C89 declaration-order-safe tp local" +else + bad "_sha3 SHA3_dealloc uses C89 declaration-order-safe tp local" +fi + +# Keep the current _randommodule.c VC6/C89 frontier explicit: _random_exec() +# must hoist locals while preserving the allocation/error/refcount sequence. +if python3 - "$REPO_ROOT/cpython/Modules/_randommodule.c" <<'PY' +import re +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("_random_exec(PyObject *module)\n{") +end = source.index("\n}\n", start) + 2 +function = source[start:end] +function = re.sub(r"/\\*.*?\\*/", "", function, flags=re.S) +function = " ".join(function.split()) + +if not function.startswith( + "_random_exec(PyObject *module) { " + "_randomstate *state = get_random_state(module); " + "PyObject *longval; PyObject *longtype; " + "state->Random_Type = PyType_FromModuleAndSpec(" +): + raise SystemExit(1) +if "PyObject *longval =" in function or "PyObject *longtype =" in function: + raise SystemExit(1) +if function.count("longval = PyLong_FromLong(0);") != 1: + raise SystemExit(1) +if function.count("longtype = PyObject_Type(longval);") != 1: + raise SystemExit(1) +sequence = ( + "if (PyModule_AddType(module, (PyTypeObject *)state->Random_Type) < 0) { " + "return -1; } " + "longval = PyLong_FromLong(0); " + "if (longval == NULL) { return -1; } " + "longtype = PyObject_Type(longval); " + "Py_DECREF(longval); " + "if (longtype == NULL) { return -1; } " + 'state->Long___abs__ = PyObject_GetAttrString(longtype, "__abs__"); ' + "Py_DECREF(longtype); " + "if (state->Long___abs__ == NULL) { return -1; } " + "return 0; }" +) +if sequence not in function: + raise SystemExit(1) +PY +then + pass "_random_exec uses C89 locals and preserves initialization order" +else + bad "_random_exec uses C89 locals and preserves initialization order" +fi + +# Keep the current _sha3 frontier explicit: its type and module definitions must +# use positional initializers because VC6 has no C99 designated initializers. +if python3 - "$REPO_ROOT/cpython/Modules/_sha3/sha3module.c" <<'PY' +import sys +from pathlib import Path +source = Path(sys.argv[1]).read_text() +start = source.index("#define SHA3_TYPE_SPEC") +end = source.index("\n\nPyDoc_STRVAR(sha3_224__doc__", start) +macro = source[start:end] +expected_macro = '''#define SHA3_TYPE_SPEC(type_spec_obj, type_name, type_slots) \\ + static PyType_Spec type_spec_obj = { \\ + "_sha3." type_name, \\ + sizeof(SHA3object), \\ + 0, \\ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE, \\ + type_slots \\ + }''' +if macro != expected_macro: + raise SystemExit(1) +start = source.index("static struct PyModuleDef _sha3module = {") +end = source.index("\n};", start) + 3 +module = source[start:end] +expected_module = '''static struct PyModuleDef _sha3module = { + PyModuleDef_HEAD_INIT, + "_sha3", + NULL, + sizeof(SHA3State), + NULL, + _sha3_slots, + _sha3_traverse, + _sha3_clear, + _sha3_free, +};''' +if module != expected_module: + raise SystemExit(1) +PY +then + pass "_sha3 uses VC6-safe positional type and module initializers" +else + bad "_sha3 uses VC6-safe positional type and module initializers" +fi + +# Keep the current _sre frontier explicit: SRE(match) must declare ptr before +# executable statements, including the entrance label. +if python3 - "$REPO_ROOT/cpython/Modules/_sre/sre_lib.h" <<'PY' +import sys +from pathlib import Path +source = Path(sys.argv[1]).read_text() +start = source.index("SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel)") +end = source.index("\n}\n\n/* need to reset capturing groups", start) + 2 +function = source[start:end] +if " const SRE_CHAR *ptr;" not in function: + raise SystemExit(1) +if " const SRE_CHAR *ptr = (SRE_CHAR *)state->ptr;" in function: + raise SystemExit(1) +if function.count(" ptr = (SRE_CHAR *)state->ptr;") != 1: + raise SystemExit(1) +PY +then + pass "_sre SRE(match) uses C89 declaration-order-safe ptr local" +else + bad "_sre SRE(match) uses C89 declaration-order-safe ptr local" +fi + +# The active _sre VC6/C89 frontier must declare repeat_of_tail before the +# executable DO_JUMP statement that assigns it. +if python3 - "$REPO_ROOT/cpython/Modules/_sre/sre_lib.h" <<'PY' +import sys +from pathlib import Path +source = Path(sys.argv[1]).read_text() +start = source.index("SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel)") +end = source.index("\n}\n\n/* need to reset capturing groups", start) + 2 +function = source[start:end] +if " SRE_REPEAT *repeat_of_tail;" not in function: + raise SystemExit(1) +if " SRE_REPEAT *repeat_of_tail = state->repeat;" in function: + raise SystemExit(1) +if function.count(" repeat_of_tail = state->repeat;") != 1: + raise SystemExit(1) +PY +then + pass "_sre MIN_UNTIL uses C89 declaration-order-safe repeat local" +else + bad "_sre MIN_UNTIL uses C89 declaration-order-safe repeat local" +fi + +# The active _sre VC6/C89 frontier must declare rc before the preceding +# VTRACE executable statement in the GROUPREF_EXISTS validation case. +if python3 - "$REPO_ROOT/cpython/Modules/_sre/sre.c" <<'PY' +import sys +from pathlib import Path +source = Path(sys.argv[1]).read_text() +start = source.index("_validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups)") +end = source.index("\n}\n\nstatic int\n_validate_outer", start) + 2 +function = source[start:end] +if " int rc;" not in function: + raise SystemExit(1) +if " int rc = _validate_inner(code+1, code+skip-1, groups);" in function: + raise SystemExit(1) +if function.count(" rc = _validate_inner(code+1, code+skip-1, groups);") != 1: + raise SystemExit(1) +PY +then + pass "_sre GROUPREF_EXISTS uses C89 declaration-order-safe rc local" +else + bad "_sre GROUPREF_EXISTS uses C89 declaration-order-safe rc local" +fi + +# The active _sre designated-initializer frontier must use C89-compatible +# positional PyType_Spec initializers in declared field order. +if python3 - "$REPO_ROOT/cpython/Modules/_sre/sre.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +expected = { + "pattern_spec": '''static PyType_Spec pattern_spec = { + "re.Pattern", + sizeof(PatternObject), + sizeof(SRE_CODE), + (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | + Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_HAVE_GC), + pattern_slots, +};''', + "match_spec": '''static PyType_Spec match_spec = { + "re.Match", + sizeof(MatchObject), + sizeof(Py_ssize_t), + (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | + Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_HAVE_GC), + match_slots, +};''', + "scanner_spec": '''static PyType_Spec scanner_spec = { + "_" SRE_MODULE ".SRE_Scanner", + sizeof(ScannerObject), + 0, + (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | + Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_HAVE_GC), + scanner_slots, +};''', +} +for name, block in expected.items(): + if block not in source: + raise SystemExit(name) +if ".name = \"re.Pattern\"" in source or ".name = \"re.Match\"" in source: + raise SystemExit("designated initializer remains") +PY +then + pass "_sre PyType_Spec definitions use C89-compatible positional initializers" +else + bad "_sre PyType_Spec definitions use C89-compatible positional initializers" +fi + +# The active _sre module definition must use C89-compatible positional +# initializers in the declared PyModuleDef field order. +if python3 - "$REPO_ROOT/cpython/Modules/_sre/sre.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +expected = '''static struct PyModuleDef sremodule = { + PyModuleDef_HEAD_INIT, + "_" SRE_MODULE, + NULL, + sizeof(_sremodulestate), + _functions, + sre_slots, + sre_traverse, + sre_clear, + sre_free, +};''' +if expected not in source: + raise SystemExit("sremodule positional initializer mismatch") +body = source[source.index("static struct PyModuleDef sremodule = {"):] +body = body[:body.index("\n};")] +if ".m_" in body: + raise SystemExit("sremodule designated initializer remains") +PY +then + pass "_sre sremodule uses C89-compatible positional initializers" +else + bad "_sre sremodule uses C89-compatible positional initializers" +fi + +# The active _sre VC6/C89 frontier must declare ADD_ULONG_CONSTANT's result +# before the executable NULL check shared by both macro call sites. +if python3 - "$REPO_ROOT/cpython/Modules/_sre/sre.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("#define ADD_ULONG_CONSTANT(") +end = source.index("\n\n", start) +actual = [ + line.rstrip().removesuffix("\\").strip() + for line in source[start:end].splitlines() +] +expected = [ + "#define ADD_ULONG_CONSTANT(module, name, value)", + "do {", + "PyObject *o = PyLong_FromUnsignedLong(value);", + "int res;", + "if (!o)", + "goto error;", + "res = PyModule_AddObjectRef(module, name, o);", + "Py_DECREF(o);", + "if (res < 0) {", + "goto error;", + "}", + "} while (0)", +] +if actual != expected: + raise SystemExit("ADD_ULONG_CONSTANT declaration/order mismatch") +PY +then + pass "_sre ADD_ULONG_CONSTANT uses C89 declaration-order-safe res local" +else + bad "_sre ADD_ULONG_CONSTANT uses C89 declaration-order-safe res local" +fi + +# Keep the active arraymodule.c VC6/C89 frontier explicit: u_setitem() +# must declare len and w before executable statements. +if python3 - "$REPO_ROOT/cpython/Modules/arraymodule.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("u_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)") +end = source.index("\n}\n\n\nstatic PyObject *\nh_getitem", start) + 2 +function = source[start:end] +if " Py_ssize_t len;" not in function: + raise SystemExit(1) +if " wchar_t w;" not in function: + raise SystemExit(1) +if " Py_ssize_t len = PyUnicode_AsWideChar(u, NULL, 0);" in function: + raise SystemExit(1) +if " wchar_t w;\n len =" in function: + raise SystemExit(1) +if function.count(" len = PyUnicode_AsWideChar(u, NULL, 0);") != 1: + raise SystemExit(1) +if " len = PyUnicode_AsWideChar(u, &w, 1);" not in function: + raise SystemExit(1) +PY +then + pass "arraymodule u_setitem uses C89 declaration-order-safe len and w locals" +else + bad "arraymodule u_setitem uses C89 declaration-order-safe len and w locals" +fi + +# Keep the next arraymodule.c VC6/C89 frontier explicit: array_repeat() +# must declare locals before executable statements and preserve assignment order. +if python3 - "$REPO_ROOT/cpython/Modules/arraymodule.c" <<'PY' +import sys +from pathlib import Path +source = Path(sys.argv[1]).read_text() +start = source.index("array_repeat(arrayobject *a, Py_ssize_t n)\n{") +end = source.index("\n}\n\nstatic int\narray_del_slice", start) + 2 +function = source[start:end] +for declaration in (" Py_ssize_t array_length;", " Py_ssize_t size;", " arrayobject *np;", " Py_ssize_t oldbytes;", " Py_ssize_t newbytes;"): + if declaration not in function: + raise SystemExit("array_repeat declaration missing: " + declaration) +for declaration in (" const Py_ssize_t array_length =", " Py_ssize_t size =", " arrayobject* np =", " const Py_ssize_t oldbytes =", " const Py_ssize_t newbytes ="): + if declaration in function: + raise SystemExit("array_repeat retains mixed declaration: " + declaration) +expected = ( + " array_length = Py_SIZE(a);\n" + " if ((array_length != 0) && (n > PY_SSIZE_T_MAX / array_length))" +) +if expected not in function: + raise SystemExit("array_repeat array_length assignment sequence changed") +if " size = array_length * n;" not in function: + raise SystemExit("array_repeat size assignment missing") +if " np = (arrayobject *) newarrayobject" not in function: + raise SystemExit("array_repeat np assignment missing") +if " oldbytes = array_length * a->ob_descr->itemsize;" not in function: + raise SystemExit("array_repeat oldbytes assignment missing") +if " newbytes = oldbytes * n;" not in function: + raise SystemExit("array_repeat newbytes assignment missing") +PY +then + pass "arraymodule array_repeat uses C89 declaration-order-safe locals" +else + bad "arraymodule array_repeat uses C89 declaration-order-safe locals" +fi + +# The current arraymodule.c VC6/C89 frontier must declare array_inplace_repeat +# locals before the executable conditional block. +if python3 - "$REPO_ROOT/cpython/Modules/arraymodule.c" <<'PY' +import sys +from pathlib import Path +source = Path(sys.argv[1]).read_text() +start = source.index("array_inplace_repeat(arrayobject *self, Py_ssize_t n)\n{") +end = source.index("\n}\n\n\nstatic PyObject *\nins(", start) + 2 +function = source[start:end] +opening = function[:function.index(" if (array_size > 0")] +if " Py_ssize_t size;\n" not in opening: + raise SystemExit("array_inplace_repeat size declaration missing from opening group") +if " Py_ssize_t size = array_size * self->ob_descr->itemsize;" in function: + raise SystemExit("array_inplace_repeat retains mixed declaration") +if function.count(" size = array_size * self->ob_descr->itemsize;") != 1: + raise SystemExit("array_inplace_repeat size assignment missing") +PY +then + pass "arraymodule array_inplace_repeat uses C89 declaration-order-safe size local" +else + bad "arraymodule array_inplace_repeat uses C89 declaration-order-safe size local" +fi + +# The next arraymodule.c VC6/C89 frontier must declare the index loop counter +# before the preceding executable start/stop normalization statements. +if python3 - "$REPO_ROOT/cpython/Modules/arraymodule.c" <<'PY' +import sys +from pathlib import Path +source = Path(sys.argv[1]).read_text() +start = source.index("array_array_index_impl(arrayobject *self, PyObject *v, Py_ssize_t start,") +end = source.index("\n}\n\nstatic int\narray_contains", start) + 2 +function = source[start:end] +opening = function[:function.index(" if (start < 0)")] +if " Py_ssize_t i;\n" not in opening: + raise SystemExit("array_array_index_impl loop counter declaration missing from opening group") +if "for (Py_ssize_t i = start;" in function: + raise SystemExit("array_array_index_impl retains C99 loop declaration") +if function.count(" for (i = start; i < stop && i < Py_SIZE(self); i++) {") != 1: + raise SystemExit("array_array_index_impl loop assignment sequence changed") +PY +then + pass "arraymodule array_array_index_impl uses C89 declaration-order-safe loop counter" +else + bad "arraymodule array_array_index_impl uses C89 declaration-order-safe loop counter" +fi + +# The active arraymodule.c VC6/C89 frontier must hoist array_state declarations +# while preserving the guarded lookup points in fromfile() and tofile(). +if python3 - "$REPO_ROOT/cpython/Modules/arraymodule.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +checks = { + "fromfile": ( + "array_array_fromfile_impl(arrayobject *self, PyTypeObject *cls, PyObject *f,", + "\n}\n\n/*[clinic input]\narray.array.tofile", + " int not_enough_bytes;\n", + " nbytes = n * itemsize;\n", + ), + "tofile": ( + "array_array_tofile_impl(arrayobject *self, PyTypeObject *cls, PyObject *f)", + "\n}\n\n/*[clinic input]\narray.array.fromlist", + " Py_ssize_t i;\n", + " for (i = 0; i < nblocks; i++) {\n", + ), +} +for name, (signature, end_marker, declaration_anchor, after_lookup) in checks.items(): + start = source.index(signature) + end = source.index(end_marker, start) + 2 + function = source[start:end] + opening = function[:function.index(" if ")] + if " array_state *state;\n" not in opening: + raise SystemExit(name + ": array_state declaration missing from opening group") + if " array_state *state = get_array_state_by_class(cls);" in function: + raise SystemExit(name + ": array_state declaration retains initializer") + if function.count(" state = get_array_state_by_class(cls);\n") != 1: + raise SystemExit(name + ": state assignment missing or duplicated") + if " state = get_array_state_by_class(cls);\n assert(state != NULL);\n" not in function: + raise SystemExit(name + ": state lookup/assert sequence changed") + if function.index(declaration_anchor) >= function.index(" if "): + raise SystemExit(name + ": declaration anchor moved after executable code") + lookup = function.index(" state = get_array_state_by_class(cls);") + if function.index(after_lookup, lookup) <= lookup: + raise SystemExit(name + ": post-lookup sequence changed") +PY +then + pass "arraymodule fromfile/tofile use C89 declaration-order-safe state locals" +else + bad "arraymodule fromfile/tofile use C89 declaration-order-safe state locals" +fi + +# The active arraymodule.c VC6/C89 frontier must hoist fromunicode() locals +# without moving either initializer past its original guard/decrement point. +if python3 - "$REPO_ROOT/cpython/Modules/arraymodule.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +signature = "array_array_fromunicode_impl(arrayobject *self, PyObject *ustr)" +start = source.index(signature) +end = source.index("\n}\n\n/*[clinic input]\narray.array.tounicode", start) + 2 +function = source[start:end] +opening = function[:function.index(" if ")] +if " Py_ssize_t ustr_length;\n" not in opening: + raise SystemExit("fromunicode: ustr_length declaration missing from opening group") +if " Py_ssize_t old_size;\n" not in function[:function.index(" ustr_length--")]: + raise SystemExit("fromunicode: old_size declaration missing before decrement") +if " Py_ssize_t ustr_length = PyUnicode_AsWideChar(ustr, NULL, 0);" in function: + raise SystemExit("fromunicode: ustr_length declaration retains initializer") +if " Py_ssize_t old_size = Py_SIZE(self);" in function: + raise SystemExit("fromunicode: old_size declaration retains initializer") +if " ustr_length = PyUnicode_AsWideChar(ustr, NULL, 0);\n assert(ustr_length > 0);" not in function: + raise SystemExit("fromunicode: Unicode conversion assignment/assert sequence changed") +if " old_size = Py_SIZE(self);\n if (array_resize(self, old_size + ustr_length) == -1)" not in function: + raise SystemExit("fromunicode: old_size assignment/resize sequence changed") +PY +then + pass "arraymodule fromunicode uses C89 declaration-order-safe locals" +else + bad "arraymodule fromunicode uses C89 declaration-order-safe locals" +fi + +# Keep the current arraymodule.c VC6/C89 frontier explicit: array_richcompare() +# must declare cmp before the executable fast-path statements. +if python3 - "$REPO_ROOT/cpython/Modules/arraymodule.c" <<'PY' +import sys +from pathlib import Path +source = Path(sys.argv[1]).read_text() +start = source.index("array_richcompare(PyObject *v, PyObject *w, int op)") +end = source.index("\n}\n\nstatic PyMethodDef", start) + 2 +function = source[start:end] +opening = function[:function.index(" if (!array_Check")] +if " int cmp;\n" not in opening: + raise SystemExit("array_richcompare cmp declaration missing from opening group") +fast_path = function[function.index(" if (va->ob_descr"):function.index("\n }\n\n\n /* Search", function.index(" if (va->ob_descr"))] +if " int cmp;\n" in fast_path: + raise SystemExit("array_richcompare cmp declaration remains after executable statements") +size_path = function[function.index(" compare_sizes: ;"):function.index("\n }\n\n /* We have an item", function.index(" compare_sizes: ;"))] +if " int cmp;\n" in size_path: + raise SystemExit("array_richcompare compare_sizes retains duplicate cmp declaration") +if size_path.count(" case Py_LT: cmp = vs < ws; break;") != 1: + raise SystemExit("array_richcompare compare_sizes cmp assignment sequence changed") +if fast_path.count(" case Py_LT: cmp = result < 0; break;") != 1: + raise SystemExit("array_richcompare cmp assignment sequence changed") +PY +then + pass "arraymodule array_richcompare uses C89 declaration-order-safe cmp local" +else + bad "arraymodule array_richcompare uses C89 declaration-order-safe cmp local" +fi + +# The next arraymodule.c VC6/C89 frontier must reuse the opening res local; +# VC6 rejects the fast-path declaration after executable statements. +if python3 - "$REPO_ROOT/cpython/Modules/arraymodule.c" <<'PY' +import sys +from pathlib import Path +source = Path(sys.argv[1]).read_text() +start = source.index("array_richcompare(PyObject *v, PyObject *w, int op)\n{") +end = source.index("\n}\n\nstatic Py_ssize_t\narray_length(", start) + 2 +function = source[start:end] +opening = function[:function.index(" if (!array_Check")] +if opening.count(" PyObject *res;\n") != 1: + raise SystemExit("array_richcompare opening res declaration missing") +start = function.index(" if (va->ob_descr") +fast_path = function[start:function.index("\n }\n\n\n /* Search", start)] +if "PyObject *res" in fast_path: + raise SystemExit("array_richcompare fast path retains res declaration") +if fast_path.count( + " }\n" + " res = cmp ? Py_True : Py_False;\n" + " Py_INCREF(res);\n" + " return res;" +) != 1: + raise SystemExit("array_richcompare fast-path res assignment sequence changed") +PY +then + pass "arraymodule array_richcompare reuses C89-safe res local" +else + bad "arraymodule array_richcompare reuses C89-safe res local" +fi + +# The next arraymodule.c VC6/C89 frontier must hoist the compare-size locals +# before the label and executable statements in the shared-size path. +if python3 - "$REPO_ROOT/cpython/Modules/arraymodule.c" <<'PY' +import re +import sys +from pathlib import Path +source = Path(sys.argv[1]).read_text() +start = source.index("array_richcompare(PyObject *v, PyObject *w, int op)\n{") +end = source.index("\n}\n\nstatic Py_ssize_t\narray_length(", start) + 2 +function = source[start:end] +opening = function[:function.index(" if (!array_Check")] +if re.search(r" Py_ssize_t [^;]*\bvs\b[^;]*\bws\b[^;]*;\n", opening) is None: + raise SystemExit("array_richcompare size locals missing from opening group") +if " Py_ssize_t vs = Py_SIZE(va);" in function: + raise SystemExit("array_richcompare retains post-label vs declaration") +if " Py_ssize_t ws = Py_SIZE(wa);" in function: + raise SystemExit("array_richcompare retains post-label ws declaration") +if function.count(" vs = Py_SIZE(va);\n ws = Py_SIZE(wa);") != 1: + raise SystemExit("array_richcompare size assignments changed") +PY +then + pass "arraymodule array_richcompare uses C89 declaration-order-safe size locals" +else + bad "arraymodule array_richcompare uses C89 declaration-order-safe size locals" +fi + +# Keep the current arraymodule.c VC6/C89 frontier explicit: getarrayitem() +# must declare ap before the debug-only executable assertion. +if python3 - "$REPO_ROOT/cpython/Modules/arraymodule.c" <<'PY' +import sys +from pathlib import Path +source = Path(sys.argv[1]).read_text() +start = source.index("getarrayitem(PyObject *op, Py_ssize_t i)") +end = source.index("\n}\n\nstatic int\nins1", start) + 2 +function = source[start:end] +if "{\n arrayobject *ap;\n#ifndef NDEBUG" not in function: + raise SystemExit("getarrayitem ap declaration is not before debug block") +if function.count(" arrayobject *ap;") != 1: + raise SystemExit("getarrayitem ap declaration is duplicated") +if " ap = (arrayobject *)op;" not in function: + raise SystemExit("getarrayitem ap assignment missing") +if " arrayobject *ap = (arrayobject *)op;" in function: + raise SystemExit("getarrayitem retains declaration initializer") +PY +then + pass "arraymodule getarrayitem uses C89 declaration-order-safe ap local" +else + bad "arraymodule getarrayitem uses C89 declaration-order-safe ap local" +fi + +# Keep the active _struct.c VC6 frontier explicit: MSVC6 has no C99 _Bool, +# so the module must provide a one-byte compatibility typedef locally. +if python3 - "$REPO_ROOT/cpython/Modules/_struct.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +expected = '''#if defined(_MSC_VER) && _MSC_VER < 1300 +/* MSVC6 has no C99 _Bool; preserve the one-byte layout used by struct. */ +typedef unsigned char _Bool; +#endif''' +if expected not in source: + raise SystemExit("_struct VC6 _Bool compatibility typedef missing") +PY +then + pass "_struct provides a guarded one-byte VC6 _Bool compatibility typedef" +else + bad "_struct provides a guarded one-byte VC6 _Bool compatibility typedef" +fi + +# The active _struct.c VC6 frontier must spell its 64-bit integer types through +# CPython's PY_LONG_LONG abstraction because VC6 rejects the long long keyword. +if python3 - "$REPO_ROOT/cpython/Modules/_struct.c" <<'PY' +import re +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +code = re.sub(r"/\*.*?\*/", "", source, flags=re.S) +doc_start = code.index("PyDoc_STRVAR(module_doc,") +doc_end = code.index('\\n");', doc_start) + 3 +code = code[:doc_start] + code[doc_end:] +if re.search(r"\b(?:unsigned\s+)?long\s+long\b", code): + raise SystemExit("_struct long long keyword remains in code") +if code.count("PY_LONG_LONG") < 20: + raise SystemExit("_struct PY_LONG_LONG replacements are incomplete") +if code.count("unsigned PY_LONG_LONG") < 7: + raise SystemExit("_struct unsigned PY_LONG_LONG replacements are incomplete") +PY +then + pass "_struct routes signed and unsigned 64-bit types through PY_LONG_LONG" +else + bad "_struct routes signed and unsigned 64-bit types through PY_LONG_LONG" +fi + +# Keep the active _stat.c VC6/C89 frontier explicit: stat_exec() must place +# its constant table and loop counter before the initial executable macro call. +if python3 - "$REPO_ROOT/cpython/Modules/_stat.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("stat_exec(PyObject *module)\n{") +end = source.index("\n}\n\n\nstatic PyModuleDef_Slot stat_slots", start) + 2 +function = source[start:end] +first_statement = function.index(" ADD_INT_MACRO(module, S_IFDIR);") +if function.index(" const char* st_constants[] = {") >= first_statement: + raise SystemExit(1) +if function.index(" };", function.index("st_constants[]")) >= first_statement: + raise SystemExit(1) +if function.index(" int i;") >= first_statement: + raise SystemExit(1) +if "for (int i" in function: + raise SystemExit(1) +if "for (i = 0; i < (int)Py_ARRAY_LENGTH(st_constants); i++)" not in function: + raise SystemExit(1) +PY +then + pass "_stat stat_exec uses C89 declaration-order-safe constants and loop counter" +else + bad "_stat stat_exec uses C89 declaration-order-safe constants and loop counter" +fi + +# The active _stat.c frontier must provide guarded Win9x/VC6 fallbacks for +# constants absent from the VC6 Windows headers, without overriding headers +# that already define them. +if python3 - "$REPO_ROOT/cpython/Modules/_stat.c" <<'PY' +import re +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("#ifdef MS_WINDOWS") +end = source.index("#endif /* MS_WINDOWS */", start) +block = source[start:end] +expected = { + "FILE_ATTRIBUTE_DEVICE": "0x0040", + "FILE_ATTRIBUTE_VIRTUAL": "0x10000", + "IO_REPARSE_TAG_SYMLINK": "0xA000000CL", +} +for name, value in expected.items(): + pattern = rf"#ifndef {name}\s+#\s*define {name}\s+{re.escape(value)}\s+#endif" + if re.search(pattern, block) is None: + raise SystemExit(name) +PY +then + pass "_stat provides guarded VC6/Win9x file-attribute fallbacks" +else + bad "_stat provides guarded VC6/Win9x file-attribute fallbacks" +fi + +# The active _stat.c frontier must use C89-compatible positional initializers +# for statmodule because VC6 has no C99 designated-initializer support. +if python3 - "$REPO_ROOT/cpython/Modules/_stat.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +expected = '''static struct PyModuleDef statmodule = { + PyModuleDef_HEAD_INIT, + "_stat", + module_doc, + 0, + stat_methods, + stat_slots, + NULL, + NULL, + NULL, +};''' +if expected not in source: + raise SystemExit("statmodule positional initializer mismatch") +body = source[source.index("static struct PyModuleDef statmodule = {"):] +body = body[:body.index("\n};")] +if ".m_" in body: + raise SystemExit("statmodule designated initializer remains") +PY +then + pass "_stat statmodule uses C89-compatible positional initializers" +else + bad "_stat statmodule uses C89-compatible positional initializers" +fi + +# The active _struct.c module definition must use C89-compatible positional +# initializers in the declared PyModuleDef field order. +if python3 - "$REPO_ROOT/cpython/Modules/_struct.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +expected = '''static struct PyModuleDef _structmodule = { + PyModuleDef_HEAD_INIT, + "_struct", + module_doc, + sizeof(_structmodulestate), + module_functions, + _structmodule_slots, + _structmodule_traverse, + _structmodule_clear, + _structmodule_free, +};''' +if expected not in source: + raise SystemExit("_structmodule positional initializer mismatch") +body = source[source.index("static struct PyModuleDef _structmodule = {"):] +body = body[:body.index("\n};")] +if ".m_" in body: + raise SystemExit("_structmodule designated initializer remains") +PY +then + pass "_struct _structmodule uses C89-compatible positional initializers" +else + bad "_struct _structmodule uses C89-compatible positional initializers" +fi + +# The active _struct.c frontier must hoist declarations before executable +# statements for VC6/C89 in s_new(), s_dealloc(), and s_pack(). +if python3 - "$REPO_ROOT/cpython/Modules/_struct.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +checks = { + "s_new": ("s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)", "\n}\n\n/*[clinic input]", [" allocfunc alloc_func;"], [" alloc_func = PyType_GetSlot(type, Py_tp_alloc);"]), + "s_dealloc": ("s_dealloc(PyStructObject *s)", "\n}\n\nstatic PyObject *\ns_unpack_internal", [" PyTypeObject *tp;", " freefunc free_func;"], [" tp = Py_TYPE(s);", " free_func = PyType_GetSlot(Py_TYPE(s), Py_tp_free);"]), + "s_pack": ("s_pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs)", "\n}\n\nPyDoc_STRVAR(s_pack_into__doc__", [" _PyBytesWriter writer;"], [" _PyBytesWriter_Init(&writer);"]), +} +for name, (signature, end_marker, declarations, assignments) in checks.items(): + start = source.index(signature) + end = source.index(end_marker, start) + 2 + function = source[start:end] + for declaration in declarations: + if declaration not in function or declaration[:-1] + " =" in function: + raise SystemExit(f"{name}: declaration not hoisted") + for assignment in assignments: + if assignment not in function: + raise SystemExit(f"{name}: assignment missing") +PY +then + pass "_struct uses C89 declaration-order-safe locals at the active frontier" +else + bad "_struct uses C89 declaration-order-safe locals at the active frontier" +fi + +# Keep the current arraymodule.c VC6 frontier explicit: the q/QQ handlers +# must route 64-bit C types through CPython's VC6-compatible spelling. +if python3 - "$REPO_ROOT/cpython/Modules/arraymodule.c" <<'PY' +import re +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("q_getitem(arrayobject *ap, Py_ssize_t i)") +end = source.index("\n}\n\nstatic PyObject *\nf_getitem", start) + 2 +family = source[start:end] +if re.search(r"(?ob_item") != 2: + raise SystemExit(1) +if family.count("(unsigned PY_LONG_LONG *)ap->ob_item") != 2: + raise SystemExit(1) +PY +then + pass "arraymodule q/QQ handlers use VC6-compatible 64-bit type spellings" +else + bad "arraymodule q/QQ handlers use VC6-compatible 64-bit type spellings" +fi + +# The active arraymodule.c frontier must declare the compare-loop counter in +# the function declaration group because VC6 has no C99 for-loop declarations. +if python3 - "$REPO_ROOT/cpython/Modules/arraymodule.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("#define DEFINE_COMPAREITEMS") +end = source.index("\n\nDEFINE_COMPAREITEMS(b", start) +macro = source[start:end] +if " Py_ssize_t i; \\\n" not in macro: + raise SystemExit("compare macro loop counter declaration missing") +if " for (i = 0; i < length; ++i) \\\n" not in macro: + raise SystemExit("compare macro still uses C99 for initializer") +if "for (Py_ssize_t i =" in macro: + raise SystemExit("compare macro retains C99 for initializer") +PY +then + pass "arraymodule compare macro uses C89 declaration-order-safe loop counter" +else + bad "arraymodule compare macro uses C89 declaration-order-safe loop counter" +fi + +# The active arraymodule.c frontier must route the q/QQ compare macro type +# arguments through CPython's VC6-compatible 64-bit spelling. +if python3 - "$REPO_ROOT/cpython/Modules/arraymodule.c" <<'PY' +import re +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("#define DEFINE_COMPAREITEMS") +end = source.index("\n\nDEFINE_COMPAREITEMS(b", start) +macro = source[start:end] +if "DEFINE_COMPAREITEMS(q, PY_LONG_LONG)" not in source: + raise SystemExit("signed q compare macro argument is not VC6-compatible") +if "DEFINE_COMPAREITEMS(QQ, unsigned PY_LONG_LONG)" not in source: + raise SystemExit("unsigned QQ compare macro argument is not VC6-compatible") +if re.search(r"DEFINE_COMPAREITEMS\(q,\s*long\s+long\)", source): + raise SystemExit("signed q compare macro retains long long") +if re.search(r"DEFINE_COMPAREITEMS\(QQ,\s*unsigned\s+long\s+long\)", source): + raise SystemExit("unsigned QQ compare macro retains long long") +PY +then + pass "arraymodule compare macro uses VC6-compatible 64-bit type arguments" +else + bad "arraymodule compare macro uses VC6-compatible 64-bit type arguments" +fi + +# Keep the active arraymodule.c frontier explicit: get_native_typecode() +# must use CPython's VC6-compatible 64-bit type spelling, not long long. +if python3 - "$REPO_ROOT/cpython/Modules/arraymodule.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("typecode_to_mformat_code(char typecode)") +end = source.index("\n}\n\n/* Forward declaration. */", start) + 2 +function = source[start:end] +if "intsize = sizeof(PY_LONG_LONG);" not in function: + raise SystemExit("get_native_typecode q/QQ width is not VC6-compatible") +if function.count("intsize = sizeof(PY_LONG_LONG);") != 2: + raise SystemExit("get_native_typecode q/QQ width count changed") +if "intsize = sizeof(long long);" in function: + raise SystemExit("get_native_typecode retains sizeof(long long)") +PY +then + pass "arraymodule get_native_typecode uses VC6-compatible 64-bit widths" +else + bad "arraymodule get_native_typecode uses VC6-compatible 64-bit widths" +fi + +# Keep the active arraymodule.c frontier explicit: the q/QQ descriptor widths +# must use CPython's VC6-compatible 64-bit type spelling, not long long. +if python3 - "$REPO_ROOT/cpython/Modules/arraymodule.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("static const struct arraydescr descriptors[]") +end = source.index("\n};", start) + 3 +descriptors = source[start:end] +if "{'q', sizeof(PY_LONG_LONG)," not in descriptors: + raise SystemExit("q descriptor does not use VC6-compatible 64-bit width") +if "{'Q', sizeof(PY_LONG_LONG)," not in descriptors: + raise SystemExit("Q descriptor does not use VC6-compatible 64-bit width") +if "{'q', sizeof(long long)," in descriptors: + raise SystemExit("q descriptor retains sizeof(long long)") +if "{'Q', sizeof(long long)," in descriptors: + raise SystemExit("Q descriptor retains sizeof(long long)") +PY +then + pass "arraymodule q/QQ descriptors use VC6-compatible 64-bit widths" +else + bad "arraymodule q/QQ descriptors use VC6-compatible 64-bit widths" +fi + +# VC6 C2026: each arraytype_doc literal must fit, while concatenation must +# preserve every byte of the original documentation (including newlines). +if python3 - "$REPO_ROOT/cpython/Modules/arraymodule.c" <<'PY' +import ast +import hashlib +import re +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +match = re.search(r'PyDoc_STRVAR\(arraytype_doc,\s*(.*?)\);', source, re.S) +assert match, "arraytype_doc must retain PyDoc_STRVAR behavior" +body = match.group(1).replace("\\\n", "") +literals = re.findall(r'"(?:[^"\\]|\\.)*"', body) +assert literals and not re.sub(r'"(?:[^"\\]|\\.)*"', "", body).strip(), \ + "arraytype_doc must consist of adjacent string literals" +chunks = [ast.literal_eval(literal).encode("ascii") for literal in literals] +assert all(len(chunk) <= 2048 for chunk in chunks), \ + "arraytype_doc exceeds VC6's 2048-byte individual string literal limit" +assert hashlib.sha256(b"".join(chunks)).hexdigest() == \ + "36d98a6261ec374e1e5ed2da654bb1c47286a2658b86c28800af1543c40f6822", \ + "arraytype_doc documentation bytes changed" +assert "{Py_tp_doc, (void *)arraytype_doc}" in source, \ + "array type must retain its documentation slot" +PY +then + pass "arraymodule arraytype_doc uses VC6-sized literals with unchanged text" +else + bad "arraymodule arraytype_doc uses VC6-sized literals with unchanged text" +fi + +# The active arraymodule.c VC6/C89 frontier must hoist arrayiter_next()'s +# debug-only state declaration before executable statements. +if python3 - "$REPO_ROOT/cpython/Modules/arraymodule.c" <<'PY' +import sys +from pathlib import Path +source = Path(sys.argv[1]).read_text() +start = source.index("arrayiter_next(arrayiterobject *it)\n{") +end = source.index("\n}\n\nstatic void\narrayiter_dealloc", start) + 2 +function = source[start:end] +opening = function[:function.index(" assert(it != NULL);")] +if " array_state *state;\n" not in opening: + raise SystemExit("arrayiter_next state declaration missing from opening group") +if " array_state *state = find_array_state_by_type(Py_TYPE(it));" in function: + raise SystemExit("arrayiter_next retains mixed declaration") +if function.count(" state = find_array_state_by_type(Py_TYPE(it));") != 1: + raise SystemExit("arrayiter_next state assignment missing") +if "#ifndef NDEBUG\n state = find_array_state_by_type(Py_TYPE(it));\n assert(PyObject_TypeCheck(it, state->ArrayIterType));" not in function: + raise SystemExit("arrayiter_next debug type-check sequence changed") +PY +then + pass "arraymodule arrayiter_next uses C89 declaration-order-safe state local" +else + bad "arraymodule arrayiter_next uses C89 declaration-order-safe state local" +fi + +# The active arraymodule.c VC6/C89 frontier must hoist array iterator reduce +# locals before the executable state lookup and assertion. +if python3 - "$REPO_ROOT/cpython/Modules/arraymodule.c" <<'PY' +import sys +from pathlib import Path +source = Path(sys.argv[1]).read_text() +start = source.index("array_arrayiterator___reduce___impl(arrayiterobject *self, PyTypeObject *cls)") +end = source.index("\n}\n\n/*[clinic input]\narray.arrayiterator.__setstate__", start) + 2 +function = source[start:end] +opening = function[:function.index(" assert(state != NULL);")] +if " array_state *state;\n" not in opening: + raise SystemExit("array iterator reduce state declaration missing from opening group") +if " PyObject *func;\n" not in opening: + raise SystemExit("array iterator reduce func declaration missing from opening group") +if " array_state *state = get_array_state_by_class(cls);" in function: + raise SystemExit("array iterator reduce retains mixed state declaration") +if " PyObject *func = _PyEval_GetBuiltin(state->str_iter);" in function: + raise SystemExit("array iterator reduce retains mixed func declaration") +if " state = get_array_state_by_class(cls);\n assert(state != NULL);\n func = _PyEval_GetBuiltin(state->str_iter);\n" not in function: + raise SystemExit("array iterator reduce lookup sequence changed") +PY +then + pass "arraymodule array iterator reduce uses C89 declaration-order-safe locals" +else + bad "arraymodule array iterator reduce uses C89 declaration-order-safe locals" +fi + +# The active arraymodule.c VC6/C89 frontier must hoist array_modexec()'s +# locals before the ADD_INTERNED executable statements. +if python3 - "$REPO_ROOT/cpython/Modules/arraymodule.c" <<'PY' +import sys +from pathlib import Path +source = Path(sys.argv[1]).read_text() +start = source.index("array_modexec(PyObject *m)\n{") +end = source.index("\n}\n\nstatic PyModuleDef_Slot arrayslots", start) + 2 +function = source[start:end] +opening = function[:function.index(" /* Add interned strings */")] +for declaration in (" PyObject *abc_mod;\n", " PyObject *mutablesequence;\n", " PyObject *res;\n"): + if declaration not in opening: + raise SystemExit("array_modexec local missing from opening declaration group: " + declaration.strip()) +for mixed in (" PyObject *abc_mod = PyImport_ImportModule", " PyObject *mutablesequence = PyObject_GetAttrString", " PyObject *res = PyObject_CallMethod"): + if mixed in function: + raise SystemExit("array_modexec retains mixed declaration: " + mixed) +if " abc_mod = PyImport_ImportModule(\"collections.abc\");\n" not in function: + raise SystemExit("array_modexec import assignment missing") +if " mutablesequence = PyObject_GetAttrString(abc_mod, \"MutableSequence\");\n" not in function: + raise SystemExit("array_modexec attribute assignment missing") +if " res = PyObject_CallMethod(mutablesequence, \"register\", \"O\",\n" not in function: + raise SystemExit("array_modexec register assignment missing") +PY +then + pass "arraymodule array_modexec uses C89 declaration-order-safe locals" +else + bad "arraymodule array_modexec uses C89 declaration-order-safe locals" +fi + +# The active arraymodule.c VC6 frontier must replace arrayiter_spec's C99 +# designated initializer with declared-order positional PyType_Spec fields. +if python3 - "$REPO_ROOT/cpython/Modules/arraymodule.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("static PyType_Spec arrayiter_spec = {") +end = source.index("\n};", start) +body = source[start:end] +assert ".name" not in body and ".basicsize" not in body and ".flags" not in body and ".slots" not in body, \ + "arrayiter_spec retains designated fields" +expected = '\n "array.arrayiterator",\n sizeof(arrayiterobject),\n 0,\n (Py_TPFLAGS_DEFAULT |' +assert expected in body, "arrayiter_spec positional field order mismatch" +assert body.rstrip().endswith("arrayiter_slots,"), "arrayiter_spec slots field missing" +PY +then + pass "arraymodule arrayiter_spec uses VC6-compatible positional PyType_Spec fields" +else + bad "arraymodule arrayiter_spec uses VC6-compatible positional PyType_Spec fields" +fi + +# The active arraymodule.c VC6 frontier must replace array_spec's C99 +# designated initializer with declared-order positional PyType_Spec fields. +if python3 - "$REPO_ROOT/cpython/Modules/arraymodule.c" <<'PY' +import re +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("static PyType_Spec array_spec = {") +end = source.index("\n};", start) +body = source[start:end] +assert ".name" not in body and ".basicsize" not in body and ".flags" not in body and ".slots" not in body, \ + "array_spec retains designated fields" +expected = '\n "array.array",\n sizeof(arrayobject),\n 0,\n (Py_TPFLAGS_DEFAULT |' +assert expected in body, "array_spec positional field order mismatch" +assert body.rstrip().endswith("array_slots,"), "array_spec slots field missing" +PY +then + pass "arraymodule array_spec uses VC6-compatible positional PyType_Spec fields" +else + bad "arraymodule array_spec uses VC6-compatible positional PyType_Spec fields" +fi + +# The active arraymodule.c VC6 frontier must replace arraymodule's C99 +# designated PyModuleDef initializer with declared-order positional fields. +if python3 - "$REPO_ROOT/cpython/Modules/arraymodule.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("static struct PyModuleDef arraymodule = {") +end = source.index("\n};", start) + 3 +module = source[start:end] +expected = '''static struct PyModuleDef arraymodule = { + PyModuleDef_HEAD_INIT, + "array", + module_doc, + sizeof(array_state), + a_methods, + arrayslots, + array_traverse, + array_clear, + array_free, +};''' +if module != expected: + raise SystemExit("arraymodule positional initializer mismatch") +PY +then + pass "arraymodule uses C89-compatible positional PyModuleDef initializer" +else + bad "arraymodule uses C89-compatible positional PyModuleDef initializer" +fi + +# The active atexitmodule.c VC6/C89 frontier must declare loop counters before +# the executable callback cleanup/call statements. +if python3 - "$REPO_ROOT/cpython/Modules/atexitmodule.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +checks = { + "cleanup": ( + "atexit_cleanup(struct atexit_state *state)", + "\n}\n\n\nPyStatus\n_PyAtExit_Init", + " int i;\n", + " for (i = 0; i < state->ncallbacks; i++) {\n", + ), + "callfuncs": ( + "atexit_callfuncs(struct atexit_state *state)", + "\n}\n\n\nvoid\n_PyAtExit_Call", + " int i;\n", + " for (i = state->ncallbacks - 1; i >= 0; i--) {\n", + ), +} +for name, (signature, end_marker, declaration, loop) in checks.items(): + start = source.index(signature) + end = source.index(end_marker, start) + 2 + function = source[start:end] + if declaration not in function: + raise SystemExit(name + ": loop counter declaration missing") + if "for (int i =" in function: + raise SystemExit(name + ": C99 loop declaration remains") + if loop not in function: + raise SystemExit(name + ": loop assignment sequence changed") +PY +then + pass "atexit cleanup/callfuncs use C89 declaration-order-safe loop counters" +else + bad "atexit cleanup/callfuncs use C89 declaration-order-safe loop counters" +fi + +# The active atexit_callfuncs() frontier must hoist callback locals before the +# loop's executable statements for MSVC6's C89 dialect. +if python3 - "$REPO_ROOT/cpython/Modules/atexitmodule.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("atexit_callfuncs(struct atexit_state *state)") +end = source.index("\n}\n\n\nvoid\n_PyAtExit_Call", start) + 2 +function = source[start:end] +if " PyObject *the_func;\n" not in function: + raise SystemExit("atexit_callfuncs: the_func declaration missing") +if " PyObject *res;\n" not in function: + raise SystemExit("atexit_callfuncs: res declaration missing") +if " PyObject* the_func = Py_NewRef(cb->func);" in function: + raise SystemExit("atexit_callfuncs: the_func remains a mixed declaration") +if " PyObject *res = PyObject_Call(cb->func, cb->args, cb->kwargs);" in function: + raise SystemExit("atexit_callfuncs: res remains a mixed declaration") +if function.count(" the_func = Py_NewRef(cb->func);\n") != 1: + raise SystemExit("atexit_callfuncs: the_func assignment sequence changed") +if function.count(" res = PyObject_Call(cb->func, cb->args, cb->kwargs);\n") != 1: + raise SystemExit("atexit_callfuncs: res assignment sequence changed") +PY +then + pass "atexit_callfuncs uses C89 declaration-order-safe callback locals" +else + bad "atexit_callfuncs uses C89 declaration-order-safe callback locals" +fi + +# The current atexitmodule.c VC6/C89 frontier must hoist every local in +# atexit_register() before its initial executable argument check. +if python3 - "$REPO_ROOT/cpython/Modules/atexitmodule.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("atexit_register(PyObject *module, PyObject *args, PyObject *kwargs)") +end = source.index("\n}\n\nPyDoc_STRVAR(atexit_run_exitfuncs__doc__", start) + 2 +function = source[start:end] +opening = function[:function.index(" if (PyTuple_GET_SIZE(args)")] +for declaration in ( + " PyObject *func;\n", + " struct atexit_state *state;\n", + " atexit_callback **r;\n", + " size_t size;\n", + " atexit_callback *callback;\n", +): + if declaration not in opening: + raise SystemExit("atexit_register declaration missing from opening group: " + declaration.strip()) +for mixed in ( + " PyObject *func = PyTuple_GET_ITEM(args, 0);", + " struct atexit_state *state = get_atexit_state();", + " atexit_callback **r;\n", + " size_t size = sizeof(atexit_callback*)", + " atexit_callback *callback = PyMem_Malloc", +): + if mixed in function: + raise SystemExit("atexit_register retains mixed declaration: " + mixed) +for assignment in ( + " func = PyTuple_GET_ITEM(args, 0);\n", + " state = get_atexit_state();\n", + " size = sizeof(atexit_callback*) * (size_t)state->callback_len;\n", + " callback = PyMem_Malloc(sizeof(atexit_callback));\n", +): + if function.count(assignment) != 1: + raise SystemExit("atexit_register assignment missing or duplicated: " + assignment.strip()) +if " r = (atexit_callback**)PyMem_Realloc(state->callbacks, size);\n" not in function: + raise SystemExit("atexit_register realloc assignment missing") +PY +then + pass "atexit_register uses C89 declaration-order-safe locals" +else + bad "atexit_register uses C89 declaration-order-safe locals" +fi + +# The active atexitmodule.c VC6/C89 frontier must hoist atexit_unregister() +# locals before the initial executable loop statement. +if python3 - "$REPO_ROOT/cpython/Modules/atexitmodule.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("atexit_unregister(PyObject *module, PyObject *func)") +end = source.index("\n}\n\n\nstatic PyMethodDef atexit_methods", start) + 2 +function = source[start:end] +opening = function[:function.index(" for (")] +for declaration in ( + " int i;\n", + " atexit_callback *cb;\n", + " int eq;\n", +): + if declaration not in opening: + raise SystemExit("atexit_unregister declaration missing from opening group: " + declaration.strip()) +for mixed in ( + "for (int i = 0;", + " atexit_callback *cb = state->callbacks[i];", + " int eq = PyObject_RichCompareBool(cb->func, func, Py_EQ);", +): + if mixed in function: + raise SystemExit("atexit_unregister retains mixed declaration: " + mixed) +if " struct atexit_state *state = get_atexit_state();\n int i;\n" not in function: + raise SystemExit("atexit_unregister state/local declaration order changed") +if function.count(" for (i = 0; i < state->ncallbacks; i++)") != 1: + raise SystemExit("atexit_unregister loop assignment changed") +if function.count(" cb = state->callbacks[i];\n") != 1: + raise SystemExit("atexit_unregister callback assignment missing") +if function.count(" eq = PyObject_RichCompareBool(cb->func, func, Py_EQ);\n") != 1: + raise SystemExit("atexit_unregister comparison assignment missing") +PY +then + pass "atexit_unregister uses C89 declaration-order-safe locals" +else + bad "atexit_unregister uses C89 declaration-order-safe locals" +fi + +# The next atexitmodule.c VC6 frontier must replace atexitmodule's C99 +# designated PyModuleDef initializer with declared-order positional fields. +if python3 - "$REPO_ROOT/cpython/Modules/atexitmodule.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("static struct PyModuleDef atexitmodule = {") +end = source.index("\n};", start) + 3 +module = source[start:end] +expected = '''static struct PyModuleDef atexitmodule = { + PyModuleDef_HEAD_INIT, + "atexit", + atexit__doc__, + 0, + atexit_methods, +};''' +if module != expected: + raise SystemExit("atexitmodule positional initializer mismatch") +PY +then + pass "atexitmodule uses C89-compatible positional PyModuleDef initializer" +else + bad "atexitmodule uses C89-compatible positional PyModuleDef initializer" +fi + +# The active audioop.c VC6 frontier must avoid SIZE_MAX, which VC6's standard +# headers do not provide, while preserving ratecv's allocation-overflow guard. +if python3 - "$REPO_ROOT/cpython/Modules/audioop.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("audioop_ratecv_impl(PyObject *module") +end = source.index("\n}\n\n/*[clinic input]\naudioop.lin2ulaw", start) + 2 +function = source[start:end] +if function.count("if ((size_t)nchannels > ((size_t)-1)/sizeof(int)) {") != 1: + raise SystemExit("audioop ratecv SIZE_MAX guard replacement missing") +if "SIZE_MAX" in function: + raise SystemExit("audioop ratecv retains unavailable SIZE_MAX") +sequence = ( + "if ((size_t)nchannels > ((size_t)-1)/sizeof(int)) {\n" + " PyErr_SetString(PyExc_MemoryError,\n" + " \"not enough memory for output buffer\");\n" + " return NULL;\n" + " }\n" + " prev_i = (int *) PyMem_Malloc(nchannels * sizeof(int));\n" + " cur_i = (int *) PyMem_Malloc(nchannels * sizeof(int));" +) +if sequence not in function: + raise SystemExit("audioop ratecv allocation guard sequence changed") +PY +then + pass "audioop ratecv allocation guard avoids unavailable SIZE_MAX" +else + bad "audioop ratecv allocation guard avoids unavailable SIZE_MAX" +fi + +# The next binascii.c VC6/C89 frontier must hoist a2b_base64 locals before +# its initial executable assertion and loop. +if python3 - "$REPO_ROOT/cpython/Modules/binascii.c" <<'PY' +import sys +from pathlib import Path +source = Path(sys.argv[1]).read_text() +start = source.index("binascii_a2b_base64_impl(PyObject *module") +end = source.index("\n}\n\n\n/*[clinic input]\nbinascii.b2a_base64", start) + 2 +function = source[start:end] +opening = function[:function.index(" /* Allocate the buffer */")] +for declaration in ( + " const unsigned char *ascii_data;\n", + " size_t ascii_len;\n", + " binascii_state *state;\n", + " char padding_started;\n", + " Py_ssize_t bin_len;\n", + " _PyBytesWriter writer;\n", + " unsigned char *bin_data;\n", + " unsigned char *bin_data_start;\n", + " int quad_pos;\n", + " unsigned char leftchar;\n", + " int pads;\n", + " size_t i;\n", + " unsigned char this_ch;\n", +): + if declaration not in opening: + raise SystemExit("a2b_base64 declaration missing from opening group: " + declaration.strip()) +for mixed in ( + "const unsigned char *ascii_data =", + "size_t ascii_len =", + "binascii_state *state =", + "char padding_started =", + "Py_ssize_t bin_len =", + "unsigned char *bin_data =", + "unsigned char *bin_data_start =", + "int quad_pos =", + "unsigned char leftchar =", + "int pads =", + "for (size_t i =", + "unsigned char this_ch =", +): + if mixed in function: + raise SystemExit("a2b_base64 retains mixed declaration: " + mixed) +for assignment in ( + " ascii_data = data->buf;\n", + " ascii_len = data->len;\n", + " state = NULL;\n", + " padding_started = 0;\n", + " bin_len = ((ascii_len+3)/4)*3; /* Upper bound, corrected later */\n", + " bin_data = _PyBytesWriter_Alloc(&writer, bin_len);\n", + " bin_data_start = bin_data;\n", + " quad_pos = 0;\n", + " leftchar = 0;\n", + " pads = 0;\n", + " for (i = 0; i < ascii_len; i++) {\n", + " this_ch = ascii_data[i];\n", +): + if assignment not in function: + raise SystemExit("a2b_base64 assignment sequence changed: " + assignment.strip()) +PY +then + pass "binascii a2b_base64 uses C89 declaration-order-safe locals" +else + bad "binascii a2b_base64 uses C89 declaration-order-safe locals" +fi + +# The active _datetimemodule.c VC6/C89 frontier must hoist iso_to_ymd() +# locals before its initial executable validation statements. +if python3 - "$REPO_ROOT/cpython/Modules/_datetimemodule.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("iso_to_ymd(const int iso_year") +end = source.index("\n}\n\n\n/* ---------------------------------------------------------------------------", start) + 2 +function = source[start:end] +opening = function[:function.index(" if (iso_week <= 0")] +for declaration in (" int day_1;\n", " int day_offset;\n"): + if declaration not in opening: + raise SystemExit("iso_to_ymd declaration missing from opening group: " + declaration.strip()) +if " int day_1 = iso_week1_monday(iso_year);" in function: + raise SystemExit("iso_to_ymd retains mixed day_1 declaration") +if " int day_offset = (iso_week - 1)*7 + iso_day - 1;" in function: + raise SystemExit("iso_to_ymd retains mixed day_offset declaration") +if " day_1 = iso_week1_monday(iso_year);\n" not in function: + raise SystemExit("iso_to_ymd day_1 assignment missing") +if " day_offset = (iso_week - 1)*7 + iso_day - 1;\n" not in function: + raise SystemExit("iso_to_ymd day_offset assignment missing") +PY +then + pass "_datetimemodule iso_to_ymd uses C89 declaration-order-safe locals" +else + bad "_datetimemodule iso_to_ymd uses C89 declaration-order-safe locals" +fi + +# The active _datetimemodule.c VC6 frontier must use CPython's compiler- +# conditional 64-bit spelling and literal suffix macros; VC6 rejects the +# portable long long keyword and C99 LL suffixes. +if python3 - "$REPO_ROOT/cpython/Modules/_datetimemodule.c" <<'PY' +import re +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +code = re.sub(r"/\*.*?\*/", "", source, flags=re.S) +code = re.sub(r"//.*", "", code) +if re.search(r"\b(?:unsigned\s+)?long\s+long\b", code): + raise SystemExit("_datetimemodule long long keyword remains") +if "719163LL" in code: + raise SystemExit("_datetimemodule C99 LL suffix remains") +if "PY_LONG_LONG max_fold_seconds" not in code: + raise SystemExit("_datetimemodule max_fold_seconds spelling missing") +if "PY_LONG_LONG epoch" not in code: + raise SystemExit("_datetimemodule epoch spelling missing") +if "#define EPOCH_SECONDS (PY_LL(719163) * 24 * 60 * 60)" not in source: + raise SystemExit("_datetimemodule epoch literal macro missing") +PY +then + pass "_datetimemodule uses compiler-compatible 64-bit spellings" +else + bad "_datetimemodule uses compiler-compatible 64-bit spellings" +fi + +# The current cmath VC6 frontier must replace its C99 designated PyModuleDef +# initializer with declared-order positional fields. +if python3 - "$REPO_ROOT/cpython/Modules/cmathmodule.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("static struct PyModuleDef cmathmodule = {") +end = source.index("\n};", start) + 3 +module = source[start:end] +expected = '''static struct PyModuleDef cmathmodule = { + PyModuleDef_HEAD_INIT, + "cmath", + module_doc, + 0, + cmath_methods, + cmath_slots +};''' +if module != expected: + raise SystemExit("cmathmodule positional initializer mismatch") +PY +then + pass "cmathmodule uses C89-compatible positional PyModuleDef initializer" +else + bad "cmathmodule uses C89-compatible positional PyModuleDef initializer" +fi + +# The current _datetimemodule.c VC6 frontier must declare parse_digits()'s +# loop counter before executable statements and assign it in the for init. +if python3 - "$REPO_ROOT/cpython/Modules/_datetimemodule.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("parse_digits(const char *ptr, int *var, size_t num_digits)") +end = source.index("\n}\n\nstatic int\nparse_isoformat_date", start) + 2 +function = source[start:end] +if " size_t i;" not in function: + raise SystemExit("parse_digits loop counter declaration missing") +if "for (size_t i = 0;" in function: + raise SystemExit("parse_digits retains C99 loop declaration") +if function.count("for (i = 0;") != 1: + raise SystemExit("parse_digits loop assignment missing") +PY +then + pass "_datetimemodule parse_digits uses C89-compatible loop counter" +else + bad "_datetimemodule parse_digits uses C89-compatible loop counter" +fi + +# The current _datetimemodule.c VC6 frontier must hoist parse_isoformat_date()'s +# separator flag before executable statements and assign it at the original point. +if python3 - "$REPO_ROOT/cpython/Modules/_datetimemodule.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("parse_isoformat_date(const char *dtstr") +end = source.index("\n}\n\nstatic int\nparse_isoformat_time", start) + 2 +function = source[start:end] +if " unsigned char uses_separator;" not in function: + raise SystemExit("parse_isoformat_date separator declaration missing") +if " const unsigned char uses_separator = (*p == '-');" in function: + raise SystemExit("parse_isoformat_date retains post-statement separator declaration") +if function.count(" uses_separator = (*p == '-');") != 1: + raise SystemExit("parse_isoformat_date separator assignment missing") +PY +then + pass "_datetimemodule parse_isoformat_date uses C89-compatible separator declaration" +else + bad "_datetimemodule parse_isoformat_date uses C89-compatible separator declaration" +fi + +# The active _datetimemodule.c VC6/C89 frontier must hoist the ISO-week locals +# before the executable parse_digits() call and preserve their assignments. +if python3 - "$REPO_ROOT/cpython/Modules/_datetimemodule.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("parse_isoformat_date(const char *dtstr") +end = source.index("\n}\n\nstatic int\nparse_isoformat_time", start) + 2 +function = source[start:end] +opening = function[:function.index(" if(*p == 'W')")] +for declaration in (" int iso_week;\n", " int iso_day;\n"): + if declaration not in opening: + raise SystemExit("parse_isoformat_date ISO-week declaration missing from opening group: " + declaration.strip()) +for mixed in (" int iso_week = 0;", " int iso_day = 0;"): + if mixed in function: + raise SystemExit("parse_isoformat_date retains post-statement ISO-week declaration: " + mixed) +if function.count(" iso_week = 0;\n") != 1: + raise SystemExit("parse_isoformat_date ISO-week assignment missing") +if function.count(" iso_day = 0;\n") != 1: + raise SystemExit("parse_isoformat_date ISO-day assignment missing") +PY +then + pass "_datetimemodule parse_isoformat_date uses C89-compatible ISO-week locals" +else + bad "_datetimemodule parse_isoformat_date uses C89-compatible ISO-week locals" +fi + +# The active _datetimemodule.c VC6/C89 frontier must hoist parse_isoformat_date()'s +# rv local before the executable ISO-week conversion call. +if python3 - "$REPO_ROOT/cpython/Modules/_datetimemodule.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("parse_isoformat_date(const char *dtstr") +end = source.index("\n}\n\nstatic int\nparse_isoformat_time", start) + 2 +function = source[start:end] +opening = function[:function.index(" if(*p == 'W')")] +if " int rv;\n" not in opening: + raise SystemExit("parse_isoformat_date rv declaration missing from opening group") +if " int rv = iso_to_ymd(" in function: + raise SystemExit("parse_isoformat_date retains post-statement rv declaration") +if function.count(" rv = iso_to_ymd(*year, iso_week, iso_day, year, month, day);\n") != 1: + raise SystemExit("parse_isoformat_date rv assignment missing") +PY +then + pass "_datetimemodule parse_isoformat_date uses C89-compatible rv local" +else + bad "_datetimemodule parse_isoformat_date uses C89-compatible rv local" +fi + +# The active _datetimemodule.c VC6/C89 frontier must hoist +# date_fromisocalendar()'s locals before executable statements and preserve the +# original conversion call position. +if python3 - "$REPO_ROOT/cpython/Modules/_datetimemodule.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("date_fromisocalendar(PyObject *cls") +end = source.index("\n}\n\n\n/*\n * Date arithmetic.", start) + 2 +function = source[start:end] +opening = function[:function.index(" if (PyArg_ParseTupleAndKeywords")] +for declaration in (" int month;\n", " int rv;\n"): + if declaration not in opening: + raise SystemExit("date_fromisocalendar declaration missing from opening group: " + declaration.strip()) +for mixed in (" int month;", " int rv = iso_to_ymd("): + if mixed in function[function.index(" // Year is bounded"):]: + raise SystemExit("date_fromisocalendar retains post-statement declaration: " + mixed) +if function.count(" rv = iso_to_ymd(year, week, day, &year, &month, &day);\n") != 1: + raise SystemExit("date_fromisocalendar conversion assignment missing") +PY +then + pass "_datetimemodule date_fromisocalendar uses C89-compatible locals" +else + bad "_datetimemodule date_fromisocalendar uses C89-compatible locals" +fi + +# The current _datetimemodule.c VC6/C89 frontier must hoist date_isocalendar()'s +# result local before executable statements and preserve the constructor call. +if python3 - "$REPO_ROOT/cpython/Modules/_datetimemodule.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("date_isocalendar(PyDateTime_Date *self") +end = source.index("\n}\n\n/* Miscellaneous methods. */", start) + 2 +function = source[start:end] +opening = function[:function.index(" v = iso_calendar_date_new_impl(")] +if " PyObject* v;\n" not in opening: + raise SystemExit("date_isocalendar v declaration missing from opening group") +if " PyObject* v = iso_calendar_date_new_impl(" in function: + raise SystemExit("date_isocalendar retains post-statement v declaration") +if function.count(" v = iso_calendar_date_new_impl(&PyDateTime_IsoCalendarDateType,\n") != 1: + raise SystemExit("date_isocalendar constructor assignment missing") +PY +then + pass "_datetimemodule date_isocalendar uses C89-compatible result local" +else + bad "_datetimemodule date_isocalendar uses C89-compatible result local" +fi + +# The active _datetimemodule.c VC6/C89 frontier must hoist +# iso_calendar_date_repr()'s tuple locals before the executable NULL check. +if python3 - "$REPO_ROOT/cpython/Modules/_datetimemodule.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("iso_calendar_date_repr(PyDateTime_IsoCalendarDate *self)") +end = source.index("\n}\n\nstatic PyObject *\niso_calendar_date_reduce", start) + 2 +function = source[start:end] +opening = function[:function.index(" if (year == NULL)")] +for declaration in (" PyObject* week;\n", " PyObject* weekday;\n"): + if declaration not in opening: + raise SystemExit("iso_calendar_date_repr declaration missing from opening group: " + declaration.strip()) +for mixed in (" PyObject* week = PyTuple_GetItem", " PyObject* weekday = PyTuple_GetItem"): + if mixed in function: + raise SystemExit("iso_calendar_date_repr retains post-statement declaration: " + mixed) +if function.count(" week = PyTuple_GetItem((PyObject *)self, 1);\n") != 1: + raise SystemExit("iso_calendar_date_repr week assignment missing") +if function.count(" weekday = PyTuple_GetItem((PyObject *)self, 2);\n") != 1: + raise SystemExit("iso_calendar_date_repr weekday assignment missing") +PY +then + pass "_datetimemodule iso_calendar_date_repr uses C89-compatible tuple locals" +else + bad "_datetimemodule iso_calendar_date_repr uses C89-compatible tuple locals" +fi + +# The active _datetimemodule.c VC6/C89 frontier must hoist +# tzinfo_from_isoformat_results()'s delta local before executable statements. +if python3 - "$REPO_ROOT/cpython/Modules/_datetimemodule.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("tzinfo_from_isoformat_results(int rv, int tzoffset, int tz_useconds)") +end = source.index("\n}\n\n/* ---------------------------------------------------------------------------", start) + 2 +function = source[start:end] +opening = function[:function.index(" if (rv == 1)")] +if " PyObject *delta;\n" not in opening: + raise SystemExit("tzinfo_from_isoformat_results delta declaration missing from opening group") +if " PyObject *delta = new_delta(" in function: + raise SystemExit("tzinfo_from_isoformat_results retains post-statement delta declaration") +if function.count(" delta = new_delta(0, tzoffset, tz_useconds, 1);\n") != 1: + raise SystemExit("tzinfo_from_isoformat_results delta assignment missing") +PY +then + pass "_datetimemodule tzinfo_from_isoformat_results uses C89-compatible delta local" +else + bad "_datetimemodule tzinfo_from_isoformat_results uses C89-compatible delta local" +fi + +# The active _datetimemodule.c VC6/C89 frontier must hoist delta_repr()'s +# separator and repr locals before executable statements. +if python3 - "$REPO_ROOT/cpython/Modules/_datetimemodule.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("delta_repr(PyDateTime_Delta *self)") +end = source.index("\n}\n\nstatic PyObject *\ndelta_str", start) + 2 +function = source[start:end] +opening = function[:function.index(" if (GET_TD_DAYS(self)")] +for declaration in (" const char *sep;\n", " PyObject *repr;\n"): + if declaration not in opening: + raise SystemExit("delta_repr declaration missing from opening group: " + declaration.strip()) +for mixed in (" const char *sep = \"\";", " PyObject *repr = PyUnicode_FromFormat"): + if mixed in function: + raise SystemExit("delta_repr retains mixed declaration: " + mixed) +if function.count(" sep = \"\";\n") != 1: + raise SystemExit("delta_repr separator assignment missing") +if function.count(" repr = PyUnicode_FromFormat(\"%s(%S)\", Py_TYPE(self)->tp_name,\n") != 1: + raise SystemExit("delta_repr repr assignment missing") +PY +then + pass "_datetimemodule delta_repr uses C89 declaration-order-safe locals" +else + bad "_datetimemodule delta_repr uses C89 declaration-order-safe locals" +fi + +# The active _datetimemodule.c VC6/C89 frontier must hoist parse_isoformat_time() +# locals before executable statements and preserve the original assignments. +if python3 - "$REPO_ROOT/cpython/Modules/_datetimemodule.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("parse_isoformat_time(const char *dtstr") +end = source.index("\n}\n\n/* ---------------------------------------------------------------------------", start) + 2 +function = source[start:end] +opening = function[:function.index(" do {")] +required = [ + " int rv;\n", + " int tzsign;\n", + " int tzhour;\n", + " int tzminute;\n", + " int tzsecond;\n", +] +for declaration in required: + if declaration not in opening: + raise SystemExit("parse_isoformat_time declaration missing from opening group: " + declaration.strip()) +for forbidden in ( + " int rv = parse_hh_mm_ss_ff(", + " int tzsign =", + " int tzhour = 0, tzminute = 0, tzsecond = 0;", +): + if forbidden in function: + raise SystemExit("parse_isoformat_time retains post-statement declaration: " + forbidden) +if function.count(" rv = parse_hh_mm_ss_ff(dtstr, tzinfo_pos, hour, minute, second,\n") != 1: + raise SystemExit("parse_isoformat_time initial rv assignment missing") +if function.count(" tzsign = (*tzinfo_pos == '-') ? -1 : 1;\n") != 1: + raise SystemExit("parse_isoformat_time timezone sign assignment missing") +if function.count(" tzhour = 0;\n") != 1 or function.count(" tzminute = 0;\n") != 1 or function.count(" tzsecond = 0;\n") != 1: + raise SystemExit("parse_isoformat_time timezone local assignments missing") +PY +then + pass "_datetimemodule parse_isoformat_time uses C89-compatible locals" +else + bad "_datetimemodule parse_isoformat_time uses C89-compatible locals" +fi + +# The active _datetimemodule.c VC6/C89 frontier must hoist all +# parse_hh_mm_ss_ff() locals before executable statements and avoid C99 +# aggregate/loop/declaration forms. +if python3 - "$REPO_ROOT/cpython/Modules/_datetimemodule.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("parse_hh_mm_ss_ff(const char *tstr") +end = source.index("\n}\n\nstatic int\nparse_isoformat_time", start) + 2 +function = source[start:end] +opening = function[:function.index(" *hour = *minute")] +required = [ + " int *vals[3];\n", + " unsigned char has_separator = 1;\n", + " size_t i;\n", + " size_t len_remains;\n", + " size_t to_parse;\n", + " static int correction[] = {\n", +] +for declaration in required: + if declaration not in opening: + raise SystemExit("parse_hh_mm_ss_ff declaration missing from opening group: " + declaration.strip()) +for forbidden in ("int *vals[3] = {hour, minute, second};", "for (size_t i = 0;", "char c = *(p++);", "size_t len_remains =", "size_t to_parse ="): + if forbidden in function: + raise SystemExit("parse_hh_mm_ss_ff retains C99/post-statement form: " + forbidden) +if function.count(" vals[0] = hour;\n") != 1 or function.count(" vals[1] = minute;\n") != 1 or function.count(" vals[2] = second;\n") != 1: + raise SystemExit("parse_hh_mm_ss_ff vals assignments missing") +if function.count("for (i = 0; i < 3; ++i) {") != 1: + raise SystemExit("parse_hh_mm_ss_ff C89 loop form missing") +if function.count(" char c;\n") != 1 or function.count(" c = *(p++);\n") != 1: + raise SystemExit("parse_hh_mm_ss_ff C89 character local form missing") +if function.count(" len_remains = p_end - p;\n") != 1 or function.count(" to_parse = len_remains;\n") != 1: + raise SystemExit("parse_hh_mm_ss_ff fractional assignments missing") +PY +then + pass "_datetimemodule parse_hh_mm_ss_ff uses C89-compatible locals" +else + bad "_datetimemodule parse_hh_mm_ss_ff uses C89-compatible locals" +fi + +# The current _datetimemodule.c VC6/C89 frontier must hoist +# date_fromisoformat() locals before its initial executable type check. +if python3 - "$REPO_ROOT/cpython/Modules/_datetimemodule.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("date_fromisoformat(PyObject *cls, PyObject *dtstr)") +end = source.index("\n}\n\n\nstatic PyObject *\ndate_fromisocalendar", start) + 2 +function = source[start:end] +opening = function[:function.index(" if (!PyUnicode_Check(dtstr))")] +for declaration in ( + " Py_ssize_t len;\n", + " const char *dt_ptr;\n", + " int year, month, day;\n", + " int rv;\n", +): + if declaration not in opening: + raise SystemExit("date_fromisoformat declaration missing from opening group: " + declaration.strip()) +for mixed in ( + " Py_ssize_t len;\n\n const char *dt_ptr =", + " const char *dt_ptr = PyUnicode_AsUTF8AndSize", + " int year = 0, month = 0, day = 0;", +): + if mixed in function: + raise SystemExit("date_fromisoformat retains post-statement declaration: " + mixed) +if function.count(" dt_ptr = PyUnicode_AsUTF8AndSize(dtstr, &len);\n") != 1: + raise SystemExit("date_fromisoformat dt_ptr assignment missing") +if function.count(" year = 0;\n month = 0;\n day = 0;\n") != 1: + raise SystemExit("date_fromisoformat date local assignments missing") +PY +then + pass "_datetimemodule date_fromisoformat uses C89-compatible locals" +else + bad "_datetimemodule date_fromisoformat uses C89-compatible locals" +fi + +# The current _datetimemodule.c VC6/C89 frontier must hoist +# time_fromisoformat() locals before its initial executable assertion. +if python3 - "$REPO_ROOT/cpython/Modules/_datetimemodule.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("time_fromisoformat(PyObject *cls, PyObject *tstr) {") +end = source.index("\n}\n\n\n/* Pickle support", start) + 2 +function = source[start:end] +opening = function[:function.index(" assert(tstr != NULL);")] +for declaration in ( + " Py_ssize_t len;\n", + " const char *p;\n", + " int hour, minute, second, microsecond;\n", + " int tzoffset, tzimicrosecond;\n", + " int rv;\n", + " PyObject *tzinfo;\n", + " PyObject *t;\n", +): + if declaration not in opening: + raise SystemExit("time_fromisoformat declaration missing from opening group: " + declaration.strip()) +for mixed in ( + " const char *p = PyUnicode_AsUTF8AndSize", + " int hour = 0, minute = 0, second = 0, microsecond = 0;", + " int tzoffset = 0, tzimicrosecond = 0;", + " int rv = parse_isoformat_time(", + " PyObject *tzinfo = tzinfo_from_isoformat_results(", + " PyObject *t;\n", +): + if mixed in function[function.index(" assert(tstr != NULL);"):]: + raise SystemExit("time_fromisoformat retains mixed declaration: " + mixed) +for assignment in ( + " p = PyUnicode_AsUTF8AndSize(tstr, &len);\n", + " hour = minute = second = microsecond = 0;\n", + " tzoffset = tzimicrosecond = 0;\n", + " rv = parse_isoformat_time(p, len,\n", + " PyObject *tzinfo =", +): + if assignment == " PyObject *tzinfo =": + continue + if assignment not in function: + raise SystemExit("time_fromisoformat assignment missing: " + assignment.strip()) +if " tzinfo = tzinfo_from_isoformat_results(rv, tzoffset,\n" not in function: + raise SystemExit("time_fromisoformat tzinfo assignment missing") +PY +then + pass "_datetimemodule time_fromisoformat uses C89-compatible locals" +else + bad "_datetimemodule time_fromisoformat uses C89-compatible locals" +fi + MSVC600_ROOT="${MSVC600_ROOT:-$REPO_ROOT/MSVC600}" if command -v wine >/dev/null 2>&1 && [ -e "$MSVC600_ROOT/VC98/Bin/CL.EXE" ]; then live_out="$($PROBE --limit 1 2>&1)" @@ -140,6 +2254,220 @@ else echo "skip - wine/MSVC600 not available; skipping live frontier integration check" fi +# The current _datetimemodule.c VC6 frontier must replace the ISO calendar +# date type's C99 designated PyTypeObject initializer with declared-order +# positional fields, matching the already-portable datetime type definitions. +if python3 - "$REPO_ROOT/cpython/Modules/_datetimemodule.c" <<'PY' +import sys +from pathlib import Path +source = Path(sys.argv[1]).read_text() +start = source.index("static PyTypeObject PyDateTime_IsoCalendarDateType = {") +end = source.index("\n};", start) + 3 +actual = source[start:end] +expected = '''static PyTypeObject PyDateTime_IsoCalendarDateType = { + PyVarObject_HEAD_INIT(NULL, 0) + "datetime.IsoCalendarDate", + sizeof(PyDateTime_IsoCalendarDate), + 0, + 0, + 0, + 0, + 0, + 0, + (reprfunc) iso_calendar_date_repr, + 0, + 0, + 0, + 0, + 0, + 0, + PyObject_GenericGetAttr, + 0, + 0, + Py_TPFLAGS_DEFAULT, + iso_calendar_date__doc__, + 0, + 0, + 0, + 0, + 0, + 0, + iso_calendar_date_methods, + 0, + iso_calendar_date_getset, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + iso_calendar_date_new, + 0, +};''' +if actual != expected: + raise SystemExit("iso calendar date type positional initializer mismatch") +PY +then + pass "_datetimemodule ISO calendar date type uses C89-compatible positional initializer" +else + bad "_datetimemodule ISO calendar date type uses C89-compatible positional initializer" +fi + +# The current _datetimemodule.c VC6 frontier must hoist _sanitize_isoformat_str() +# locals before executable statements while preserving initializer order. +if python3 - "$REPO_ROOT/cpython/Modules/_datetimemodule.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("_sanitize_isoformat_str(PyObject *dtstr)") +end = source.index("\n}\n\n\nstatic Py_ssize_t\n_find_isoformat_datetime_separator", start) + 2 +function = source[start:end] +opening = function[:function.index(" Py_ssize_t len = PyUnicode_GetLength(dtstr);")] +for declaration in ( + " static const size_t potential_separators[3] = {7, 8, 10};\n", + " const void *unicode_data;\n", + " unsigned int kind;\n", + " size_t surrogate_separator;\n", + " size_t idx;\n", + " PyObject *str_out;\n", +): + if declaration not in opening: + raise SystemExit("_sanitize_isoformat_str declaration missing from opening group: " + declaration.strip()) +for forbidden in ( + " const void* const unicode_data =", + " const unsigned int kind =", + " static const size_t potential_separators[3] = {7, 8, 10};\n size_t surrogate_separator", + " for(size_t idx = 0;", + " PyObject *str_out = _PyUnicode_Copy(dtstr);", +): + if forbidden in function: + raise SystemExit("_sanitize_isoformat_str retains post-statement declaration: " + forbidden) +for assignment in ( + " unicode_data = PyUnicode_DATA(dtstr);\n", + " kind = PyUnicode_KIND(dtstr);\n", + " surrogate_separator = 0;\n", + " for (idx = 0;\n", + " str_out = _PyUnicode_Copy(dtstr);\n", +): + if assignment not in function: + raise SystemExit("_sanitize_isoformat_str assignment missing: " + assignment.strip()) +PY +then + pass "_datetimemodule _sanitize_isoformat_str uses C89-compatible locals" +else + bad "_datetimemodule _sanitize_isoformat_str uses C89-compatible locals" +fi + +# The active _datetimemodule.c VC6 frontier must hoist datetime_fromisoformat() +# locals before executable statements while preserving initializer order. +if python3 - "$REPO_ROOT/cpython/Modules/_datetimemodule.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("datetime_fromisoformat(PyObject *cls, PyObject *dtstr)") +end = source.index("\n}\n\n/*\n * Destructor.", start) + 2 +function = source[start:end] +opening = function[:function.index(" assert(dtstr != NULL);")] +for declaration in ( + " PyObject *dtstr_clean;\n", + " Py_ssize_t len;\n", + " const char *dt_ptr;\n", + " Py_ssize_t separator_location;\n", + " const char *p;\n", + " int year, month, day;\n", + " int hour, minute, second, microsecond;\n", + " int tzoffset, tzusec;\n", + " int rv;\n", + " PyObject *tzinfo;\n", + " PyObject *dt;\n", +): + if declaration not in opening: + raise SystemExit("datetime_fromisoformat declaration missing from opening group: " + declaration.strip()) +for forbidden in ( + " PyObject *dtstr_clean =", + " const char *dt_ptr =", + " const Py_ssize_t separator_location =", + " const char *p =", + " int year = 0, month = 0, day = 0;", + " int hour = 0, minute = 0, second = 0, microsecond = 0;", + " int tzoffset = 0, tzusec = 0;", + " int rv = parse_isoformat_date(", + " PyObject *tzinfo =", + " PyObject *dt =", +): + if forbidden in function: + raise SystemExit("datetime_fromisoformat retains mixed declaration: " + forbidden) +for assignment in ( + " dtstr_clean = _sanitize_isoformat_str(dtstr);\n", + " dt_ptr = PyUnicode_AsUTF8AndSize(dtstr_clean, &len);\n", + " separator_location = _find_isoformat_datetime_separator(\n", + " p = dt_ptr;\n", + " year = 0; month = 0; day = 0;\n", + " hour = 0; minute = 0; second = 0; microsecond = 0;\n", + " tzoffset = 0; tzusec = 0;\n", + " rv = parse_isoformat_date(p, separator_location, &year, &month, &day);\n", + " tzinfo = tzinfo_from_isoformat_results(rv, tzoffset, tzusec);\n", + " dt = new_datetime_subclass_ex(year, month, day, hour, minute,\n", +): + if assignment not in function: + raise SystemExit("datetime_fromisoformat assignment missing: " + assignment.strip()) +PY +then + pass "_datetimemodule datetime_fromisoformat uses C89-compatible locals" +else + bad "_datetimemodule datetime_fromisoformat uses C89-compatible locals" +fi + +# The active _datetimemodule.c VC6 frontier must hoist all _datetime_exec() +# locals before executable statements while preserving later assignments. +if python3 - "$REPO_ROOT/cpython/Modules/_datetimemodule.c" <<'PY' +import sys +from pathlib import Path + +source = Path(sys.argv[1]).read_text() +start = source.index("_datetime_exec(PyObject *module)") +end = source.index("\n}\n\nstatic struct PyModuleDef", start) + 2 +function = source[start:end] +opening = function[:function.index(" // `&...`")] +body = function[len(opening):] +for declaration in ( + " PyTypeObject *types[] = {\n", + " size_t i;\n", + " PyObject *d;\n", + " PyObject *delta;\n", + " PyObject *x;\n", + " PyDateTime_CAPI *capi;\n", +): + if declaration not in opening: + raise SystemExit("_datetime_exec declaration missing from opening group: " + declaration.strip()) +for forbidden in ( + " PyTypeObject *types[] = {\n &PyDateTime_DateType,", + " for (size_t i = 0;", + " PyObject *d = PyDateTime_DeltaType.tp_dict;", + " PyObject *delta = new_delta(0, 0, 0, 0);", + " PyObject *x = create_timezone(delta, NULL);", + " PyDateTime_CAPI *capi = get_datetime_capi();", +): + if forbidden in body: + raise SystemExit("_datetime_exec retains post-statement declaration: " + forbidden.strip()) +for assignment in ( + " d = PyDateTime_DeltaType.tp_dict;\n", + " delta = new_delta(0, 0, 0, 0);\n", + " x = create_timezone(delta, NULL);\n", + " capi = get_datetime_capi();\n", +): + if assignment not in function: + raise SystemExit("_datetime_exec assignment missing: " + assignment.strip()) +PY +then + pass "_datetimemodule _datetime_exec uses C89-compatible locals" +else + bad "_datetimemodule _datetime_exec uses C89-compatible locals" +fi + if [ "$fail" -ne 0 ]; then echo "FAILED" exit 1