changeset 1347:aaa88d805aac

Refactory composite() to smaller functions
author Thinker K.F. Li <thinker@codemud.net>
date Sat, 12 Feb 2011 18:21:16 +0800
parents 4fdc998d3dc3
children 22a79dcbaec6
files pyink/trait.py
diffstat 1 files changed, 75 insertions(+), 52 deletions(-) [+]
line wrap: on
line diff
--- a/pyink/trait.py	Sat Feb 12 17:55:12 2011 +0800
+++ b/pyink/trait.py	Sat Feb 12 18:21:16 2011 +0800
@@ -88,62 +88,16 @@
     
     return derived
 
-## \brief A decorator to make class composited from traits.
-#
-# The class decorated by composite must own a use_traits attribute.
-#
-# \verbatim
-# @trait
-# class trait_a(object):
-#   var_a = require
-#   def xxx(self): return self.var_a
-#
-# @trait
-# class trait_b(object):
-#   def ooo(self): pass
-#
-# @composite
-# class foo(object):
-#    use_traits = (trait_a, trait_b)
-#
-#    var_a = 'value of var_a'
-#    pass
-#
-# obj = foo()
-# \endverbatim
+
+## \brief Handle explicity providing for requires.
 #
-# To make a class from a set of traits.  You must decorate the class
-# with the decorator 'composite'.  The class must has an attribute,
-# named use_traits, to provide a list or tuple of traits.
-#
-# Class that defines a trait must decorated with the decorator
-# 'trait'.  If the trait need to access state (varaibles) of the
-# intances of composition class, it must define attributes with value
-# 'require', likes what 'var_a' of trait_a does.  Then, the attributes
-# would be mapped to corresponding attributes of instances of
-# composition class.  For example, when you call obj.xxx(), it returns
-# value of 'var_a', and attribute 'var_a' is a property that returns
-# the value of 'var_a' of 'obj', an instance of class foo.
+# Composite maps require attributes of traits to the attribute, with
+# the same name, of composition class by default.  But, composition
+# class can specify name of the attribute that will satisfy a require.
 #
-# By default, traits map attribute 'var_a' to 'var_a' of instances of
-# composition classes.  But, you can change it by specifying the map
-# in an attribute, named 'provide_traits', defined in composition
-# class.  The attribute provide_traits is a dictionary mapping from
-# trait class to a dictionary, named 'attrname_map' for the trait.
-# The attrname_map maps require attributes of the trait to names of
-# attributes of instances of the composition class.
-#
-def composite(clazz):
-    if not hasattr(clazz, 'use_traits'):
-        raise KeyError, \
-            '%s has no use_trait: it must be a list of traits' % (repr(clazz))
+def _handle_provide_traits(clazz):
     traits = clazz.use_traits
     
-    for a_trait in traits:
-        if not hasattr(a_trait, '_is_trait'):
-            raise TypeError, '%s is not a trait' % (repr(a_trait))
-        pass
-
     #
     # Check content of clazz.provide_traits
     #
@@ -168,6 +122,13 @@
                 pass
             pass
         pass
+    pass
+
+
+## \brief Include methods from trait for a composition class.
+#
+def _include_methods(clazz):
+    traits = clazz.use_traits
     
     #
     # Count number of appearing in all traits for every attribute name.
@@ -249,6 +210,68 @@
             setattr(clazz, attrname, proxy)
             pass
         pass
+    pass
+
+
+## \brief A decorator to make class composited from traits.
+#
+# The class decorated by composite must own a use_traits attribute.
+#
+# \verbatim
+# @trait
+# class trait_a(object):
+#   var_a = require
+#   def xxx(self): return self.var_a
+#
+# @trait
+# class trait_b(object):
+#   def ooo(self): pass
+#
+# @composite
+# class foo(object):
+#    use_traits = (trait_a, trait_b)
+#
+#    var_a = 'value of var_a'
+#    pass
+#
+# obj = foo()
+# \endverbatim
+#
+# To make a class from a set of traits.  You must decorate the class
+# with the decorator 'composite'.  The class must has an attribute,
+# named use_traits, to provide a list or tuple of traits.
+#
+# Class that defines a trait must decorated with the decorator
+# 'trait'.  If the trait need to access state (varaibles) of the
+# intances of composition class, it must define attributes with value
+# 'require', likes what 'var_a' of trait_a does.  Then, the attributes
+# would be mapped to corresponding attributes of instances of
+# composition class.  For example, when you call obj.xxx(), it returns
+# value of 'var_a', and attribute 'var_a' is a property that returns
+# the value of 'var_a' of 'obj', an instance of class foo.
+#
+# By default, traits map attribute 'var_a' to 'var_a' of instances of
+# composition classes.  But, you can change it by specifying the map
+# in an attribute, named 'provide_traits', defined in composition
+# class.  The attribute provide_traits is a dictionary mapping from
+# trait class to a dictionary, named 'attrname_map' for the trait.
+# The attrname_map maps require attributes of the trait to names of
+# attributes of instances of the composition class.
+#
+def composite(clazz):
+    if not hasattr(clazz, 'use_traits'):
+        raise KeyError, \
+            '%s has no use_trait: it must be a list of traits' % (repr(clazz))
+    traits = clazz.use_traits
+    
+    for a_trait in traits:
+        if not hasattr(a_trait, '_is_trait'):
+            raise TypeError, '%s is not a trait' % (repr(a_trait))
+        pass
+
+    _handle_provide_traits(clazz)
+    
+    _include_methods(clazz)
     
     return clazz