diff --git a/fastjsonschema/draft04.py b/fastjsonschema/draft04.py index 228dc1f..b0db0be 100644 --- a/fastjsonschema/draft04.py +++ b/fastjsonschema/draft04.py @@ -257,7 +257,7 @@ def generate_not(self): else: with self.l('try:', optimize=False): code_len = len(self._code) - self.generate_func_code_block(not_definition, self._variable, self._variable_name) + self.generate_func_code_block(not_definition, self._variable, self._variable_name, clear_variables=True) if len(self._code) == code_len: self.l('pass') self.l('except JsonSchemaValueException: pass') diff --git a/tests/test_common.py b/tests/test_common.py index 29a3b13..3c70dfc 100644 --- a/tests/test_common.py +++ b/tests/test_common.py @@ -101,6 +101,22 @@ def test_not(asserter, value, expected): asserter({'not': {'type': 'number'}}, value, expected) +@pytest.mark.parametrize('value, expected', [ + ({'a': 1}, {'a': 1}), + ({'b': 2}, {'b': 2}), + ({'a': 1, 'b': 2}, JsonSchemaValueException('data must NOT match a disallowed definition', value='{data}', name='data', definition='{definition}', rule='not')), +]) +def test_not_with_object_and_additional_properties(asserter, value, expected): + # Regression test: variables created inside the not block must not leak + # into the outer scope (issue #208). + asserter({ + 'type': 'object', + 'properties': {'a': {}, 'b': {}}, + 'additionalProperties': False, + 'not': {'properties': {'a': {}, 'b': {}}, 'required': ['a', 'b']}, + }, value, expected) + + exc = JsonSchemaValueException('data must NOT match a disallowed definition', value='{data}', name='data', definition='{definition}', rule='not') @pytest.mark.parametrize('subdefinition', [ {'title': 'x'},