Merge "Allow Sequence/Iterable/Iterator to be nullable"

This commit is contained in:
Jenkins 2016-02-10 17:56:12 +00:00 committed by Gerrit Code Review
commit 63537f0fe2
2 changed files with 57 additions and 7 deletions

View File

@ -166,9 +166,9 @@ class DateTime(PythonType):
class Iterable(PythonType):
def __init__(self, validators=None):
def __init__(self, validators=None, nullable=False):
super(Iterable, self).__init__(
collections.Iterable, False, [
collections.Iterable, nullable, [
lambda t: not isinstance(t, six.string_types + (
utils.MappingType,))] + (validators or []))
@ -183,19 +183,20 @@ class Iterable(PythonType):
*args, **kwargs):
res = super(Iterable, self).convert(
value, receiver, context, function_spec, engine, *args, **kwargs)
return utils.limit_iterable(res, engine)
return None if res is None else utils.limit_iterable(res, engine)
class Iterator(Iterable):
def __init__(self, validators=None):
def __init__(self, validators=None, nullable=False):
super(Iterator, self).__init__(
validators=[utils.is_iterator] + (validators or []))
validators=[utils.is_iterator] + (validators or []),
nullable=nullable)
class Sequence(PythonType):
def __init__(self, validators=None):
def __init__(self, validators=None, nullable=False):
super(Sequence, self).__init__(
collections.Sequence, False, [
collections.Sequence, nullable, [
lambda t: not isinstance(t, six.string_types + (dict,))] + (
validators or []))

View File

@ -30,3 +30,52 @@ class TestMiscellaneous(yaql.tests.TestCase):
self.assertRaises(
exceptions.NoMatchingFunctionException,
self.eval, 'foo(true)')
def test_nullable_collections(self):
@specs.parameter('arg', yaqltypes.Sequence())
def foo1(arg):
return arg is None
@specs.parameter('arg', yaqltypes.Sequence(nullable=True))
def foo2(arg):
return arg is None
@specs.parameter('arg', yaqltypes.Iterable())
def bar1(arg):
return arg is None
@specs.parameter('arg', yaqltypes.Iterable(nullable=True))
def bar2(arg):
return arg is None
@specs.parameter('arg', yaqltypes.Iterator())
def baz1(arg):
return arg is None
@specs.parameter('arg', yaqltypes.Iterator(nullable=True))
def baz2(arg):
return arg is None
for func in (foo1, foo2, bar1, bar2, baz1, baz2):
self.context.register_function(func)
self.assertFalse(self.eval('foo1([1, 2])'))
self.assertRaises(
exceptions.NoMatchingFunctionException,
self.eval, 'foo1(null)')
self.assertFalse(self.eval('foo2([1, 2])'))
self.assertTrue(self.eval('foo2(null)'))
self.assertFalse(self.eval('bar1([1, 2])'))
self.assertRaises(
exceptions.NoMatchingFunctionException,
self.eval, 'bar1(null)')
self.assertFalse(self.eval('bar2([1, 2])'))
self.assertTrue(self.eval('bar2(null)'))
self.assertFalse(self.eval('baz1($)', data=iter([1, 2])))
self.assertRaises(
exceptions.NoMatchingFunctionException,
self.eval, 'baz1(null)')
self.assertFalse(self.eval('baz2($)', data=iter([1, 2])))
self.assertTrue(self.eval('baz2(null)'))