~ubuntu-branches/debian/jessie/sqlalchemy/jessie

« back to all changes in this revision

Viewing changes to test/lib/exclusions.py

  • Committer: Package Import Robot
  • Author(s): Piotr Ożarowski, Jakub Wilk, Piotr Ożarowski
  • Date: 2013-07-06 20:53:52 UTC
  • mfrom: (1.4.23) (16.1.17 experimental)
  • Revision ID: package-import@ubuntu.com-20130706205352-ryppl1eto3illd79
Tags: 0.8.2-1
[ Jakub Wilk ]
* Use canonical URIs for Vcs-* fields.

[ Piotr Ożarowski ]
* New upstream release
* Upload to unstable
* Build depend on python3-all instead of -dev, extensions are not built for
  Python 3.X 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
import operator
2
 
from nose import SkipTest
3
 
from sqlalchemy.util import decorator
4
 
from test.bootstrap import config
5
 
from sqlalchemy import util
6
 
 
7
 
 
8
 
def fails_if(predicate, reason=None):
9
 
    predicate = _as_predicate(predicate)
10
 
 
11
 
    @decorator
12
 
    def decorate(fn, *args, **kw):
13
 
        if not predicate():
14
 
            return fn(*args, **kw)
15
 
        else:
16
 
            try:
17
 
                fn(*args, **kw)
18
 
            except Exception, ex:
19
 
                print ("'%s' failed as expected (%s): %s " % (
20
 
                    fn.__name__, predicate, str(ex)))
21
 
                return True
22
 
            else:
23
 
                raise AssertionError(
24
 
                    "Unexpected success for '%s' (%s)" %
25
 
                    (fn.__name__, predicate))
26
 
    return decorate
27
 
 
28
 
def skip_if(predicate, reason=None):
29
 
    predicate = _as_predicate(predicate)
30
 
 
31
 
    @decorator
32
 
    def decorate(fn, *args, **kw):
33
 
        if predicate():
34
 
            if reason:
35
 
                msg = "'%s' : %s" % (
36
 
                        fn.__name__,
37
 
                        reason
38
 
                    )
39
 
            else:
40
 
                msg = "'%s': %s" % (
41
 
                        fn.__name__, predicate
42
 
                    )
43
 
            raise SkipTest(msg)
44
 
        else:
45
 
            return fn(*args, **kw)
46
 
    return decorate
47
 
 
48
 
def only_if(predicate, reason=None):
49
 
    predicate = _as_predicate(predicate)
50
 
    return skip_if(NotPredicate(predicate), reason)
51
 
 
52
 
def succeeds_if(predicate, reason=None):
53
 
    predicate = _as_predicate(predicate)
54
 
    return fails_if(NotPredicate(predicate), reason)
55
 
 
56
 
class Predicate(object):
57
 
    @classmethod
58
 
    def as_predicate(cls, predicate):
59
 
        if isinstance(predicate, Predicate):
60
 
            return predicate
61
 
        elif isinstance(predicate, list):
62
 
            return OrPredicate([cls.as_predicate(pred) for pred in predicate])
63
 
        elif isinstance(predicate, tuple):
64
 
            return SpecPredicate(*predicate)
65
 
        elif isinstance(predicate, basestring):
66
 
            return SpecPredicate(predicate, None, None)
67
 
        elif util.callable(predicate):
68
 
            return LambdaPredicate(predicate)
69
 
        else:
70
 
            assert False, "unknown predicate type: %s" % predicate
71
 
 
72
 
class SpecPredicate(Predicate):
73
 
    def __init__(self, db, op=None, spec=None, description=None):
74
 
        self.db = db
75
 
        self.op = op
76
 
        self.spec = spec
77
 
        self.description = description
78
 
 
79
 
    _ops = {
80
 
            '<': operator.lt,
81
 
             '>': operator.gt,
82
 
             '==': operator.eq,
83
 
             '!=': operator.ne,
84
 
             '<=': operator.le,
85
 
             '>=': operator.ge,
86
 
             'in': operator.contains,
87
 
             'between': lambda val, pair: val >= pair[0] and val <= pair[1],
88
 
             }
89
 
 
90
 
    def __call__(self, engine=None):
91
 
        if engine is None:
92
 
            engine = config.db
93
 
 
94
 
        if "+" in self.db:
95
 
            dialect, driver = self.db.split('+')
96
 
        else:
97
 
            dialect, driver = self.db, None
98
 
 
99
 
        if dialect and engine.name != dialect:
100
 
            return False
101
 
        if driver is not None and engine.driver != driver:
102
 
            return False
103
 
 
104
 
        if self.op is not None:
105
 
            assert driver is None, "DBAPI version specs not supported yet"
106
 
 
107
 
            version = _server_version()
108
 
            oper = hasattr(self.op, '__call__') and self.op \
109
 
                        or self._ops[self.op]
110
 
            return oper(version, self.spec)
111
 
        else:
112
 
            return True
113
 
 
114
 
    def _as_string(self, negate=False):
115
 
        if self.description is not None:
116
 
            return self.description
117
 
        elif self.op is None:
