Skip to content

Commit f2bc762

Browse files
committed
Fix parsing of scientific notation in JSONPath queries
1 parent 65c8920 commit f2bc762

File tree

4 files changed

+17
-5
lines changed

4 files changed

+17
-5
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
**Fixes**
1111

1212
- We no longer silently ignore invalid escape sequences in JSONPath string literals. For example, `$['\"']` used to be OK, it now raises a `JSONPathSyntaxError`.
13+
- Fixed parsing of JSONPath integer literals that use scientific notation.
1314

1415
## Version 0.9.0
1516

jsonpath/lex.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ def compile_rules(self) -> Pattern[str]:
139139
(TOKEN_BRACKET_PROPERTY, self.bracketed_property_pattern),
140140
(TOKEN_DOT_PROPERTY, self.dot_property_pattern),
141141
(TOKEN_FLOAT, r"-?\d+\.\d*(?:e[+-]?\d+)?"),
142-
(TOKEN_INT, r"-?\d+(?:e[+\-]?\d+)?\b"),
142+
(TOKEN_INT, r"-?\d+(?P<G_EXP>e[+\-]?\d+)?\b"),
143143
(TOKEN_DDOT, r"\.\."),
144144
(TOKEN_AND, self.bool_and_pattern),
145145
(TOKEN_OR, self.bool_or_pattern),
@@ -265,6 +265,19 @@ def tokenize(self, path: str) -> Iterator[Token]: # noqa PLR0912
265265
value=match.group("G_SQUOTE"),
266266
index=match.start("G_SQUOTE"),
267267
)
268+
elif kind == TOKEN_INT:
269+
if match.group("G_EXP") and match.group("G_EXP")[1] == "-":
270+
yield _token(
271+
kind=TOKEN_FLOAT,
272+
value=match.group(),
273+
index=match.start(),
274+
)
275+
else:
276+
yield _token(
277+
kind=TOKEN_INT,
278+
value=match.group(),
279+
index=match.start(),
280+
)
268281
elif kind == TOKEN_RE_PATTERN:
269282
yield _token(
270283
kind=TOKEN_RE_PATTERN,

jsonpath/parse.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,8 @@ def parse_string_literal(self, stream: TokenStream) -> FilterExpression:
454454
return StringLiteral(value=self._decode_string_literal(stream.current))
455455

456456
def parse_integer_literal(self, stream: TokenStream) -> FilterExpression:
457-
return IntegerLiteral(value=int(stream.current.value))
457+
# Convert to float first to handle scientific notation.
458+
return IntegerLiteral(value=int(float(stream.current.value)))
458459

459460
def parse_float_literal(self, stream: TokenStream) -> FilterExpression:
460461
return FloatLiteral(value=float(stream.current.value))

tests/test_compliance.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,6 @@ class Case:
7878
"filter, multiple selectors, filter and wildcard": "TODO",
7979
"filter, multiple selectors, filter and slice": "TODO",
8080
"filter, multiple selectors, comparison filter, index and slice": "TODO",
81-
"filter, equals number, exponent": "TODO",
82-
"filter, equals number, positive exponent": "TODO",
83-
"filter, equals number, negative exponent": "TODO",
8481
"filter, equals number, decimal fraction, no fractional digit": "TODO",
8582
"functions, length, result must be compared": "ignore",
8683
"functions, count, result must be compared": "ignore",

0 commit comments

Comments
 (0)