1 import sys
2 from itertools import izip, repeat, chain as ichain
3
4 from dispatch import strategy, functions
5
6
8
9 """Generic function allowing a priori method ordering."""
10
12 functions.GenericFunction.__init__(self, func)
13 self.order_when = []
14 self.order_around = []
15
16 - def when(self, cond, order=0):
17 if order not in self.order_when:
18 self.order_when.append(order)
19 self.order_when.sort()
20 return self._decorate(cond, "primary%d" % order)
21
22 - def around(self, cond, order=0):
23 if order not in self.order_around:
24 self.order_around.append(order)
25 self.order_around.sort()
26 return self._decorate(cond, "around%d" % order)
27
28
30 strict = [strategy.ordered_signatures,strategy.safe_methods]
31 loose = [strategy.ordered_signatures,strategy.all_methods]
32
33 primary_names = ['primary%d' % order for order in self.order_when]
34 around_names = ['around%d' % order for order in self.order_around]
35
36 cases = strategy.separate_qualifiers(
37 cases,
38 before = loose, after =loose,
39 **dict(izip(ichain(primary_names, around_names), repeat(strict)))
40 )
41
42 primary = strategy.method_chain(ichain(
43 *[cases.get(primary, []) for primary in primary_names]))
44
45 if cases.get('after') or cases.get('before'):
46
47 befores = strategy.method_list(cases.get('before',[]))
48 afters = strategy.method_list(list(cases.get('after',[]))[::-1])
49
50 def chain(*args,**kw):
51 for tmp in befores(*args,**kw): pass
52 result = primary(*args,**kw)
53 for tmp in afters(*args,**kw): pass
54 return result
55
56 else:
57 chain = primary
58
59 if (self.order_around):
60 chain = strategy.method_chain(ichain(*([cases.get(around, [])
61 for around in around_names] + [[chain]])))
62
63 return chain
64
65
67 """Create an accessor for given variable."""
68 frame = sys._getframe(1)
69 return lambda: var in frame.f_locals and frame.f_locals[var] or \
70 frame.f_globals[var]
71
72 __all__ = ["MultiorderGenericFunction", "getter", ]
73