Add new type List that converts delimited values into a tuple

This commit is contained in:
Rob Crittenden
2009-03-18 15:44:53 -04:00
parent c39a29e0cf
commit a8a2664190
3 changed files with 110 additions and 1 deletions

View File

@@ -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

View File

@@ -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``.

View File

@@ -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.