summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Crittenden <rcritten@redhat.com>2009-03-18 15:44:53 -0400
committerRob Crittenden <rcritten@redhat.com>2009-03-20 09:29:44 -0400
commita8a2664190eb6f2604d4753b4af8a599a4e24c4b (patch)
treedbe68c5980bc61621fedc5f9d54a3f27f45d85b9
parentc39a29e0cf72a7f7629e3bdaaa2efc49337cb727 (diff)
downloadfreeipa-a8a2664190eb6f2604d4753b4af8a599a4e24c4b.tar.gz
freeipa-a8a2664190eb6f2604d4753b4af8a599a4e24c4b.tar.xz
freeipa-a8a2664190eb6f2604d4753b4af8a599a4e24c4b.zip
Add new type List that converts delimited values into a tuple
-rw-r--r--ipalib/__init__.py2
-rw-r--r--ipalib/parameters.py50
-rw-r--r--tests/test_ipalib/test_parameters.py59
3 files changed, 110 insertions, 1 deletions
diff --git a/ipalib/__init__.py b/ipalib/__init__.py
index 76310cad0..b2fc1f857 100644
--- a/ipalib/__init__.py
+++ b/ipalib/__init__.py
@@ -876,7 +876,7 @@ from backend import Backend
from frontend import Command, LocalOrRemote, Application
from frontend import Object, Method, Property
from crud import Create, Retrieve, Update, Delete, Search
-from parameters import DefaultFrom, Bool, Flag, Int, Float, Bytes, Str, Password
+from parameters import DefaultFrom, Bool, Flag, Int, Float, Bytes, Str, Password,List
from parameters import BytesEnum, StrEnum
from errors2 import SkipPluginModule
diff --git a/ipalib/parameters.py b/ipalib/parameters.py
index 4746e7652..e5f4e8ef1 100644
--- a/ipalib/parameters.py
+++ b/ipalib/parameters.py
@@ -36,6 +36,7 @@ from request import ugettext
from plugable import ReadOnly, lock, check_name
from errors2 import ConversionError, RequirementError, ValidationError
from constants import NULLS, TYPE_ERROR, CALLABLE_ERROR
+import csv
class DefaultFrom(ReadOnly):
@@ -1071,6 +1072,55 @@ class StrEnum(Enum):
type = unicode
+class List(Param):
+ """
+ Base class for parameters as a list of values. The input is a delimited
+ string.
+ """
+ type = tuple
+
+ kwargs = Param.kwargs + (
+ ('separator', str, ','),
+ ('skipspace', bool, True),
+ )
+
+ # The following 2 functions were taken from the Python
+ # documentation at http://docs.python.org/library/csv.html
+ def __utf_8_encoder(self, unicode_csv_data):
+ for line in unicode_csv_data:
+ yield line.encode('utf-8')
+
+ def __unicode_csv_reader(self, unicode_csv_data, dialect=csv.excel, **kwargs):
+ # csv.py doesn't do Unicode; encode temporarily as UTF-8:
+ csv_reader = csv.reader(self.__utf_8_encoder(unicode_csv_data),
+ dialect=dialect, delimiter=self.separator,
+ skipinitialspace=self.skipspace,
+ **kwargs)
+ for row in csv_reader:
+ # decode UTF-8 back to Unicode, cell by cell:
+ yield [unicode(cell, 'utf-8') for cell in row]
+
+ def __init__(self, name, *rules, **kw):
+ (name, kw_from_spec) = parse_param_spec(name)
+ kw.update(kw_from_spec)
+ kw.update(multivalue=True)
+ super(List, self).__init__(name, *rules, **kw)
+
+ def normalize(self, value):
+ if not isinstance(value, tuple):
+ reader = self.__unicode_csv_reader([value])
+ value = []
+ for row in reader:
+ value = value + row
+ value = tuple(value)
+ return super(List, self).normalize(value)
+
+ def _convert_scalar(self, value, index=None):
+ return value
+
+ def _validate_scalar(self, value, index=None):
+ return
+
def create_param(spec):
"""
Create an `Str` instance from the shorthand ``spec``.
diff --git a/tests/test_ipalib/test_parameters.py b/tests/test_ipalib/test_parameters.py
index 472386da3..82f39a32d 100644
--- a/tests/test_ipalib/test_parameters.py
+++ b/tests/test_ipalib/test_parameters.py
@@ -1226,6 +1226,65 @@ class test_Float(ClassChecker):
dummy.reset()
+class test_List(ClassChecker):
+ """
+ Test the `ipalib.parameters.List` class.
+ """
+ _cls = parameters.List
+
+ def test_init(self):
+ """
+ Test the `ipalib.parameters.List.__init__` method.
+ """
+ # Test with no kwargs:
+ o = self.cls('my_list')
+ assert o.type is tuple
+ assert isinstance(o, parameters.List)
+ assert o.multivalue is True
+ assert o.skipspace is True
+
+ def test_normalize(self):
+ """
+ Test the `ipalib.parameters.List.normalize` method.
+ """
+ o = self.cls('my_list')
+ n = o.normalize('a,b')
+ assert type(n) is tuple
+ assert len(n) is 2
+
+ n = o.normalize('bar, "hi, there",foo')
+ assert type(n) is tuple
+ assert len(n) is 3
+
+ def test_normalize_separator(self):
+ """
+ Test the `ipalib.parameters.List.normalize` method with a separator.
+ """
+ o = self.cls('my_list', separator='|')
+
+ n = o.normalize('a')
+ assert type(n) is tuple
+ assert len(n) is 1
+
+ n = o.normalize('a|b')
+ assert type(n) is tuple
+ assert len(n) is 2
+
+ def test_normalize_skipspace(self):
+ """
+ Test the `ipalib.parameters.List.normalize` method without skipping spaces.
+ """
+ o = self.cls('my_list', skipspace=False)
+
+ n = o.normalize('a')
+ assert type(n) is tuple
+ assert len(n) is 1
+
+ n = o.normalize('a, "b,c", d')
+ assert type(n) is tuple
+ # the output w/o skipspace is ['a',' "b','c"',' d']
+ assert len(n) is 4
+
def test_create_param():
"""
Test the `ipalib.parameters.create_param` function.