[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnue] r9962 - trunk/gnue-common/src/base
From: |
reinhard |
Subject: |
[gnue] r9962 - trunk/gnue-common/src/base |
Date: |
Mon, 12 Oct 2009 15:32:31 -0500 (CDT) |
Author: reinhard
Date: 2009-10-12 15:32:31 -0500 (Mon, 12 Oct 2009)
New Revision: 9962
Modified:
trunk/gnue-common/src/base/tree.py
Log:
Added option to allow/disallow None values for attribs.
Modified: trunk/gnue-common/src/base/tree.py
===================================================================
--- trunk/gnue-common/src/base/tree.py 2009-10-12 19:38:44 UTC (rev 9961)
+++ trunk/gnue-common/src/base/tree.py 2009-10-12 20:32:31 UTC (rev 9962)
@@ -668,11 +668,13 @@
_node_attribs_['color'] = {
'type': str,
'allowed_values': ['white', 'blue', 'red', 'green'],
+ 'required': False,
'default': 'white',
'label': u_("Background Color"),
'description': u_("Color on the screen")}
_node_attribs_['speed'] = {
'type': int,
+ 'required': True,
'default': 0,
'label': u_("Speed"),
'description': u_("Speed in km per hour")}
@@ -688,6 +690,11 @@
allowed_values: Limited value set for this attribute. If not included in
the dictionary, all possible values of the defined type are valid.
+ required: False means that the attribute may also be set to None, True
+ means that this is not allowed. If not included in the dictionary, it
+ defaults to False. Required attributes must be set at object initialization
+ unless a default value exists.
+
label: Short name for the attribute to present to users (e.g. in
gnue-designer).
@@ -765,10 +772,17 @@
if name is not None:
self.name = name
+ # Set attributes given in object constructor.
for (attrib, value) in kwargs.items():
self.__set_attrib__(attrib, value)
+ # Check whether all required attribs have been initialized.
+ for (attrib, definition) in self._node_attribs_.items():
+ if definition.get('required', False):
+ if self.__get_attrib__(attrib) is None:
+ raise AttribRequiredError(self, attrib)
+
# -------------------------------------------------------------------------
# Access attribs as object attributes
# -------------------------------------------------------------------------
@@ -826,7 +840,7 @@
if issubclass(target_type, NamedNode) and value is not None:
return self.__root__.__get_node_dict__(target_type)[value]
else:
- value
+ return value
# -------------------------------------------------------------------------
@@ -844,11 +858,13 @@
definition = self._node_attribs_[name]
- # TODO: Add option to allow/disallow setting to None.
+ # Check if setting to None is allowed.
+ if value is None and definition.get('required', False):
+ raise AttribRequiredError(self, name)
target_type = definition['type']
- # If this is a reference to another node, we need to store the name
+ # If this is a reference to another node, we need to store the name.
if issubclass(target_type, NamedNode):
target_type = unicode
@@ -856,15 +872,18 @@
if not isinstance(value, target_type):
value = target_type(value)
+ # Check if value is allowed.
if definition.has_key('allowed_values'):
if value not in definition['allowed_values']:
raise ValueError
+ # Call _change_foo_ method of the object.
if '_change_' + name + '_' in dir(self):
getattr(self, '_change_' + name + '_')(value)
self.__attribs[name] = value
+ # The attrib 'name' doubles as the node name.
if name == 'name':
self.__node_name__ = value
@@ -995,6 +1014,25 @@
# =============================================================================
+
+class AttribRequiredError(errors.ApplicationError):
+ """
+ The attribute is required.
+
+ A required attribute is missing at object creation or attempt to set
+ required attribute to None.
+ """
+ def __init__(self, node, attrib_name):
+ message = u_(
+ "Attribute '%(attrib_name)s' is required for node "
+ "'%(node_name)s' of of class '%(node_class)s'")
+ errors.ApplicationError.__init__(self, message % {
+ 'attrib_name': attrib_name,
+ 'node_name': unicode(node),
+ 'node_class': node.__class__.__name__})
+
+
+# =============================================================================
# Self test code
# =============================================================================
@@ -1212,10 +1250,10 @@
_allowed_children_ = {}
def _change_supervisor_(self, value):
print "Hey, %s's supervisor has changed to %s" % (self, value)
- Member._node_attribs_ = AttribNode._node_attribs_
+ Member._node_attribs_ = AttribNode._node_attribs_.copy()
Member._node_attribs_.update({
- 'rank': {'type': str},
- 'supervisor': {'type': Member}})
+ 'rank': {'type': str, 'required': True},
+ 'supervisor': {'type': Member}})
class Crew(AttribNode):
_allowed_children_ = {Member: {}}
_node_dicts_ = [Member]
@@ -1239,6 +1277,16 @@
name="Nyota Uhura",
rank="Communication Officer")])
+ # Test check of required attributes.
+ try:
+ Member(parent=crew, name='Guest')
+ except AttribRequiredError, error:
+ print "Correctly got an exception:", error
+ try:
+ crew.Spock.rank = None
+ except AttribRequiredError, error:
+ print "Correctly got an exception:", error
+
# Test attribute access for children.
print "Spock can be directly accessed:",
print crew.Spock
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnue] r9962 - trunk/gnue-common/src/base,
reinhard <=