def test_item(): data = {'a': {'b': {'c': 111}}} assert item(data, 'a', 'b', 'c') is 111 assert item(data, 'a.b', 'c') is 111 assert item(data, 'a', 'b.c') is 111 assert item(data, 'a.b.c') is 111 assert isinstance(item(data, 'x', 'b'), jrt.Undefined) assert item(data, 'x', 'b', default=999) is 999 assert item(data, 'a', 'x', default=999) is 999 assert item(data, 'x', d=999) is 999 assert item(data, 'x', d=None) is None data = {'a': [{'b': 111}, [222]]} assert item(data, 'a[0].b') is 111 assert item(data, 'a.0.b') is 111 assert item(data, 'a.0.1', d=999) is 999 assert item(data, 'a[1][0]') is 222 assert item(data, 'a.1.0') is 222 assert item({'0': 111}, '0') is 111 assert item({0: 111}, '0') is 111 undef = jrt.StrictUndefined() assert item(undef, d=999) is 999 assert item(undef, 'x', d=999) is 999 assert item({'a': undef}, 'a', d=999) is 999
def findall(data, pattern, *args, **kwargs): """Search the input for a given pattern and return any matches found If a match cannot be found, return a default instead, otherwise an empty string """ default = kwargs.get('d', jrt.StrictUndefined()) default = kwargs.get('default', default) try: matches = re.findall(pattern, data) yield matches except TypeError: if not isinstance(default, jrt.StrictUndefined): yield default
def item(root, *refs, **kwargs): """Complement to attr.""" default = kwargs.get('d', jrt.StrictUndefined()) default = kwargs.get('default', default) for ref in _split_refs(refs): try: if type(root) is list and ref.isdigit(): ref = int(ref) try: root = root[ref] except KeyError: if not ref.isdigit(): raise root = root[int(ref)] except (KeyError, jrt.UndefinedError, IndexError): return default if isinstance(root, jrt.Undefined): return default return root
def do_reduce(collection, *args, **kwargs): """Extract multi-level attributes from collection Return a generator of the results from the given attributes in the provided collection. So for multiple dictionaries such as: collection = [ {'attr': {'data': 1}}, {'attr': {'data': 2}}, {'attr': {'data': 3}} } so `do_reduce(collection, 'attr', 'data')` yields `1, 2, 3` """ default = kwargs.get('d', jrt.StrictUndefined()) default = kwargs.get('default', default) for item in collection: try: yield reduce(type(item).__getitem__, args, item) except (KeyError, TypeError): if not isinstance(default, jrt.StrictUndefined): yield default