annotate pyink/trait.py @ 1529:af8dd27bf450

Remove layer from button
author Thinker K.F. Li <thinker@codemud.net>
date Wed, 31 Aug 2011 22:30:02 +0800
parents 28769a82a72d
children
rev   line source
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
1 ## \brief Implement descriptors for mapping attributes for traits.
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
2 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
3 # The instances of require map attributes of traits to corresponding
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
4 # attributes of the instance of the composition class.
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
5 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
6 class require(object):
1348
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
7 def __init__(self, trait_clazz):
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
8 self.trait_clazz = trait_clazz
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
9 pass
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
10
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
11 def __get__(self, instance, owner):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
12 if not instance: # from a class object
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
13 return self
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
14
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
15 attrname = instance._trait_attrname_map[self]
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
16 composite_obj = instance._trait_composite_obj
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
17 val = getattr(composite_obj, attrname)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
18 return val
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
19
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
20 def __set__(self, instance, value):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
21 attrname = instance._trait_attrname_map[self]
1464
28769a82a72d Raise a maningful exception for traits that is not ready
Thinker K.F. Li <thinker@codemud.net>
parents: 1351
diff changeset
22 try:
28769a82a72d Raise a maningful exception for traits that is not ready
Thinker K.F. Li <thinker@codemud.net>
parents: 1351
diff changeset
23 composite_obj = instance._trait_composite_obj
28769a82a72d Raise a maningful exception for traits that is not ready
Thinker K.F. Li <thinker@codemud.net>
parents: 1351
diff changeset
24 except AttributeError:
28769a82a72d Raise a maningful exception for traits that is not ready
Thinker K.F. Li <thinker@codemud.net>
parents: 1351
diff changeset
25 raise RuntimeError, \
28769a82a72d Raise a maningful exception for traits that is not ready
Thinker K.F. Li <thinker@codemud.net>
parents: 1351
diff changeset
26 '%s does not finish its initialization' % (repr(instance))
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
27 setattr(composite_obj, attrname, value)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
28 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
29 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
30
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
31
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
32 ## \brief Decorator for making a class being a trait.
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
33 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
34 def trait(trait_clazz):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
35 attrname_map = {}
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
36 trait_clazz._trait_attrname_map = attrname_map
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
37
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
38 for attr in dir(trait_clazz):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
39 value = getattr(trait_clazz, attr)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
40 if value != require:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
41 continue
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
42
1348
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
43 require_o = require(trait_clazz)
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
44 setattr(trait_clazz, attr, require_o)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
45 attrname_map[require_o] = attr
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
46 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
47
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
48 trait_clazz._is_trait = True
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
49
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
50 return trait_clazz
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
51
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
52
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
53 ## \brief The function to return a proxy for a method of a trait.
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
54 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
55 def trait_method_proxy(trait_clazz, method):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
56 def trait_method_proxy_real(self, *args, **kws):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
57 if not hasattr(self, '_all_trait_objs'):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
58 # self is an instance of the class composed from traits.
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
59 self._all_trait_objs = {}
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
60 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
61
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
62 try:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
63 trait_obj = self._all_trait_objs[trait_clazz]
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
64 except KeyError:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
65 trait_obj = trait_clazz()
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
66 trait_obj._trait_composite_obj = self
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
67 self._all_trait_objs[trait_clazz] = trait_obj
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
68 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
69
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
70 r = method(trait_obj, *args, **kws)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
71
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
72 return r
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
73
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
74 return trait_method_proxy_real
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
75
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
76
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
77 ## \brief Derive and modify an existing trait.
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
78 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
79 def derive_trait(a_trait, composite_clazz):
1348
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
80 #
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
81 # Set a map mamping requires to attribute names.
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
82 #
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
83 # Search provide_traits for requires of a_trait, and patch
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
84 # attrname_map for it.
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
85 #
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
86 attrname_map = None
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
87 if hasattr(composite_clazz, 'provide_traits'):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
88 provide_traits = composite_clazz.provide_traits
1348
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
89 attrname_map = dict(a_trait._trait_attrname_map)
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
90 for req in provide_traits:
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
91 if req.trait_clazz == a_trait:
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
92 attrname_map[req] = provide_traits[req]
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
93 pass
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
94 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
95 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
96
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
97 dic = {}
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
98 if attrname_map:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
99 dic['_trait_attrname_map'] = attrname_map
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
100 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
101
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
102 derived = type('derived_trait', (a_trait,), dic)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
103
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
104 return derived
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
105
1347
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
106
1348
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
107 ## \brief Check explicity providing for requires.
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
108 #
1347
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
109 # Composite maps require attributes of traits to the attribute, with
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
110 # the same name, of composition class by default. But, composition
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
111 # class can specify name of the attribute that will satisfy a require.
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
112 #
1348
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
113 def _check_provide_traits(clazz):
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
114 traits = clazz.use_traits
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
115
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
116 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
117 # Check content of clazz.provide_traits
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
118 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
119 if hasattr(clazz, 'provide_traits'):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
120 if not isinstance(clazz.provide_traits, dict):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
121 raise TypeError, \
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
122 'provide_traits of a composite must be a dictionary'
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
123
1348
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
124 provide_set = set([req.trait_clazz
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
125 for req in clazz.provide_traits.keys()])
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
126 trait_set = set(traits)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
127 unused_set = provide_set - trait_set
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
128 if unused_set:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
129 raise ValueError, \
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
130 'can not find %s in provide_traits' % (repr(unused_set.pop()))
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
131
1348
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
132 for req in clazz.provide_traits:
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
133 if not isinstance(req, require):
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
134 raise TypeError, \
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
135 '%s is not a require: key of an ' \
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
136 'attribute name map must be a require' % (repr(req))
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
137 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
138 pass
1347
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
139 pass
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
140
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
141
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
142 ## \brief Include methods from trait for a composition class.
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
143 #
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
144 def _include_methods(clazz):
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
145 traits = clazz.use_traits
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
146
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
147 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
148 # Count number of appearing in all traits for every attribute name.
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
149 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
150 attrname_cnts = {}
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
151 for a_trait in traits:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
152 for attr in dir(a_trait):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
153 if attr.startswith('_'):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
154 continue
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
155
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
156 value = getattr(a_trait, attr)
1351
1a4d15fe2c62 Fix the issue for name confliction between two used traits.
Thinker K.F. Li <thinker@codemud.net>
parents: 1349
diff changeset
157 if isinstance(value, require) or not callable(value):
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
158 continue
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
159
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
160 attrname_cnts[attr] = attrname_cnts.setdefault(attr, 0) + 1
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
161 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
162 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
163
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
164 if hasattr(clazz, 'method_map_traits'):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
165 method_map_traits = clazz.method_map_traits
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
166 else:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
167 method_map_traits = {}
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
168 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
169
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
170 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
171 # Set a proxy for every exported methods.
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
172 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
173 derived_traits = clazz._derived_traits = {}
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
174 for a_trait in traits:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
175 derived = derive_trait(a_trait, clazz)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
176 derived_traits[a_trait] = derived
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
177
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
178 for attr in dir(derived):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
179 if attr not in attrname_cnts: # hidden
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
180 continue
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
181 if attrname_cnts[attr] > 1: # conflict
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
182 continue
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
183
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
184 if hasattr(clazz, attr): # override
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
185 continue
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
186
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
187 value = getattr(a_trait, attr)
1348
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
188 if value in method_map_traits: # do it later
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
189 continue
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
190
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
191 value = getattr(derived, attr)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
192
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
193 if not callable(value):
1351
1a4d15fe2c62 Fix the issue for name confliction between two used traits.
Thinker K.F. Li <thinker@codemud.net>
parents: 1349
diff changeset
194 continue
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
195
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
196 func = value.im_func
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
197 proxy = trait_method_proxy(derived, func)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
198 setattr(clazz, attr, proxy)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
199 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
200 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
201
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
202 #
1348
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
203 # Set a proxy for methods specified in method_map_traits.
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
204 #
1348
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
205 for method, attrname in method_map_traits.items():
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
206 if not callable(method):
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
207 raise TypeError, \
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
208 '%s.%s is not a callable' % (repr(a_trait), repr(method))
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
209
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
210 a_trait = method.im_class
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
211 if a_trait not in derived_traits:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
212 raise TypeError, \
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
213 '%s is not a trait used by the composition class' % \
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
214 (repr(a_trait))
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
215
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
216 derived = derived_traits[a_trait]
1348
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
217 func = method.im_func
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
218 proxy = trait_method_proxy(derived, func)
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
219 setattr(clazz, attrname, proxy)
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
220 pass
1347
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
221 pass
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
222
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
223
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
224 ## \brief A decorator to make class composited from traits.
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
225 #
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
226 # The class decorated by composite must own a use_traits attribute.
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
227 #
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
228 # \verbatim
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
229 # @trait
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
230 # class trait_a(object):
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
231 # var_a = require
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
232 # def xxx(self): return self.var_a
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
233 #
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
234 # @trait
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
235 # class trait_b(object):
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
236 # def ooo(self): pass
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
237 #
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
238 # @composite
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
239 # class foo(object):
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
240 # use_traits = (trait_a, trait_b)
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
241 #
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
242 # var_a = 'value of var_a'
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
243 # pass
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
244 #
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
245 # obj = foo()
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
246 # \endverbatim
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
247 #
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
248 # To make a class from a set of traits. You must decorate the class
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
249 # with the decorator 'composite'. The class must has an attribute,
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
250 # named use_traits, to provide a list or tuple of traits.
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
251 #
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
252 # Class that defines a trait must decorated with the decorator
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
253 # 'trait'. If the trait need to access state (varaibles) of the
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
254 # intances of composition class, it must define attributes with value
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
255 # 'require', likes what 'var_a' of trait_a does. Then, the attributes
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
256 # would be mapped to corresponding attributes of instances of
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
257 # composition class. For example, when you call obj.xxx(), it returns
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
258 # value of 'var_a', and attribute 'var_a' is a property that returns
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
259 # the value of 'var_a' of 'obj', an instance of class foo.
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
260 #
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
261 # By default, traits map attribute 'var_a' to 'var_a' of instances of
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
262 # composition classes. But, you can change it by specifying the map
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
263 # in an attribute, named 'provide_traits', defined in composition
1348
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
264 # class. The attribute provide_traits of a composition class is a
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
265 # dictionary mapping from require attributes of used traits to names
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
266 # of attributes of the composition class.
1347
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
267 #
1349
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
268 # \verbatim
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
269 # @composite
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
270 # class foo(object):
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
271 # use_trait = (trait_a, trait_b)
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
272 # provide_traits = {trait_a.var_a: 'var_foo'}
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
273 #
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
274 # var_foo = 'value of var_foo'
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
275 # pass
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
276 # \endverbatim
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
277 #
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
278 # Like mapping require attributes of used traits, there is a map,
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
279 # named method_map_traits, for methods of used traits.
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
280 #
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
281 # \verbatim
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
282 # @composite
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
283 # class foo(object):
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
284 # use_trait = (trait_a, trait_b)
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
285 # provide_traits = {trait_a.var_a: 'var_foo'}
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
286 # method_map_traits = {trait_a.xxx: 'hello')
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
287 #
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
288 # var_foo = 'value of var_foo'
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
289 # pass
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
290 # \endverbatim
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
291 #
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
292 # Previous example maps trait_a.xxx method to foo.hello method.
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
293 # composite does not include methods that has a name prefixed by a '_'
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
294 # charater. But, you can still force it, by an explicity mapping in
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
295 # method_map_traits, to include a method prefixed by a '_' character.
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
296 #
1347
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
297 def composite(clazz):
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
298 if not hasattr(clazz, 'use_traits'):
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
299 raise KeyError, \
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
300 '%s has no use_trait: it must be a list of traits' % (repr(clazz))
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
301 traits = clazz.use_traits
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
302
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
303 for a_trait in traits:
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
304 if not hasattr(a_trait, '_is_trait'):
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
305 raise TypeError, '%s is not a trait' % (repr(a_trait))
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
306 pass
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
307
1348
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
308 _check_provide_traits(clazz)
1347
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
309
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
310 _include_methods(clazz)
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
311
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
312 return clazz
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
313
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
314
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
315 if __name__ == '__main__':
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
316 @trait
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
317 class hello(object):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
318 msg = require
1351
1a4d15fe2c62 Fix the issue for name confliction between two used traits.
Thinker K.F. Li <thinker@codemud.net>
parents: 1349
diff changeset
319 bye_provide = require
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
320
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
321 def hello(self, name):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
322 return self.msg + ' hello ' + name
1351
1a4d15fe2c62 Fix the issue for name confliction between two used traits.
Thinker K.F. Li <thinker@codemud.net>
parents: 1349
diff changeset
323
1a4d15fe2c62 Fix the issue for name confliction between two used traits.
Thinker K.F. Li <thinker@codemud.net>
parents: 1349
diff changeset
324 def hello_provide(self):
1a4d15fe2c62 Fix the issue for name confliction between two used traits.
Thinker K.F. Li <thinker@codemud.net>
parents: 1349
diff changeset
325 return 'hello provide'
1a4d15fe2c62 Fix the issue for name confliction between two used traits.
Thinker K.F. Li <thinker@codemud.net>
parents: 1349
diff changeset
326
1a4d15fe2c62 Fix the issue for name confliction between two used traits.
Thinker K.F. Li <thinker@codemud.net>
parents: 1349
diff changeset
327 def require_bye(self):
1a4d15fe2c62 Fix the issue for name confliction between two used traits.
Thinker K.F. Li <thinker@codemud.net>
parents: 1349
diff changeset
328 return self.bye_provide()
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
329 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
330
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
331 @trait
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
332 class bye(object):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
333 msg = require
1351
1a4d15fe2c62 Fix the issue for name confliction between two used traits.
Thinker K.F. Li <thinker@codemud.net>
parents: 1349
diff changeset
334 hello_provide = require
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
335
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
336 def bye(self, name):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
337 return self.msg + ' bye ' + name
1351
1a4d15fe2c62 Fix the issue for name confliction between two used traits.
Thinker K.F. Li <thinker@codemud.net>
parents: 1349
diff changeset
338
1a4d15fe2c62 Fix the issue for name confliction between two used traits.
Thinker K.F. Li <thinker@codemud.net>
parents: 1349
diff changeset
339 def bye_provide(self):
1a4d15fe2c62 Fix the issue for name confliction between two used traits.
Thinker K.F. Li <thinker@codemud.net>
parents: 1349
diff changeset
340 return 'bye provide'
1a4d15fe2c62 Fix the issue for name confliction between two used traits.
Thinker K.F. Li <thinker@codemud.net>
parents: 1349
diff changeset
341
1a4d15fe2c62 Fix the issue for name confliction between two used traits.
Thinker K.F. Li <thinker@codemud.net>
parents: 1349
diff changeset
342 def require_hello(self):
1a4d15fe2c62 Fix the issue for name confliction between two used traits.
Thinker K.F. Li <thinker@codemud.net>
parents: 1349
diff changeset
343 return self.hello_provide()
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
344 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
346 @composite
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
347 class hello_bye(object):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
348 use_traits = (hello, bye)
1348
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
349 provide_traits = {hello.msg: 'msg1'}
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
350 method_map_traits = {hello.hello: 'hello1'}
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
351
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
352 msg = 'hello_bye'
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
353 msg1 = 'hello_bye_msg1'
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
354 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
355
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
356 o = hello_bye()
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
357 assert o.hello1('Miky') == 'hello_bye_msg1 hello Miky'
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
358 assert o.bye('Miky') == 'hello_bye bye Miky'
1351
1a4d15fe2c62 Fix the issue for name confliction between two used traits.
Thinker K.F. Li <thinker@codemud.net>
parents: 1349
diff changeset
359 assert o.require_bye() == 'bye provide'
1a4d15fe2c62 Fix the issue for name confliction between two used traits.
Thinker K.F. Li <thinker@codemud.net>
parents: 1349
diff changeset
360 assert o.require_hello() == 'hello provide'
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
361 print 'OK'
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
362 pass