Whole file

sean2077/jsonpath-python

The author described this change as fix: resolve issue #15 where filters with bracket notation returned empty results. It counts as a record because the check below fails on the code as it stood at 6caa9d4e0 and passes on 100bf6fda, with nothing else changed between the two runs.

Fix saved2025-11-23
Sharing licenceMIT · LICENSE
Change size+14 9

What the code was meant to do, written into the code itself as a save note

fix: resolve issue #15 where filters with bracket notation returned empty results

The change

5353 # operators
5454 REP_SLICE_CONTENT = re.compile(r"^(-?\d*)?:(-?\d*)?(:-?\d*)?$")
5555 REP_SELECT_CONTENT = re.compile(r"^([\w.']+)(, ?[\w.']+)+$")
56- REP_FILTER_CONTENT = re.compile(r"@\.(.*?)(?=<=|>=|==|!=|>|<| in| not| is)|len\(@\.(.*?)\)")
56+ REP_FILTER_CONTENT = re.compile(r"@([.\[].*?)(?=<=|>=|==|!=|>|<| in| not| is)|len\(@([.\[].*?)\)")
5757
5858 # annotations
5959 f: list
9494 # pick up special patterns
9595 expr = JSONPath.REP_GET_QUOTE.sub(self._get_quote, expr)
9696 expr = JSONPath.REP_GET_BACKQUOTE.sub(self._get_backquote, expr)
97+ expr = JSONPath.REP_GET_PAREN.sub(self._get_paren, expr)
9798 expr = JSONPath.REP_GET_BRACKET.sub(self._get_bracket, expr)
9899 expr = re.sub(r"\.(\.#B)", r"\1", expr)
99- expr = JSONPath.REP_GET_PAREN.sub(self._get_paren, expr)
100100 # split
101101 expr = JSONPath.REP_DOUBLEDOT.sub(f"{JSONPath.SEP}..{JSONPath.SEP}", expr)
102102 expr = JSONPath.REP_DOT.sub(JSONPath.SEP, expr)
103103 # put back
104- expr = JSONPath.REP_PUT_PAREN.sub(self._put_paren, expr)
105104 expr = JSONPath.REP_PUT_BRACKET.sub(self._put_bracket, expr)
105+ expr = JSONPath.REP_PUT_PAREN.sub(self._put_paren, expr)
106106 expr = JSONPath.REP_PUT_BACKQUOTE.sub(self._put_backquote, expr)
107107 expr = JSONPath.REP_PUT_QUOTE.sub(self._put_quote, expr)
108108 if expr.startswith("$;"):
147147 @staticmethod
148148 def _gen_obj(m):
149149 content = m.group(1) or m.group(2) # group 2 is for len()
150- ret = "__obj"
151- for e in content.split("."):
152- if len(e) >= 2 and ((e[0] == "'" and e[-1] == "'") or (e[0] == '"' and e[-1] == '"')):
153- e = e[1:-1]
154- ret += f'["{e}"]'
155- return ret
156150
151+ def repl(m):
152+ g = m.group(1)
153+ if g[0] in ("'", '"'):
154+ return f"[{g}]"
155+ return f"['{g}']"
156+
157+ content = re.sub(r"\.(\w+|'[^']*'|\"[^\"]*\")", repl, content)
158+ return "__obj" + content
159+
157160 @staticmethod
158161 def _traverse(f, obj, i: int, path: str, *args):
159162 if isinstance(obj, list):
275278 if step.startswith("?(") and step.endswith(")"):
276279 step = step[2:-1]
277280 step = JSONPath.REP_FILTER_CONTENT.sub(self._gen_obj, step)
281+ if isinstance(obj, dict):
282+ self._filter(obj, i + 1, path, step)
278283 self._traverse(self._filter, obj, i + 1, path, step)
279284 return
280285

The check that tells the two apart

failpass·tests/test_issues.py::test_issue_15_bracket_notation_in_filter

Check file tests/test_issues.py, taken without changes from the fix and copied onto the older code, so the exact same check runs against both versions.

Origin and history

The code before it6caa9d4e0e9a95363edc6024b41d5b8ea5e785c0
Broken version dated2025-11-23
Modulejsonpath.jsonpath
Units changedJSONPath
Fingerprint84cf1610334e7f71
Checked2026-08-18 by goldset/0.1

Every field above is generated by our program. None of it is written by hand.

Other bugs found in sean2077/jsonpath-python