Skip to content

fix(python): slice must not treat a boolean as a number - #85

Merged
rjrodger merged 1 commit into
mainfrom
claude/test-spec-utility-review-f1clz7
Aug 18, 2026
Merged

fix(python): slice must not treat a boolean as a number#85
rjrodger merged 1 commit into
mainfrom
claude/test-spec-utility-review-f1clz7

Conversation

@rjrodger

Copy link
Copy Markdown
Contributor

Python's bool is a subclass of int, so isinstance(val, (int, float)) sent booleans down slice's numeric clamp path:

Call Canonical (TS/JS) python, before after
slice(True, 1) True 1 True
slice(True, 0, 1) True 0 True
slice(False, 1) False 1 False

Canonical StructUtility.ts guards with S_number === typeof val, and typeof true is "boolean", so a boolean falls through to the container path and is returned unchanged. Excluding bool restores that.

Why the corpus did not catch it

It cannot — not in this port or any other. The in-situ runner compares results with plain ==, under which 1 == True, so the wrong value passes. It surfaced while running the python suite under voxgig/omni, whose deepequal refuses to conflate booleans with numbers.

Worth pinning with a corpus entry once enough ports run under a strict comparison for the entry to mean something; that is recorded in omni's handover note rather than added here, where it would be toothless.

Other ports

Checked, and all four already guard: Ruby excludes TrueClass/FalseClass explicitly, Perl requires !ref (JSON booleans are blessed refs), PHP's is_numeric(true) is false, and Lua's type(true) is "boolean".

Verification

cd python && python3 -m unittest discover -s tests — 100 tests, 3 skipped, OK. Unchanged from before the fix, as expected given the == comparison; the fix is verified directly against canonical slice output for the cases in the table.


Generated by Claude Code

Python's bool is a subclass of int, so `isinstance(val, (int, float))`
sent booleans down slice's numeric clamp path:

    slice(True, 1)     -> 1      (canonical: True)
    slice(True, 0, 1)  -> 0      (canonical: True)
    slice(False, 1)    -> 1      (canonical: False)

Canonical StructUtility.ts guards with `S_number === typeof val`, and
`typeof true` is "boolean", so a boolean falls through to the container
path and is returned unchanged. Excluding bool restores that.

The corpus cannot catch this, in this port or any other: the in-situ
runner compares results with plain `==`, under which `1 == True`, so the
wrong value passes. It surfaced while running the suite under voxgig/omni,
whose deepequal refuses to conflate booleans with numbers. Worth pinning
with a corpus entry once enough ports run under a strict comparison to
make the entry mean something; recorded in omni's handover note.

The other dynamic ports were checked and already guard: Ruby excludes
TrueClass/FalseClass explicitly, Perl requires !ref (JSON booleans are
blessed refs), PHP's is_numeric(true) is false, and Lua's type(true) is
"boolean".

python: 100 tests, 3 skipped, OK - unchanged from before the fix, as
expected given the `==` comparison.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EHLH9d5Jaiy6QbMKja22nt
@rjrodger
rjrodger merged commit 2e20c29 into main Aug 18, 2026
126 of 127 checks passed
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.

2 participants