Skip to content

[codex] Fix SharedNPArray partial init cleanup - #99

Merged
den-sq merged 1 commit into
mainfrom
codex/fix-shared-np-array-del
Jul 3, 2026
Merged

[codex] Fix SharedNPArray partial init cleanup#99
den-sq merged 1 commit into
mainfrom
codex/fix-shared-np-array-del

Conversation

@den-sq

@den-sq den-sq commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

Fixes #97

Summary

  • add a class-level SharedNPArray.__shutdown default of True so partially constructed instances are treated as already shut down
  • add a regression test covering both object.__new__ reconstruction and failed SharedMemory lookup without unraisable destructor warnings

Root Cause

SharedNPArray.__init__ could raise before assigning the instance __shutdown flag. When Python finalized that half-built object, __del__ read the missing attribute and pytest reported a PytestUnraisableExceptionWarning.

Validation

@tavateva tavateva left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Draft Promotion Criteria — FAIL on criterion 4 (fixable documentation gap)

Code and regression test are correct. Blocking promotion on the same missing-pass-count issue we hit on den-sq/mctutil#78.

Passes:

  1. CI & mergeability — all 3 checks green (`coverage`, `server-image`, `test-coverage`); `mergeable: MERGEABLE`, `mergeStateStatus: CLEAN`. ✓

  2. Issue Acceptance Criteria — issue #97's 3-item checklist:

    • `del` no longer raises `AttributeError` on partially-constructed instances → satisfied by class-level `__shutdown = True` default at mem.py:22. The name-mangled attribute (`_SharedNPArray__shutdown`) resolves via class lookup when the instance attribute is unset, so `if not self.__shutdown:` correctly reads `True` and skips `shutdown()`. ✓
    • Regression test → `test_partial_shared_np_array_destruction_is_already_shutdown` covers both paths (`object.new` reconstruction and a failed `SharedMemory` lookup), forces `gc.collect()`, and decorates with `@pytest.mark.filterwarnings("error::pytest.PytestUnraisableExceptionWarning")` so any regression flips the warning into a hard failure. ✓
    • Two-warning count drop → verifiable by re-running the coverage workflow; PR body doesn't explicitly cite the delta, but the strict filter effectively enforces it. ✓ (soft)
  3. Test Plan checkboxes — no checkbox section. N/A.

  4. Tests run, not just report — Validation section reads:

    `poetry run pytest test/helpers/test_mem.py -W error::pytest.PytestUnraisableExceptionWarning`

    Issue #97's AC includes a test requirement ("A test ... confirms no `PytestUnraisableExceptionWarning`"), so criterion 4 requires concrete pass/fail counts ("X passed / Y skipped") in the PR body. Command is listed but no counts. CI green implies it passed, but the criterion demands explicit reporting. Failure.

  5. Scope — mem.py +2 (class attr) / test_mem.py +13 (regression test + `gc` import). Tight to #97. ✓

  6. Regressions & patterns — class-level attribute pattern matches how similar guards are handled elsewhere in the codebase; no other code paths touched. ✓

  7. Judgement calls — chose Option 1 (class-level default) from #97's suggested-fix pair; explained inline in Root Cause. Also the `gc.collect()` after the `FileNotFoundError` path is a subtle judgement (needed because CPython may not have finalized the half-built object by the time the test returns) — not explicitly explained but obvious from context. ✓

Fix to promote: append pass count to the Validation section, e.g.:

```
poetry run pytest test/helpers/test_mem.py -W error::pytest.PytestUnraisableExceptionWarning
→ N passed, M skipped
```

Also worth adding a full-suite `pytest` run with its count to confirm no regressions elsewhere. Then all 7 criteria hold.

@tavateva tavateva left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Re-review — Draft Promotion Criteria PASS ✅

Validation section updated with concrete pass counts. All 7 criteria hold.

  1. CI & mergeability — 3 checks green (`coverage`, `server-image`, `test-coverage`); MERGEABLE / CLEAN. ✓
  2. Issue #97 AC — class-level `__shutdown` default satisfies the "no AttributeError on partial instance" item; regression test covers both `object.new` and failed-`SharedMemory` paths. ✓
  3. Test Plan checkboxes — N/A.
  4. Tests run with counts — targeted `pytest test/helpers/test_mem.py -W error::pytest.PytestUnraisableExceptionWarning` → 5 passed in 2.38s; full `pytest` → 169 passed, 1 warning in 5.65s (up from 168, +1 = new regression test). The remaining warning is explicitly identified as the sibling Pydantic warning tracked in #98 / PR #100 — no hidden regressions. ✓
  5. Scope — mem.py +2 / test_mem.py +13. ✓
  6. Regressions & patterns — 169 = 168 baseline (from PR #96) + 1 new regression test; no existing tests broke. ✓
  7. Judgement calls — reasoned inline. ✓

Approving. Safe to promote and merge.

@den-sq
den-sq marked this pull request as ready for review July 3, 2026 00:05
@den-sq
den-sq merged commit 19a0fb6 into main Jul 3, 2026
3 checks passed
@den-sq
den-sq deleted the codex/fix-shared-np-array-del branch July 3, 2026 00:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SharedNPArray.__del__ AttributeError on partially-constructed instance (mem.py:76)

2 participants