File: extended.py

package info (click to toggle)
python-yaql 0.2.3-2%2Bdeb8u1
  • links: PTS, VCS
  • area: main
  • in suites: jessie
  • size: 216 kB
  • ctags: 213
  • sloc: python: 986; makefile: 31; sh: 15
file content (136 lines) | stat: -rw-r--r-- 3,580 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#    Copyright (c) 2013 Mirantis, Inc.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

import collections
import random
import types
import itertools
from yaql.context import EvalArg, ContextAware
from yaql.exceptions import YaqlExecutionException
from yaql.utils import limit


def join(self, others, join_predicate, composer):
    for self_item in self():
        for other_item in others():
            if join_predicate(self_item, other_item):
                yield composer(self_item, other_item)


def select(collection, composer):
    for item in collection():
        yield composer(item)


def _sum(this):
    return sum(this())


def _range_limited(start, end):
    for i in xrange(int(start()), int(end())):
        yield i


def _range_infinite(start):
    for i in itertools.count(start()):
        yield i


def rand():
    return random.random()


@EvalArg('self', collections.Iterable)
def take_while(self, predicate):
    for item in self:
        if predicate(item):
            yield item
        else:
            return


@EvalArg('self', types.GeneratorType)
def _list(self):
    return limit(self)


@ContextAware()
@EvalArg('levels', types.IntType)
def parent(context, levels, func):
    con = context
    traversed = 0
    while con:
        if con.data:
            traversed += 1
        if traversed > levels:
            break
        con = con.parent_context
    if con:
        context.data = con.data
    else:
        return None
    return func()


@ContextAware()
def direct_parent(context, func):
    return parent(context, 1, func)

@ContextAware()
def _as(self, context, *tuples):
    self = self()
    for t in tuples:
        tup = t(self)
        val = tup[0]
        key_name = tup[1]
        context.set_data(val, key_name)
    return self

@ContextAware()
def root(context):
    def get_not_null_data(context):
        if context.parent_context:
            data = get_not_null_data(context.parent_context)
            if data:
                return data
        return context.data
    first_data = get_not_null_data(context)
    return first_data.get('$')


def switch(self, *conditions):
    self = self()
    for cond in conditions:
        res = cond(self)
        if not isinstance(res, types.TupleType):
            raise YaqlExecutionException("Switch must have tuple parameters")
        if len(res) != 2:
            raise YaqlExecutionException("Switch tuples must be of size 2")
        if res[0]:
            return res[1]
    return None


def add_to_context(context):
    context.register_function(join, 'join')
    context.register_function(select, 'select')
    context.register_function(_sum, 'sum')
    context.register_function(_range_infinite, 'range')
    context.register_function(_range_limited, 'range')
    context.register_function(rand, 'random')
    context.register_function(_list, 'list')
    context.register_function(take_while, 'takeWhile')
    context.register_function(root, 'root')
    context.register_function(_as, 'as')
    context.register_function(switch, 'switch')