Example #1
0
def search_object_non_rec(obj, path, *attrs, **attrs_value):
    res = next(search_object(obj, path, *attrs, **attrs_value))
    if res:
        p, e = res
        yield p, e
        # only next siblings and remaining next cousins, etc...
        p_cur, cur = p, e
        while cur and '/' in p_cur:
            if cur is obj:
                yield
            p_par = p_cur.rsplit('/', 1)[0]
            par = get_descendant(obj, p_par.split('/'))
            if utils.is_sequence(par):
                next_siblings = list(range(par.index(cur) + 1, len(par)))
            else:
                next_siblings = {
                    k
                    for i, k in enumerate(par.keys())
                    if i > list(par.keys()).index(cur)
                }
            for s in next_siblings:
                for ps, pe in par[s].search_non_rec(path, *attrs,
                                                    **attrs_value):
                    yield ps, pe
            p_cur, cur = p_par, cur._parent
Example #2
0
def search_object(obj, path, *attrs, **attrs_value):
    """wrapper around dpath.util with filters on attributes presence and value"""
    import dpath.util, dpath.path
    afilter = Filter(*attrs, **attrs_value) if attrs or attrs_value else None
    separator = '/'
    globlist = dpath.util.__safe_path__(path, separator)
    for path in dpath.util._inner_search(obj, globlist, '/', dirs=True):
        val = get_descendant(obj, [p[0] for p in path])
        if afilter and afilter(val):
            yield (separator.join(map(str, dpath.path.paths_only(path))), val)
Example #3
0
    def __call__(self, obj):
        test = not self.anyOf
        for k, v2 in self.attrs_value.items():
            ks, ops, ops_negate = self.attrs_ops[k]
            o = get_descendant(obj, ks)
            if o is None:
                # breaking the look we never go in the for/ELSE statement where
                # an object is potentially yielded
                test = False
                break
            elif ops and utils.is_mapping(o):
                # check if it s not a child
                for op in ops:
                    o2 = get_descendant(o, op)
                    if o2:
                        o = o2
                        ks.append(ops.pop(0))
                    else:
                        test = False
                        break
            ops = ops or ['eq']
            v = _comparable(o)
            test2 = bool(_apply_ops_test(ops, ops_negate, v, v2))
            test = (test or test2) if self.anyOf else (test and test2)
            if self.anyOf:
                if test2:
                    break
            elif not test:
                break

        for k in self.attrs:
            ks = k.split('__')
            test2 = get_descendant(obj, ks) is not None
            test = (test or test2) if self.anyOf else (test and test2)
            if self.anyOf:
                if test2:
                    break
            elif not test:
                break
        # todo change
        if test is not self.negate:
            return True
        return False
Example #4
0
    def result_cache(self):
        if self._result_cache is None:
            self._result_cache = list(self._iterable)

            ob = self._order_by
            if ob:
                from .utils.utils import split_path
                ks = split_path(ob) if isinstance(ob, str) else ob
                self._result_cache = sorted(self._result_cache,
                                            lambda x: get_descendant(x, ks))
            if self._reverse:
                self._result_cache = reversed(self._result_cache)
        return self._result_cache
Example #5
0
    def _filter_or_exclude__(iterable,
                             *attrs,
                             negate=False,
                             any_of=False,
                             distinct=False,
                             **attrs_value):

        seen = set()
        attrs_ops = {}
        for k, v2 in attrs_value.items():
            ks, ops = _sort_criteria(k)
            ops_negate = 'not' in ops
            if ops_negate:
                ops.remove('not')
            attrs_ops[k] = (ks, ops, ops_negate)

        for obj in iterable:
            if not obj:
                continue
            test = not any_of
            for k, v2 in attrs_value.items():
                ks, ops, ops_negate = attrs_ops[k]
                o = get_descendant(obj, ks)
                if o is None:
                    # breaking the look we never go in the for/ELSE statement where
                    # an object is potentially yielded
                    test = False
                    break
                elif ops and utils.is_mapping(o):
                    # check if it s not a child
                    for op in ops:
                        o2 = get_descendant(o, op)
                        if o2:
                            o = o2
                            ks.append(ops.pop(0))
                        else:
                            test = False
                            break
                ops = ops or ['eq']
                v = _comparable(o)
                test2 = bool(_apply_ops_test(ops, ops_negate, v, v2))
                test = (test or test2) if any_of else (test and test2)
                if any_of:
                    if test2:
                        break
                elif not test:
                    break

            for k in attrs:
                ks = k.split('__')
                test2 = get_descendant(obj, ks) is not None
                test = (test or test2) if any_of else (test and test2)
                if any_of:
                    if test2:
                        break
                elif not test:
                    break
            if test is not negate:
                if distinct:
                    comparable = _comparable(obj)
                    if comparable not in seen:
                        seen.add(comparable)
                    else:
                        continue
                yield obj