diff --git a/jmespath/compat.py b/jmespath/compat.py index 50f8f27..6b12ccc 100644 --- a/jmespath/compat.py +++ b/jmespath/compat.py @@ -1,8 +1,8 @@ -import sys import inspect -from itertools import zip_longest +iteritems = dict.items +map = map text_type = str string_type = str diff --git a/jmespath/functions.py b/jmespath/functions.py index 11ab56a..d68ef2f 100644 --- a/jmespath/functions.py +++ b/jmespath/functions.py @@ -2,8 +2,10 @@ import json from jmespath import exceptions -from jmespath.compat import string_type as STRING_TYPE from jmespath.compat import get_methods +from jmespath.compat import iteritems +from jmespath.compat import map +from jmespath.compat import string_type as STRING_TYPE # python types -> jmespath types @@ -281,6 +283,14 @@ def _func_sort(self, arg): def _func_sum(self, arg): return sum(arg) + @signature({'types': ['object']}) + def _func_items(self, arg): + return list(map(list, iteritems(arg))) + + @signature({'types': ['array']}) + def _func_from_items(self, items): + return dict(items) + @signature({"types": ['object']}) def _func_keys(self, arg): # To be consistent with .values() @@ -346,6 +356,10 @@ def _func_max_by(self, array, expref): else: return None + @signature({'types': ['array'], 'variadic': True}) + def _func_zip(self, *arguments): + return list(map(list, zip(*arguments))) + def _create_key_func(self, expref, allowed_types, function_name): def keyfunc(x): result = expref.visit(expref.expression, x) diff --git a/tests/compliance/functions.json b/tests/compliance/functions.json index 7b55445..0ddb433 100644 --- a/tests/compliance/functions.json +++ b/tests/compliance/functions.json @@ -12,6 +12,7 @@ "empty_list": [], "empty_hash": {}, "objects": {"foo": "bar", "bar": "baz"}, + "items": [["a", "first"], ["b", "second"], ["c", "third"]], "null_key": null }, "cases": [ @@ -175,6 +176,22 @@ "expression": "floor(str)", "error": "invalid-type" }, + { + "expression": "sort_by(items(objects), &[0])", + "result": [["bar", "baz"], ["foo", "bar"]] + }, + { + "expression": "items(empty_hash)", + "result": [] + }, + { + "expression": "items(numbers)", + "error": "invalid-type" + }, + { + "expression": "from_items(items)", + "result": {"a": "first", "b": "second", "c": "third"} + }, { "expression": "length('abc')", "result": 3 @@ -189,7 +206,7 @@ }, { "expression": "length(@)", - "result": 12 + "result": 13 }, { "expression": "length(strings[0])", @@ -588,6 +605,18 @@ "comment": "function projection on single arg function", "expression": "array[].to_number(@)", "result": [-1, 3, 4, 5, 100] + }, + { + "expression": "zip(strings, numbers)", + "result": [["a", -1], ["b", 3], ["c", 4]] + }, + { + "expression": "zip(strings, numbers, decimals)", + "result": [["a", -1, 1.01], ["b", 3, 1.2], ["c", 4, -1.5]] + }, + { + "expression": "zip(str)", + "error": "invalid-type" } ] }, {