Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src/sugar/tutorius/constraints.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/sugar/tutorius/constraints.py')
-rw-r--r--src/sugar/tutorius/constraints.py189
1 files changed, 189 insertions, 0 deletions
diff --git a/src/sugar/tutorius/constraints.py b/src/sugar/tutorius/constraints.py
new file mode 100644
index 0000000..a666ecb
--- /dev/null
+++ b/src/sugar/tutorius/constraints.py
@@ -0,0 +1,189 @@
+# Copyright (C) 2009, Tutorius.org
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+"""
+Constraints
+
+Defines a set of constraints with their related errors. These constraints are
+made to be used inside TutoriusProperties in order to limit the values that
+they might take. They can also be used to enforce a particular format or type
+for some properties.
+"""
+
+# For the File Constraint
+import os
+
+class Constraint():
+ """
+ Basic block for defining constraints on a TutoriusProperty. Every class
+ inheriting from Constraint will have a validate function that will be
+ executed when the property's value is to be changed.
+ """
+ def validate(self, value):
+ """
+ This function receives the value that is proposed as a new value for
+ the property. It needs to raise an Error in the case where the value
+ does not respect this constraint.
+ """
+ raise NotImplementedError("Unable to validate a base Constraint")
+
+class ValueConstraint(Constraint):
+ """
+ A value constraint contains a _limit member that can be used in a children
+ class as a basic value. See UpperLimitConstraint for an exemple.
+ """
+ def __init__(self, limit):
+ self.limit = limit
+
+class UpperLimitConstraintError(Exception):
+ pass
+
+class UpperLimitConstraint(ValueConstraint):
+ def validate(self, value):
+ """
+ Evaluates whether the given value is smaller than the limit.
+
+ @raise UpperLimitConstraintError When the value is strictly higher than
+ the limit.
+ """
+ if self.limit is not None:
+ if self.limit >= value:
+ return
+ raise UpperLimitConstraintError()
+ return
+
+class LowerLimitConstraintError(Exception):
+ pass
+
+class LowerLimitConstraint(ValueConstraint):
+ def validate(self, value):
+ """
+ If the value is lower than the limit, this function raises an error.
+
+ @raise LowerLimitConstraintError When the value is strictly smaller
+ than the limit.
+ """
+ if self.limit is not None:
+ if value >= self.limit:
+ return
+ raise LowerLimitConstraintError()
+ return
+
+class SizeConstraintError(Exception):
+ pass
+
+class SizeConstraint(ValueConstraint):
+ def validate(self, value):
+ """
+ Evaluate whether a given object is smaller than the given size when
+ run through len(). Great for string, lists and the like. ;)
+
+ @raise SizeConstraintError If the length of the value is strictly
+ bigger than the limit.
+ """
+ if self.limit is not None:
+ if self.limit > len(value):
+ return
+ raise SizeConstraintError("Setter : trying to set value of length %d while limit is %d"%(len(value), self.limit))
+ return
+
+class ColorConstraintError(Exception):
+ pass
+
+class ColorArraySizeError(ColorConstraintError):
+ pass
+
+class ColorTypeError(ColorConstraintError):
+ pass
+
+class ColorValueError(ColorConstraintError):
+ pass
+
+class ColorConstraint(Constraint):
+ """
+ Validates that the value is an array of size 3 with three numbers between
+ 0 and 255 (inclusively) in it.
+
+ """
+ def validate(self, value):
+ if len(value) != 3:
+ raise ColorArraySizeError("The value is not an array of size 3")
+
+ if not (type(value[0]) == type(22) and type(value[1]) == type(22) and type(value[2]) == type(22)):
+ raise ColorTypeError("Not all the elements of the array are integers")
+
+ if value[0] > 255 or value[0] <0:
+ raise ColorValueError("Red value is not between 0 and 255")
+
+ if value[1] > 255 or value[1] <0:
+ raise ColorValueError("Green value is not between 0 and 255")
+
+ if value[2] > 255 or value[2] <0:
+ raise ColorValueError("Blue value is not between 0 and 255")
+
+ return
+
+class BooleanConstraintError(Exception):
+ pass
+
+class BooleanConstraint(Constraint):
+ """
+ Validates that the value is either True or False.
+ """
+ def validate(self, value):
+ if value == True or value == False:
+ return
+ raise BooleanConstraintError("Value is not True or False")
+
+class EnumConstraintError(Exception):
+ pass
+
+class EnumConstraint(Constraint):
+ """
+ Validates that the value is part of a set of well-defined values.
+ """
+ def __init__(self, accepted_values):
+ """
+ Creates the constraint and stores the list of accepted values.
+
+ @param correct_values A list that contains all the values that will
+ be declared as satisfying the constraint
+ """
+ self._accepted_values = accepted_values
+
+ def validate(self, value):
+ """
+ Ensures that the value that is passed is part of the list of accepted
+ values.
+ """
+ if not value in self._accepted_values:
+ raise EnumConstraintError("Value is not part of the enumeration")
+ return
+
+class FileConstraintError(Exception):
+ pass
+
+class FileConstraint(Constraint):
+ """
+ Ensures that the string given corresponds to an existing file on disk.
+ """
+ def validate(self, value):
+ # TODO : Decide on the architecture for file retrieval on disk
+ # Relative paths? From where? Support macros?
+ #
+ if not os.path.isfile(value):
+ raise FileConstraintError("Non-existing file : %s"%value)
+ return
+ \ No newline at end of file