annotate pyink/trait.py @ 1457:416a18409603

Show an empty document in SVG viewer widget
author Thinker K.F. Li <thinker@codemud.net>
date Sat, 16 Apr 2011 22:25:35 +0800
parents 1a4d15fe2c62
children 28769a82a72d
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]
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
22 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
23 setattr(composite_obj, attrname, value)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
24 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
25 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
26
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
27
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
28 ## \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
29 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
30 def trait(trait_clazz):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
31 attrname_map = {}
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
32 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
33
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
34 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
35 value = getattr(trait_clazz, attr)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
36 if value != require:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
37 continue
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
38
1348
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
39 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
40 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
41 attrname_map[require_o] = attr
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
42 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
43
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
44 trait_clazz._is_trait = True
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
45
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
46 return trait_clazz
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
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
49 ## \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
50 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
51 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
52 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
53 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
54 # 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
55 self._all_trait_objs = {}
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
56 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
57
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
58 try:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
59 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
60 except KeyError:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
61 trait_obj = trait_clazz()
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
62 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
63 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
64 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
65
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
66 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
67
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
68 return r
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 return trait_method_proxy_real
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
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
73 ## \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
74 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
75 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
76 #
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
77 # 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
78 #
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
79 # 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
80 # 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
81 #
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
82 attrname_map = None
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
83 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
84 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
85 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
86 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
87 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
88 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
89 pass
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
90 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
91 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
92
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
93 dic = {}
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
94 if attrname_map:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
95 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
96 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
97
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
98 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
99
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
100 return derived
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
101
1347
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
102
1348
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
103 ## \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
104 #
1347
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
105 # 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
106 # 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
107 # 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
108 #
1348
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
109 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
110 traits = clazz.use_traits
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
111
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
112 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
113 # 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
114 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
115 if hasattr(clazz, 'provide_traits'):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
116 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
117 raise TypeError, \
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
118 '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
119
1348
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
120 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
121 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
122 trait_set = set(traits)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
123 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
124 if unused_set:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
125 raise ValueError, \
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
126 '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
127
1348
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
128 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
129 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
130 raise TypeError, \
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
131 '%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
132 '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
133 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
134 pass
1347
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
135 pass
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
136
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
137
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
138 ## \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
139 #
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
140 def _include_methods(clazz):
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
141 traits = clazz.use_traits
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
142
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
143 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
144 # 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
145 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
146 attrname_cnts = {}
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
147 for a_trait in traits:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
148 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
149 if attr.startswith('_'):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
150 continue
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
151
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
152 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
153 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
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 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
157 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
158 pass
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 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
161 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
162 else:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
163 method_map_traits = {}
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
164 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
165
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
166 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
167 # 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
168 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
169 derived_traits = clazz._derived_traits = {}
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
170 for a_trait in traits:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
171 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
172 derived_traits[a_trait] = derived
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
173
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
174 for attr in dir(derived):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
175 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
176 continue
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
177 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
178 continue
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
179
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
180 if hasattr(clazz, attr): # override
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
181 continue
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
182
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
183 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
184 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
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(derived, attr)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
188
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
189 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
190 continue
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
191
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
192 func = value.im_func
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
193 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
194 setattr(clazz, attr, proxy)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
195 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
196 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
197
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
198 #
1348
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
199 # 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
200 #
1348
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
201 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
202 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
203 raise TypeError, \
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
204 '%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
205
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
206 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
207 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
208 raise TypeError, \
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
209 '%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
210 (repr(a_trait))
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
211
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
212 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
213 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
214 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
215 setattr(clazz, attrname, proxy)
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
216 pass
1347
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
217 pass
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
218
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
219
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
220 ## \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
221 #
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
222 # 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
223 #
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
224 # \verbatim
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
225 # @trait
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
226 # class trait_a(object):
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
227 # var_a = require
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
228 # def xxx(self): return self.var_a
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
229 #
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
230 # @trait
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
231 # class trait_b(object):
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
232 # def ooo(self): pass
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 # @composite
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
235 # class foo(object):
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
236 # use_traits = (trait_a, trait_b)
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 # var_a = 'value of var_a'
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
239 # pass
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
240 #
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
241 # obj = foo()
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
242 # \endverbatim
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
243 #
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
244 # 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
245 # 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
246 # 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
247 #
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
248 # 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
249 # '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
250 # 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
251 # '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
252 # 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
253 # 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
254 # 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
255 # 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
256 #
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
257 # 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
258 # 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
259 # 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
260 # 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
261 # 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
262 # of attributes of the composition class.
1347
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
263 #
1349
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
264 # \verbatim
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
265 # @composite
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
266 # class foo(object):
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
267 # use_trait = (trait_a, trait_b)
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
268 # provide_traits = {trait_a.var_a: 'var_foo'}
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
269 #
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
270 # var_foo = 'value of var_foo'
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
271 # pass
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
272 # \endverbatim
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 # 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
275 # named method_map_traits, for methods of used traits.
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
276 #
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
277 # \verbatim
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
278 # @composite
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
279 # class foo(object):
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
280 # use_trait = (trait_a, trait_b)
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
281 # provide_traits = {trait_a.var_a: 'var_foo'}
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
282 # method_map_traits = {trait_a.xxx: 'hello')
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
283 #
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
284 # var_foo = 'value of var_foo'
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
285 # pass
b0e54ae756f8 More doc
Thinker K.F. Li <thinker@codemud.net>
parents: 1348
diff changeset
286 # \endverbatim
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 # 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
289 # 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
290 # 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
291 # 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
292 #
1347
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
293 def composite(clazz):
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
294 if not hasattr(clazz, 'use_traits'):
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
295 raise KeyError, \
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
296 '%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
297 traits = clazz.use_traits
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
298
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
299 for a_trait in traits:
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
300 if not hasattr(a_trait, '_is_trait'):
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
301 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
302 pass
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
303
1348
22a79dcbaec6 Change structure of provide_traits and method_map_traits
Thinker K.F. Li <thinker@codemud.net>
parents: 1347
diff changeset
304 _check_provide_traits(clazz)
1347
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
305
aaa88d805aac Refactory composite() to smaller functions
Thinker K.F. Li <thinker@codemud.net>
parents: 1346
diff changeset
306 _include_methods(clazz)
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
307
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
308 return clazz
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
309
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
310
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
311 if __name__ == '__main__':
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
312 @trait
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
313 class hello(object):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
314 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
315 bye_provide = require
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
316
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
317 def hello(self, name):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
318 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
319
1a4d15fe2c62 Fix the issue for name confliction between two used traits.
Thinker K.F. Li <thinker@codemud.net>
parents: 1349
diff changeset
320 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
321 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
322
1a4d15fe2c62 Fix the issue for name confliction between two used traits.
Thinker K.F. Li <thinker@codemud.net>
parents: 1349
diff changeset
323 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
324 return self.bye_provide()
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
325 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
326
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
327 @trait
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
328 class bye(object):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
329 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
330 hello_provide = require
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
331
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
332 def bye(self, name):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
333 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
334
1a4d15fe2c62 Fix the issue for name confliction between two used traits.
Thinker K.F. Li <thinker@codemud.net>
parents: 1349
diff changeset
335 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
336 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
337
1a4d15fe2c62 Fix the issue for name confliction between two used traits.
Thinker K.F. Li <thinker@codemud.net>
parents: 1349
diff changeset
338 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
339 return self.hello_provide()
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
340 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
341
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
342 @composite
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
343 class hello_bye(object):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
344 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
345 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
346 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
347
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
348 msg = 'hello_bye'
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
349 msg1 = 'hello_bye_msg1'
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
350 pass
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 o = hello_bye()
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
353 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
354 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
355 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
356 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
357 print 'OK'
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
358 pass