Skip to content

Fix filter equality against int literal truncating float values (#227) - #241

Open
youdie006 wants to merge 1 commit into
h2non:masterfrom
youdie006:fix/227-filter-int-float-truncation
Open

Fix filter equality against int literal truncating float values (#227)#241
youdie006 wants to merge 1 commit into
h2non:masterfrom
youdie006:fix/227-filter-int-float-truncation

Conversation

@youdie006

Copy link
Copy Markdown

Fixes #227.

Problem

An extended filter comparing against an integer literal wrongly matched float values. For example $[?(@.v = 0)] matched an element with v = 0.6:

from jsonpath_ng.ext import parse
data = [{"k": "A", "v": 0.0}, {"k": "B", "v": 0.6}, {"k": "C", "v": 0}]
parse("$[?(@.v = 0)].k").find(data)   # returned ["A", "B", "C"], expected ["A", "C"]

Root cause

In Expression.find (jsonpath_ng/ext/filter.py), when the RHS literal is an int, the LHS value was coerced with int(value) before comparison. For a float LHS this truncates (int(0.6) == 0), so an equality filter against 0 wrongly matched 0.6.

Fix

Restrict the coercion to string LHS values (isinstance(value, str)). This preserves the original string->int intent (e.g. matching "5" against 5) while leaving numeric values uncoerced, so float comparisons stay exact. Booleans are unaffected (type(True) is int is False).

Tests

  • Added a parametrized case issue-227-int-no-float-truncation.
  • Red/green verified: without the fix the case returns ["A", "B", "C"] (fails); with the fix it returns ["A", "C"].
  • Full ext suite and tests/ pass (352 passed).
  • CHANGELOG.md updated under [Unreleased] / Fixed per CONTRIBUTING.md.

Thanks to @AkiraVoid for the clear bug report.


This change was prepared with AI assistance and reviewed by me before submission.

In Expression.find (jsonpath_ng/ext/filter.py), when the RHS literal is an
int, the LHS value was coerced with int(value) before comparison. For a float
LHS this truncates (int(0.6) == 0), so an equality filter against 0 wrongly
matched 0.6, e.g. $[?(@.v = 0)] matched an element with v = 0.6.

Restrict the coercion to string LHS values (isinstance(value, str)). This
preserves the original string->int intent (matching "5" against 5) while
leaving numeric values uncoerced, so float comparisons stay exact. Booleans
are unaffected (type(True) is int is False).

Fixes h2non#227.
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.

[Bug] 0 is not equal to 0.0

1 participant