Mercurial > MadButterfly
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 | 268 # \verbatim |
269 # @composite | |
270 # class foo(object): | |
271 # use_trait = (trait_a, trait_b) | |
272 # provide_traits = {trait_a.var_a: 'var_foo'} | |
273 # | |
274 # var_foo = 'value of var_foo' | |
275 # pass | |
276 # \endverbatim | |
277 # | |
278 # Like mapping require attributes of used traits, there is a map, | |
279 # named method_map_traits, for methods of used traits. | |
280 # | |
281 # \verbatim | |
282 # @composite | |
283 # class foo(object): | |
284 # use_trait = (trait_a, trait_b) | |
285 # provide_traits = {trait_a.var_a: 'var_foo'} | |
286 # method_map_traits = {trait_a.xxx: 'hello') | |
287 # | |
288 # var_foo = 'value of var_foo' | |
289 # pass | |
290 # \endverbatim | |
291 # | |
292 # Previous example maps trait_a.xxx method to foo.hello method. | |
293 # composite does not include methods that has a name prefixed by a '_' | |
294 # charater. But, you can still force it, by an explicity mapping in | |
295 # method_map_traits, to include a method prefixed by a '_' character. | |
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 |