diff --git a/jsonpath_ng/jsonpath.py b/jsonpath_ng/jsonpath.py index 550b52c..8322bae 100644 --- a/jsonpath_ng/jsonpath.py +++ b/jsonpath_ng/jsonpath.py @@ -649,7 +649,7 @@ def _update_base(self, data, val, create): return data def filter(self, fn, data): - if data is not None: + if data is not None and isinstance(data, dict): for field in self.reified_fields(DatumInContext.wrap(data)): if field in data: if fn(data[field]): diff --git a/tests/test_jsonpath.py b/tests/test_jsonpath.py index abd105e..17170b6 100644 --- a/tests/test_jsonpath.py +++ b/tests/test_jsonpath.py @@ -188,6 +188,26 @@ def test_update(parse: Callable[[str], JSONPath], expression: str, data, update_ assert data_copy2 == expected_value +filter_test_cases = ( + # Docs examples + ("foo[*].baz", {'foo': [{'baz': 1}, {'baz': 2}]}, lambda d: True, {'foo': [{}, {}]}), + ("foo[*].baz", {'foo': [{'baz': 1}, {'baz': 2}]}, lambda d: d == 2, {'foo': [{'baz': 1}, {}]}), + # Wildcard issue fix + ("*.baz", {"flag": False, "foo": {"bar": 1, "baz": 2}}, lambda d: True, {"flag": False, "foo": {"bar": 1}}), +) + + +@pytest.mark.parametrize( + "expression, data, filter_function, expected_value", + filter_test_cases, +) +@parsers +def test_filter(parse: Callable[[str], JSONPath], expression: str, data, filter_function: Callable, expected_value): + data_copy = copy.deepcopy(data) + parse(expression).filter(filter_function, data_copy) + assert data_copy == expected_value + + find_test_cases = ( # # * (star)