1
# -*- test-case-name: imagination.test -*-
4
from twisted.python import reflect, log, util as tputil
5
from imagination.facets import Faceted
10
def lazy(adapter, kw):
11
def doLazyAdapt(original):
12
return adapter(original, **kw)
16
def lazyApply(interface, methodName, args, kw):
17
def doLazyApply(original):
18
component = interface(original)
19
return getattr(component, methodName)(*args, **kw)
25
A facilitate creation of templates. Do something like this.
27
SomeThing = thingTemplateInstance[
28
IFoo: iFooAdapterFactory,
29
(IBar, IBaz): wrc(iMultiFactory, arg1, arg2),
31
# 'template' will then be a callable object
32
someThing = SomeThing()
33
IFoo(someThing) -> iFooAdapter
36
ObjectFactory = Faceted
38
def __init__(self, templateList=None, templateMap=None, order=None):
39
"""Create a new template.
41
@param templateList: A list of two-tuples. The first element
42
of each two-tuple must be a tuple consisting of only Interface
43
subclasses. The second element of each two-tuple must be a
44
one-argument callable which will be called with an object to
45
be adapted and which will return a component implementing all
46
of the Interfaces present in the first element of the
49
if templateMap is None:
51
self.templateMap = templateMap
56
for (ifaces, adapter) in templateList:
57
self.order.extend(ifaces)
59
self.templateMap[iface] = (ifaces, adapter)
61
def __getitem__(self, items):
62
"""Create a new ThingTemplate based on, but not identical to, this one.
64
map = self.templateMap.copy()
66
if not isinstance(items, (list, tuple)):
71
if not isinstance(ifaces, (list, tuple)):
75
previousGroup = map[iface][0]
76
for prevIface in previousGroup:
77
if prevIface not in ifaces:
79
"Interfaces in a group must be changed "
80
"all at once or not at all: %s not in %s"
81
% (prevIface, ifaces))
84
map[iface] = (ifaces, adapter)
85
return ThingTemplate(templateMap=map, order=order)
87
def fill(self, interfaces, **kw):
88
if not isinstance(interfaces, (list, tuple)):
89
interfaces = [interfaces]
90
map = self.templateMap.copy()
92
for iface in interfaces:
93
for identicalIface in map.get(iface, ((),))[0]:
94
ifmap[identicalIface] = 1
95
interfaces = ifmap.keys()
97
for iface in interfaces:
98
map[iface] = (map[iface][0], lazy(map[iface][1], kw))
99
return ThingTemplate(templateMap=map, order=order)
101
def apply(self, methodClass, methodName, *args, **kw):
102
map = self.templateMap.copy()
103
order = self.order[:]
105
lazyApply(methodClass, methodName, args, kw))
106
return ThingTemplate(templateMap=map, order=order)
109
return self.__getitem__(())
113
Instantiate the template.
115
o = self.ObjectFactory()
117
for iface in self.order:
118
if isinstance(iface, types.FunctionType):
119
## Apply a lazy method invocation
124
value = self.templateMap[iface]
125
if isinstance(value, types.FunctionType):
126
## Apply a lazy component construction
130
ifaces, adapter = value
140
baseTemplate = ThingTemplate()