Merge "Allow lists to be generated from any non-string iterable"

This commit is contained in:
Zuul 2019-02-25 17:29:33 +00:00 committed by Gerrit Code Review
commit c45d34823a
2 changed files with 42 additions and 1 deletions

View File

@ -13,6 +13,7 @@
# under the License.
import abc
import collections
import datetime
from distutils import versionpredicate
import re
@ -642,7 +643,9 @@ class CompoundFieldType(FieldType):
class List(CompoundFieldType):
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, '
'not a %(type)s') %
{'attr': attr, 'type': type(value).__name__})

View File

@ -1229,3 +1229,41 @@ class TestIPV6Network(TestField):
invalid_vals = [x for x in self.coerce_bad_values]
for invalid_val in invalid_vals:
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())