fix(python): slice must not treat a boolean as a number - #85
Merged
Conversation
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Python's
boolis a subclass ofint, soisinstance(val, (int, float))sent booleans downslice's numeric clamp path:slice(True, 1)True1Trueslice(True, 0, 1)True0Trueslice(False, 1)False1FalseCanonical
StructUtility.tsguards withS_number === typeof val, andtypeof trueis"boolean", so a boolean falls through to the container path and is returned unchanged. Excludingboolrestores 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 which1 == True, so the wrong value passes. It surfaced while running the python suite undervoxgig/omni, whosedeepequalrefuses 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/FalseClassexplicitly, Perl requires!ref(JSON booleans are blessed refs), PHP'sis_numeric(true)isfalse, and Lua'stype(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 canonicalsliceoutput for the cases in the table.Generated by Claude Code