Mercurial > MadButterfly
annotate pyink/trait.py @ 1351:1a4d15fe2c62
Fix the issue for name confliction between two used traits.
- When a class use two or more traits, and the name of a method from
one trait conflicts with an attribute from another one, composite
will be fault for setting method proxys.
- Solution is to skip attributes that is not callable when setting
proxys.
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Sun, 13 Feb 2011 10:04:33 +0800 |
parents | b0e54ae756f8 |
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 | 264 # \verbatim |
265 # @composite | |
266 # class foo(object): | |
267 # use_trait = (trait_a, trait_b) | |
268 # provide_traits = {trait_a.var_a: 'var_foo'} | |
269 # | |
270 # var_foo = 'value of var_foo' | |
271 # pass | |
272 # \endverbatim | |
273 # | |
274 # Like mapping require attributes of used traits, there is a map, | |
275 # named method_map_traits, for methods of used traits. | |
276 # | |
277 # \verbatim | |
278 # @composite | |
279 # class foo(object): | |
280 # use_trait = (trait_a, trait_b) | |
281 # provide_traits = {trait_a.var_a: 'var_foo'} | |
282 # method_map_traits = {trait_a.xxx: 'hello') | |
283 # | |
284 # var_foo = 'value of var_foo' | |
285 # pass | |
286 # \endverbatim | |
287 # | |
288 # Previous example maps trait_a.xxx method to foo.hello method. | |
289 # composite does not include methods that has a name prefixed by a '_' | |
290 # charater. But, you can still force it, by an explicity mapping in | |
291 # method_map_traits, to include a method prefixed by a '_' character. | |
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 |