Merge "Allow lists to be generated from any non-string iterable"
This commit is contained in:
commit
c45d34823a
@ -13,6 +13,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import abc
|
import abc
|
||||||
|
import collections
|
||||||
import datetime
|
import datetime
|
||||||
from distutils import versionpredicate
|
from distutils import versionpredicate
|
||||||
import re
|
import re
|
||||||
@ -642,7 +643,9 @@ class CompoundFieldType(FieldType):
|
|||||||
|
|
||||||
class List(CompoundFieldType):
|
class List(CompoundFieldType):
|
||||||
def coerce(self, obj, attr, value):
|
def coerce(self, obj, attr, value):
|
||||||
if not isinstance(value, list):
|
|
||||||
|
if (not isinstance(value, collections.Iterable) or
|
||||||
|
isinstance(value, six.string_types + (collections.Mapping,))):
|
||||||
raise ValueError(_('A list is required in field %(attr)s, '
|
raise ValueError(_('A list is required in field %(attr)s, '
|
||||||
'not a %(type)s') %
|
'not a %(type)s') %
|
||||||
{'attr': attr, 'type': type(value).__name__})
|
{'attr': attr, 'type': type(value).__name__})
|
||||||
|
@ -1229,3 +1229,41 @@ class TestIPV6Network(TestField):
|
|||||||
invalid_vals = [x for x in self.coerce_bad_values]
|
invalid_vals = [x for x in self.coerce_bad_values]
|
||||||
for invalid_val in invalid_vals:
|
for invalid_val in invalid_vals:
|
||||||
self.assertNotRegex(str(invalid_val), pattern)
|
self.assertNotRegex(str(invalid_val), pattern)
|
||||||
|
|
||||||
|
|
||||||
|
class FakeCounter(six.Iterator):
|
||||||
|
def __init__(self):
|
||||||
|
self.n = 0
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __next__(self):
|
||||||
|
if self.n <= 4:
|
||||||
|
self.n += 1
|
||||||
|
return self.n
|
||||||
|
else:
|
||||||
|
raise StopIteration
|
||||||
|
|
||||||
|
|
||||||
|
class TestListTypes(test.TestCase):
|
||||||
|
|
||||||
|
def test_regular_list(self):
|
||||||
|
fields.List(fields.Integer).coerce(None, None, [1, 2])
|
||||||
|
|
||||||
|
def test_non_iterable(self):
|
||||||
|
self.assertRaises(ValueError,
|
||||||
|
fields.List(fields.Integer).coerce, None, None, 2)
|
||||||
|
|
||||||
|
def test_string_iterable(self):
|
||||||
|
self.assertRaises(ValueError,
|
||||||
|
fields.List(fields.Integer).coerce, None, None,
|
||||||
|
'hello')
|
||||||
|
|
||||||
|
def test_mapping_iterable(self):
|
||||||
|
self.assertRaises(ValueError,
|
||||||
|
fields.List(fields.Integer).coerce, None, None,
|
||||||
|
{'a': 1, 'b': 2})
|
||||||
|
|
||||||
|
def test_iter_class(self):
|
||||||
|
fields.List(fields.Integer).coerce(None, None, FakeCounter())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user