[GRASS-SVN] r61163 - grass/trunk/lib/python/pygrass/modules/interface
svn_grass at osgeo.org
svn_grass at osgeo.org
Mon Jul 7 03:20:22 PDT 2014
Author: zarch
Date: 2014-07-07 03:20:22 -0700 (Mon, 07 Jul 2014)
New Revision: 61163
Modified:
grass/trunk/lib/python/pygrass/modules/interface/parameter.py
Log:
pygrass: Parameter check refactoring and add examples and documentation
Modified: grass/trunk/lib/python/pygrass/modules/interface/parameter.py
===================================================================
--- grass/trunk/lib/python/pygrass/modules/interface/parameter.py 2014-07-07 10:00:11 UTC (rev 61162)
+++ grass/trunk/lib/python/pygrass/modules/interface/parameter.py 2014-07-07 10:20:22 UTC (rev 61163)
@@ -12,14 +12,103 @@
from grass.pygrass.modules.interface.read import GETTYPE, element2dict, DOC
+def _check_value(param, value):
+ """Function to check the correctness of a value and
+ return the checked value and the original.
+ """
+ must_val = 'The Parameter <%s>, must be one of the following values: %r'
+ req = 'The Parameter <%s>, require: %s, get: %s instead: %r\n%s'
+ string = (str, unicode)
+
+ def raiseexcpet(exc, param, ptype, value):
+ """Function to modifa the error message"""
+ msg = req % (param.name, param.typedesc, ptype, value, exc.message)
+ if exc is ValueError:
+ raise ValueError(msg)
+ elif exc is TypeError:
+ raise TypeError(msg)
+ else:
+ exc.message = msg
+ raise exc
+
+ def check_string(value):
+ """Function to check that a string parameter is already a string"""
+ if param.type in string and type(value) not in string:
+ msg = ("The Parameter <%s> require a string,"
+ " %s instead is provided: %r")
+ raise ValueError(msg % (param.name, type(value), value))
+ return value
+
+ # return None if None
+ if value is None:
+ return param.default, param.default
+
+ # find errors with multiple parmaeters
+ if param.multiple or param.keydescvalues:
+ if not isinstance(value, (list, tuple)):
+ msg = ('The Parameter <%s> require multiple inputs,'
+ ' give: %r instaed')
+ raise TypeError(msg % (param.name, value))
+ # everything looks fine, so check each value
+ try:
+ return [param.type(check_string(val)) for val in value], value
+ except Exception as exc:
+ raiseexcpet(exc, param, param.type, value)
+ elif isinstance(value, (list, tuple)):
+ # this check is needed to avoid a list is converted to string silently
+ msg = 'The Parameter <%s> does not accept multiple inputs'
+ raise TypeError(msg % param.name)
+
+ if param.typedesc == 'all':
+ return value, value
+
+ # check string before trying to convert value to the correct type
+ check_string(value)
+ # the value is a scalar
+ try:
+ newvalue = param.type(value)
+ except Exception as exc:
+ raiseexcpet(exc, param, type(value), value)
+
+ # check values
+ if hasattr(param, 'values'):
+ if param.type in (float, int):
+ # check for value in range
+ if ((param.min is not None and newvalue < param.min) or
+ (param.max is not None and newvalue > param.max)):
+ err_str = ('The Parameter <%s>, must be between: '
+ '%g<=value<=%g, %r is outside.')
+ raise ValueError(err_str % (param.name, param.min,
+ param.max, newvalue))
+ # check if value is in the list of valid values
+ if param.values is not None and newvalue not in param.values:
+ raise ValueError(must_val % (param.name, param.values))
+ return newvalue, value
+
+
# TODO add documentation
class Parameter(object):
- """The Parameter object store all information about a parameter of module.
+ """The Parameter object store all information about a parameter of a
+ GRASS GIS module. ::
- It is possible to set parameter of command using this object.
+ >>> param = Parameter(diz=dict(name='int_number', required='yes',
+ ... multiple='no', type='integer',
+ ... values=[2, 4, 6, 8]))
+ >>> param.value = 2
+ >>> param.value
+ 2
+ >>> param.value = 3
+ Traceback (most recent call last):
+ ...
+ ValueError: The Parameter <int_number>, must be one of the following values: [2, 4, 6, 8]
+
+ ...
"""
def __init__(self, xparameter=None, diz=None):
self._value = None
+ self._rawvalue = None
+ self.min = None
+ self.max = None
diz = element2dict(xparameter) if xparameter is not None else diz
if diz is None:
raise TypeError('Xparameter or diz are required')
@@ -66,10 +155,9 @@
for v in diz['default'].split(',')]
else:
self.default = self.type(diz['default'])
- self._value = self.default
else:
self.default = None
-
+ self._value, self._rawvalue = self.default, self.default
self.guisection = diz.get('guisection', None)
#
@@ -85,82 +173,59 @@
return self._value
def _set_value(self, value):
- values_error = 'The Parameter <%s>, must be a python list ' \
- 'containing one or more of the following values: %r'
- if value is None:
- self._value = value
- elif isinstance(value, list) or isinstance(value, tuple):
- if self.multiple or self.keydescvalues:
- # check each value
- self._value = [self.type(val) for val in value]
- else:
- str_err = 'The Parameter <%s> does not accept multiple inputs'
- raise TypeError(str_err % self.name)
- elif self.typedesc == 'all':
- self._value = value
- elif isinstance(value, self.type):
- if hasattr(self, 'values'):
- if self.type in (float, int):
- if self.min <= value <= self.max:
- self._value = value
- else:
- err_str = 'The Parameter <%s>, must be: %g<=value<=%g'
- raise ValueError(err_str % (self.name, self.min,
- self.max))
- elif value in self.values:
- self._value = value
- else:
- raise ValueError(values_error % (self.name, self.values))
- else:
- self._value = value
- elif self.type is str and isinstance(value, unicode):
- if hasattr(self, 'values'):
- if value in self.values:
- self._value = str(value)
- else:
- raise ValueError(values_error % (self.name, self.values))
- else:
- self._value = str(value)
- elif self.type is str and isinstance(value, str):
- if hasattr(self, 'values'):
- if value in self.values:
- self._value = value
- else:
- raise ValueError(values_error % (self.name, self.values))
- else:
- self._value = value
- else:
- str_err = 'The Parameter <%s>, require: %s, get: %s instead'
- raise TypeError(str_err % (self.name, self.typedesc, type(value)))
+ self._value, self._rawvalue = _check_value(self, value)
# here the property function is used to transform value in an attribute
# in this case we define which function must be use to get/set the value
value = property(fget=_get_value, fset=_set_value,
- doc="Set or obtain value")
+ doc="Parameter value transformed and validated.")
+ @property
+ def rawvalue(self):
+ """Parameter value as insert by user without transformation"""
+ return self._rawvalue
+
def get_bash(self):
- """Prova"""
- if isinstance(self._value, list) or isinstance(self._value, tuple):
- value = ','.join([str(v) for v in self._value])
- else:
- value = str(self._value)
- return """%s=%s""" % (self.name, value)
+ """Return the BASH representation of the parameter. ::
+ >>> param = Parameter(diz=dict(name='int_number', required='yes',
+ ... multiple='no', type='integer',
+ ... values=[2, 4, 6, 8], default=8))
+ >>> param.get_bash()
+ u'int_number=8'
+
+ ..
+ """
+ if self.value is None:
+ return ''
+ return """%s=%s""" % (self.name, self.rawvalue)
+
def get_python(self):
- """Prova"""
- if not self.value:
+ """Return a string with the Python representation of the parameter. ::
+
+ >>> param = Parameter(diz=dict(name='int_number', required='yes',
+ ... multiple='no', type='integer',
+ ... values=[2, 4, 6, 8], default=8))
+ >>> param.get_python()
+ u'int_number=8'
+
+ ..
+ """
+ if self.value is None:
return ''
- return """%s=%r""" % (self.name, self._value)
+ return """%s=%r""" % (self.name, self.value)
def __str__(self):
+ """Return the BASH representation of the GRASS module parameter."""
return self.get_bash()
def __repr__(self):
+ """Return the python representation of the GRASS module parameter."""
str_repr = "Parameter <%s> (required:%s, type:%s, multiple:%s)"
+ mtype = ('raster', 'vector') # map type
return str_repr % (self.name,
"yes" if self.required else "no",
- self.type if self.type in (
- 'raster', 'vector') else self.typedesc,
+ self.type if self.type in mtype else self.typedesc,
"yes" if self.multiple else "no")
@docstring_property(__doc__)
@@ -168,7 +233,21 @@
"""Return the docstring of the parameter
{name}: {default}{required}{multi}{ptype}
- {description}{values}"","""
+ {description}{values}"",
+
+ ::
+
+ >>> param = Parameter(diz=dict(name='int_number',
+ ... description="Set an number",
+ ... required='yes',
+ ... multiple='no', type='integer',
+ ... values=[2, 4, 6, 8], default=8))
+ >>> print(param.__doc__)
+ int_number: 8, required, integer
+ Set an number
+ Values: 2, 4, 6, 8
+ ..
+ """
if hasattr(self, 'values'):
if self.isrange:
vals = self.isrange
More information about the grass-commit
mailing list