renaming to src/neco to src/nepi
[nepi.git] / src / nepi / execution / attribute.py
diff --git a/src/nepi/execution/attribute.py b/src/nepi/execution/attribute.py
new file mode 100644 (file)
index 0000000..1282dfe
--- /dev/null
@@ -0,0 +1,89 @@
+
+### Attribute Types
+class Types:
+    String  = "STRING"
+    Bool    = "BOOL"
+    Enum    = "ENUM"
+    Double  = "DOUBLE"
+    Integer = "INTEGER"
+
+### Attribute Flags
+class Flags:
+    # Attribute can be modified by the user 
+    NoFlags         = 0x00
+    # Attribute is not modifiable by the user
+    ReadOnly        = 0x01
+    # Attribute is not modifiable by the user during runtime
+    ExecReadOnly        = 0x02
+    # Attribute is an access credential
+    Credential      = 0x04
+
+class Attribute(object):
+    def __init__(self, name, help, type = Types.String,
+            flags = Flags.NoFlags, default = None, allowed = None,
+            set_hook = None):
+        self._name = name
+        self._help = help
+        self._type = type
+        self._flags = flags
+        self._allowed = allowed
+        self._default = self._value = default
+        # callback to be invoked upon changing the 
+        # attribute value
+        self.set_hook = set_hook
+
+    @property
+    def name(self):
+        return self._name
+
+    @property
+    def default(self):
+        return self._default
+
+    @property
+    def type(self):
+        return self._type
+
+    @property
+    def help(self):
+        return self._help
+
+    @property
+    def flags(self):
+        return self._flags
+
+    @property
+    def allowed(self):
+        return self._allowed
+
+    def has_flag(self, flag):
+        return (self._flags & flag) == flag
+
+    def get_value(self):
+        return self._value
+
+    def set_value(self, value):
+        valid = True
+
+        if self.type == Types.Enum:
+            valid = value in self._allowed
+        
+        valid = valid and self.is_valid_value(value)
+
+        if valid: 
+            if self.set_hook:
+                # Hook receives old value, new value
+                value = self.set_hook(self._value, value)
+
+            self._value = value
+        else:
+            raise ValueError("Invalid value %s for attribute %s" %
+                    (str(value), self.name))
+
+    value = property(get_value, set_value)
+
+    def is_valid_value(self, value):
+        """ Attribute subclasses will override this method to add 
+        adequate validation"""
+        return True
+