validation: Reject iterators as core arguments

iter() always never re-wraps an iterator, so 'iter(i) is iter(i)' tests if we
wrapped a container or if we already had an iterator. I also tried
types.GeneratorType and inspect helpers but they did not work for this use
case.
This commit is contained in:
Thomas Adamcik 2015-04-17 00:05:46 +02:00
parent e265f5d673
commit 09027854c6
2 changed files with 8 additions and 2 deletions

View File

@ -22,11 +22,13 @@ DISTINCT_FIELDS = {
# TODO: _check_iterable(check, msg, **kwargs) + [check(a) for a in arg]?
def _check_iterable(arg, msg, **kwargs):
"""Ensure we have an iterable which is not a string."""
"""Ensure we have an iterable which is not a string or an iterator"""
if isinstance(arg, compat.string_types):
raise exceptions.ValidationError(msg.format(arg=arg, **kwargs))
elif not isinstance(arg, collections.Iterable):
raise exceptions.ValidationError(msg.format(arg=arg, **kwargs))
elif iter(arg) is iter(arg):
raise exceptions.ValidationError(msg.format(arg=arg, **kwargs))
def check_choice(arg, choices, msg='Expected one of {choices}, not {arg!r}'):

View File

@ -72,6 +72,8 @@ def test_check_instances_with_invalid_values():
validation.check_instances(None, compat.string_types)
with raises(exceptions.ValidationError):
validation.check_instances([None], compat.string_types)
with raises(exceptions.ValidationError):
validation.check_instances(iter(['abc']), compat.string_types)
def test_check_instances_error_message():
@ -110,7 +112,7 @@ def test_check_field_error_message():
def test_check_query_invalid_values():
for value in '', None, 'foo', 123, [''], [None]:
for value in '', None, 'foo', 123, [''], [None], iter(['abc']):
with raises(exceptions.ValidationError):
validation.check_query({'any': value})
@ -155,6 +157,8 @@ def test_check_uris_with_invalid_values():
validation.check_uris([None])
with raises(exceptions.ValidationError):
validation.check_uris(['foobar:', 'foobar'])
with raises(exceptions.ValidationError):
validation.check_uris(iter(['http://example.com']))
def test_check_uris_error_message():