118
 
            if negate:
119
 
                return "not %s" % self.db
120
 
            else:
121
 
                return "%s" % self.db
122
 
        else:
123
 
            if negate:
124
 
                return "not %s %s %s" % (
125
 
                        self.db,
126
 
                        self.op,
127
 
                        self.spec
128
 
                    )
129
 
            else:
130
 
                return "%s %s %s" % (
131
 
                        self.db,
132
 
                        self.op,
133
 
                        self.spec
134
 
                    )
135
 
 
136
 
    def __str__(self):
137
 
        return self._as_string()
138
 
 
139
 
class LambdaPredicate(Predicate):
140
 
    def __init__(self, lambda_, description=None, args=None, kw=None):
141
 
        self.lambda_ = lambda_
142
 
        self.args = args or ()
143
 
        self.kw = kw or {}
144
 
        if description:
145
 
            self.description = description
146
 
        elif lambda_.__doc__:
147
 
            self.description = lambda_.__doc__
148
 
        else:
149
 
            self.description = "custom function"
150
 
 
151
 
    def __call__(self):
152
 
        return self.lambda_(*self.args, **self.kw)
153
 
 
154
 
    def _as_string(self, negate=False):
155
 
        if negate:
156
 
            return "not " + self.description
157
 
        else:
158
 
            return self.description
159
 
 
160
 
    def __str__(self):
161
 
        return self._as_string()
162
 
 
163
 
class NotPredicate(Predicate):
164
 
    def __init__(self, predicate):
165
 
        self.predicate = predicate
166
 
 
167
 
    def __call__(self, *arg, **kw):
168
 
        return not self.predicate(*arg, **kw)
169
 
 
170
 
    def __str__(self):
171
 
        return self.predicate._as_string(True)
172
 
 
173
 
class OrPredicate(Predicate):
174
 
    def __init__(self, predicates, description=None):
175
 
        self.predicates = predicates
176
 
        self.description = description
177
 
 
178
 
    def __call__(self, *arg, **kw):
179
 
        for pred in self.predicates:
180
 
            if pred(*arg, **kw):
181
 
                self._str = pred
182
 
                return True
183
 
        return False
184
 
 
185
 
    _str = None
186
 
 
187
 
    def _eval_str(self, negate=False):
188
 
        if self._str is None:
189
 
            if negate:
190
 
                conjunction = " and "
191
 
            else:
192
 
                conjunction = " or "
193
 
            return conjunction.join(p._as_string(negate=negate)
194
 
                            for p in self.predicates)
195
 
        else:
196
 
            return self._str._as_string(negate=negate)
197
 
 
198
 
    def _negation_str(self):
199
 
        if self.description is not None:
200
 
            return "Not " + (self.description % {"spec": self._str})
201
 
        else:
202
 
            return self._eval_str(negate=True)
203
 
 
204
 
    def _as_string(self, negate=False):
205
 
        if negate:
206
 
            return self._negation_str()
207
 
        else:
208
 
            if self.description is not None:
209
 
                return self.description % {"spec": self._str}
210
 
            else:
211
 
                return self._eval_str()
212
 
 
213
 
    def __str__(self):
214
 
        return self._as_string()
215
 
 
216
 
_as_predicate = Predicate.as_predicate
217
 
 
218
 
def _is_excluded(db, op, spec):
219
 
    return SpecPredicate(db, op, spec)()
220
 
 
221
 
def _server_version(bind=None):
222
 
    """Return a server_version_info tuple."""
223
 
 
224
 
    if bind is None:
225
 
        bind = config.db
226
 
 
227
 
    # force metadata to be retrieved
228
 
    conn = bind.connect()
229
 
    version = getattr(bind.dialect, 'server_version_info', ())
230
 
    conn.close()
231
 
    return version
232
 
 
233
 
def db_spec(*dbs):
234
 
    return OrPredicate(
235
 
            Predicate.as_predicate(db) for db in dbs
236
 
        )
237
 
 
238
 
@decorator
239
 
def future(fn, *args, **kw):
240
 
    return fails_if(LambdaPredicate(fn, *args, **kw), "Future feature")
241
 
 
242
 
def fails_on(db, reason):
243
 
    return fails_if(SpecPredicate(db), reason)
244
 
 
245
 
def fails_on_everything_except(*dbs):
246
 
    return succeeds_if(
247
 
                OrPredicate([
248
 
                    SpecPredicate(db) for db in dbs
249
 
                    ])
250
 
            )
251
 
 
252
 
def skip(db, reason):
253
 
    return skip_if(SpecPredicate(db), reason)
254
 
 
255
 
def only_on(dbs, reason):
256
 
    return only_if(
257
 
            OrPredicate([SpecPredicate(db) for db in util.to_list(dbs)])
258
 
    )
259
 
 
260
 
 
261
 
def exclude(db, op, spec, reason):
262
 
    return skip_if(SpecPredicate(db, op, spec), reason)
263
 
 
264
 
 
265
 
def against(*queries):
266
 
    return OrPredicate([
267
 
                Predicate.as_predicate(query)
268
 
                for query in queries
269
 
            ])()