From 7b4efb403b6bed94e306d58d487d2a7e21194af4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Cabessa?= Date: Wed, 9 Jan 2019 11:06:56 +0100 Subject: [PATCH] Fix #379: Regression with Any and required In 0.9.3, the `Schema`s associated to the `Any` validators where setup with the `required` argument given to `Any` https://github.com/alecthomas/voluptuous/blob/0.9.3/voluptuous/validators.py#L218 This allow us to write something like: ``` Schema(Any({'a': int}, {'b': str}, required=True)) ``` In recent version, the `required` keyword is ignored. This patch pass the required argument to the `Schema`s associated with the `SubValidator`. --- voluptuous/tests/tests.py | 27 +++++++++++++++++++++++++++ voluptuous/validators.py | 9 +++++---- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/voluptuous/tests/tests.py b/voluptuous/tests/tests.py index bc16a12..f2db8da 100644 --- a/voluptuous/tests/tests.py +++ b/voluptuous/tests/tests.py @@ -1322,3 +1322,30 @@ def test_strip_util_handles_various_inputs(): assert Strip(u"3") == u"3" assert Strip(b'\xe2\x98\x83'.decode("UTF-8")) == b'\xe2\x98\x83'.decode("UTF-8") assert Strip(u" aaa ") == u"aaa" + + +def test_any_required(): + schema = Schema(Any({'a': int}, {'b': str}, required=True)) + + try: + schema({}) + except MultipleInvalid as e: + assert_equal(str(e), + "required key not provided @ data['a']") + else: + assert False, "Did not raise Invalid for MultipleInvalid" + + +def test_any_required_with_subschema(): + schema = Schema(Any({'a': Any(float, int)}, + {'b': int}, + {'c': {'aa': int}}, + required=True)) + + try: + schema({}) + except MultipleInvalid as e: + assert_equal(str(e), + "required key not provided @ data['a']") + else: + assert False, "Did not raise Invalid for MultipleInvalid" diff --git a/voluptuous/validators.py b/voluptuous/validators.py index 8c6a86d..81566b9 100644 --- a/voluptuous/validators.py +++ b/voluptuous/validators.py @@ -192,12 +192,13 @@ class _WithSubValidators(object): def __init__(self, *validators, **kwargs): self.validators = validators self.msg = kwargs.pop('msg', None) + self.required = kwargs.pop('required', False) def __voluptuous_compile__(self, schema): - self._compiled = [ - schema._compile(v) - for v in self.validators - ] + self._compiled = [] + for v in self.validators: + schema.required = self.required + self._compiled.append(schema._compile(v)) return self._run def _run(self, path, value):