Skip to content

Commit 205b235

Browse files
authored
Merge pull request #67 from jg-rp/update-cts
Update CTS and fix
2 parents eda8288 + ddde9e9 commit 205b235

File tree

6 files changed

+41
-5
lines changed

6 files changed

+41
-5
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@
55
**Fixes**
66

77
- Fixed handling of JSONPath literals in filter expressions. We now raise a `JSONPathSyntaxError` if a filter expression literal is not part of a comparison, membership or function expression. See [jsonpath-compliance-test-suite#81](https://github.com/jsonpath-standard/jsonpath-compliance-test-suite/pull/81).
8+
- Fixed parsing of number literals including an exponent. Upper case 'e's are now allowed.
9+
- Fixed handling of trailing commas in bracketed selection lists. We now raise a `JSONPathSyntaxError` in such cases.
810

911
**Compliance**
1012

1113
- Skipped tests for invalid escape sequences. The JSONPath spec is more strict than Python's JSON decoder when it comes to parsing `\u` escape sequences in string literals. We are adopting a policy of least surprise. The assertion is that most people will expect the JSONPath parser to behave the same as Python's JSON parser. See [jsonpath-compliance-test-suite #87](https://github.com/jsonpath-standard/jsonpath-compliance-test-suite/pull/87).
14+
- Skipped tests for invalid integer and float literals. Same as above. We are deliberately choosing to match Python's int and float parsing behavior. See [jsonpath-compliance-test-suite #89](https://github.com/jsonpath-standard/jsonpath-compliance-test-suite/pull/89).
15+
- Skipped tests for incorrect casing `true`, `false` and `null` literals.
1216

1317
**Features**
1418

docs/syntax.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ And this is a list of areas where we deviate from [RFC 9535](https://datatracker
208208
- We don't require property names to be quoted inside a bracketed selection, unless the name contains reserved characters.
209209
- We don't require the recursive descent segment to have a selector. `$..` is equivalent to `$..*`.
210210
- We support explicit comparisons to `undefined` as well as implicit existence tests.
211-
- Float literals without a fractional digit are OK. `1.` is equivalent to `1.0`.
211+
- Float literals without a fractional digit are OK or leading digit. `1.` is equivalent to `1.0`.
212212
- We treat literals (such as `true` and `false`) as valid "basic" expressions. For example, `$[?true || false]`, without an existence test or comparison either side of logical _or_, does not raise a syntax error.
213213
- By default, `and` is equivalent to `&&` and `or` is equivalent to `||`.
214214
- `none` and `nil` are aliases for `null`.

jsonpath/lex.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""JSONPath tokenization."""
2+
23
from __future__ import annotations
34

45
import re
@@ -138,8 +139,8 @@ def compile_rules(self) -> Pattern[str]:
138139
(TOKEN_LIST_SLICE, self.slice_list_pattern),
139140
(TOKEN_FUNCTION, self.function_pattern),
140141
(TOKEN_DOT_PROPERTY, self.dot_property_pattern),
141-
(TOKEN_FLOAT, r"-?\d+\.\d*(?:e[+-]?\d+)?"),
142-
(TOKEN_INT, r"-?\d+(?P<G_EXP>e[+\-]?\d+)?\b"),
142+
(TOKEN_FLOAT, r"-?\d+\.\d*(?:[eE][+-]?\d+)?"),
143+
(TOKEN_INT, r"-?\d+(?P<G_EXP>[eE][+\-]?\d+)?\b"),
143144
(TOKEN_DDOT, r"\.\."),
144145
(TOKEN_AND, self.logical_and_pattern),
145146
(TOKEN_OR, self.logical_or_pattern),

jsonpath/parse.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,12 @@ def parse_selector_list(self, stream: TokenStream) -> ListSelector: # noqa: PLR
474474
stream.expect_peek(TOKEN_COMMA)
475475
stream.next_token()
476476

477+
if stream.peek.kind == TOKEN_RBRACKET:
478+
raise JSONPathSyntaxError(
479+
"unexpected trailing comma",
480+
token=stream.peek,
481+
)
482+
477483
stream.next_token()
478484

479485
if not list_items:

tests/test_compliance.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import json
99
import operator
1010
from dataclasses import dataclass
11+
from dataclasses import field
1112
from typing import Any
1213
from typing import List
1314
from typing import Mapping
@@ -28,6 +29,7 @@ class Case:
2829
result: Any = None
2930
results: Optional[List[Any]] = None
3031
invalid_selector: Optional[bool] = None
32+
tags: List[str] = field(default_factory=list)
3133

3234

3335
SKIP = {
@@ -43,12 +45,35 @@ class Case:
4345
"functions, match, filter, match function, unicode char class negated, uppercase": "\\P not supported", # noqa: E501
4446
"functions, search, filter, search function, unicode char class, uppercase": "\\p not supported", # noqa: E501
4547
"functions, search, filter, search function, unicode char class negated, uppercase": "\\P not supported", # noqa: E501
46-
"filter, equals number, decimal fraction, no fractional digit": "TODO",
48+
"filter, equals number, decimal fraction, no fractional digit": "expected behavior policy", # noqa: E501
49+
"filter, equals number, decimal fraction, no int digit": "expected behavior policy",
50+
"filter, equals number, invalid no int digit": "expected behavior policy",
51+
"filter, equals number, invalid 00": "expected behavior policy",
52+
"filter, equals number, invalid leading 0": "expected behavior policy",
53+
"filter, equals number, invalid no fractional digit": "expected behavior policy",
54+
"filter, equals number, invalid no fractional digit e": "expected behavior policy",
55+
"slice selector, start, leading 0": "expected behavior policy",
56+
"slice selector, start, -0": "expected behavior policy",
57+
"slice selector, start, leading -0": "expected behavior policy",
58+
"slice selector, end, leading 0": "expected behavior policy",
59+
"slice selector, end, minus space": "expected behavior policy",
60+
"slice selector, end, -0": "expected behavior policy",
61+
"slice selector, end, leading -0": "expected behavior policy",
62+
"slice selector, step, leading 0": "expected behavior policy",
63+
"slice selector, step, minus space": "expected behavior policy",
64+
"slice selector, step, -0": "expected behavior policy",
65+
"slice selector, step, leading -0": "expected behavior policy",
66+
"filter, true, incorrectly capitalized": "flexible literal policy",
67+
"filter, false, incorrectly capitalized": "flexible literal policy",
68+
"filter, null, incorrectly capitalized": "flexible literal policy",
4769
"name selector, double quotes, single high surrogate": "expected behavior policy",
4870
"name selector, double quotes, single low surrogate": "expected behavior policy",
4971
"name selector, double quotes, high high surrogate": "expected behavior policy",
5072
"name selector, double quotes, low low surrogate": "expected behavior policy",
5173
"name selector, double quotes, surrogate non-surrogate": "expected behavior policy",
74+
"name selector, double quotes, non-surrogate surrogate": "expected behavior policy",
75+
"name selector, double quotes, surrogate supplementary": "expected behavior policy",
76+
"name selector, double quotes, supplementary surrogate": "expected behavior policy",
5277
"whitespace, selectors, space between dot and name": "flexible whitespace policy", # noqa: E501
5378
"whitespace, selectors, newline between dot and name": "flexible whitespace policy", # noqa: E501
5479
"whitespace, selectors, tab between dot and name": "flexible whitespace policy", # noqa: E501

0 commit comments

Comments
 (0)