From 3038aa67391efc25b35f26bd323babf4474ad0e2 Mon Sep 17 00:00:00 2001 From: CLCK0622 Date: Fri, 23 Oct 2026 11:37:10 -0500 Subject: [PATCH] Fix const compilation without detailed exceptions --- fastjsonschema/generator.py | 5 ++- tests/test_const.py | 74 ++++++++++++++++++++++++++++++++++++- 2 files changed, 76 insertions(+), 3 deletions(-) diff --git a/fastjsonschema/generator.py b/fastjsonschema/generator.py index 951edda..317e85a 100644 --- a/fastjsonschema/generator.py +++ b/fastjsonschema/generator.py @@ -304,10 +304,11 @@ def exc(self, msg, *args, append_to_msg=None, rule=None): Short-cut for creating raising exception in the code. """ if not self._detailed_exceptions: + definition_rule = self.e(self._definition.get(rule) if isinstance(self._definition, dict) else None) if self._fast_fail: - self.l('raise JsonSchemaValueException("'+msg+'")', *args) + self.l('raise JsonSchemaValueException("'+msg+'")', *args, definition_rule=definition_rule) else: - self.l('errors.append(JsonSchemaValueException("'+msg+'"))', *args) + self.l('errors.append(JsonSchemaValueException("'+msg+'"))', *args, definition_rule=definition_rule) return arg = '"'+msg+'"' diff --git a/tests/test_const.py b/tests/test_const.py index 903cf6b..d62c771 100644 --- a/tests/test_const.py +++ b/tests/test_const.py @@ -1,6 +1,8 @@ import pytest -from fastjsonschema import JsonSchemaValueException +from fastjsonschema import ( + JsonSchemaValueException, JsonSchemaValuesException, compile, compile_to_code, +) @pytest.mark.parametrize('value, testError', ( @@ -22,3 +24,73 @@ def test_const(asserter, value, testError): '$schema': 'http://json-schema.org/draft-06/schema', 'const': const, }, value, expected) + + +@pytest.mark.parametrize('draft', ('06', '07')) +@pytest.mark.parametrize('detailed_exceptions', (True, False)) +@pytest.mark.parametrize('fast_fail', (True, False)) +@pytest.mark.parametrize('matches', (True, False)) +@pytest.mark.parametrize('const, invalid, message_value', ( + ('foo', 'bar', 'foo'), + ('\'"', 'other', '\'"'), + (42, 43, '42'), + (1.5, 1.6, '1.5'), + (True, False, 'True'), + (None, 0, 'None'), + ([1, 'x'], [2, 'x'], "[1, 'x']"), + ({'key': 'value'}, {'key': 'other'}, "{'key': 'value'}"), +)) +def test_const_exception_options(draft, detailed_exceptions, fast_fail, matches, + const, invalid, message_value): + validator = compile({ + '$schema': 'http://json-schema.org/draft-{}/schema#'.format(draft), + 'const': const, + }, detailed_exceptions=detailed_exceptions, fast_fail=fast_fail) + + if matches: + assert validator(const) is const + else: + exception = JsonSchemaValueException if fast_fail else JsonSchemaValuesException + with pytest.raises(exception) as exc: + validator(invalid) + expected_message = 'data must be same as const definition: ' + message_value + assert exc.value.message == expected_message + if not fast_fail: + assert len(exc.value.errors) == 1 + assert isinstance(exc.value.errors[0], JsonSchemaValueException) + assert exc.value.errors[0].message == expected_message + + +@pytest.mark.parametrize('detailed_exceptions', (True, False)) +@pytest.mark.parametrize('fast_fail', (True, False)) +def test_const_compile_to_code_exception_options(detailed_exceptions, fast_fail): + code = compile_to_code({'const': 1}, detailed_exceptions=detailed_exceptions, + fast_fail=fast_fail) + scope = {} + exec(code, scope) + + assert scope['validate'](1) == 1 + exception = JsonSchemaValueException if fast_fail else JsonSchemaValuesException + with pytest.raises(exception) as exc: + scope['validate'](2) + assert exc.value.message == 'data must be same as const definition: 1' + + +@pytest.mark.parametrize('fast_fail', (True, False)) +@pytest.mark.parametrize('to_code', (True, False)) +def test_compact_exceptions_ignore_refs_in_examples(fast_fail, to_code): + schema = { + '$schema': 'http://json-schema.org/draft-07/schema#', + 'type': 'object', + 'examples': [{'$ref': '#/missing'}], + } + if to_code: + code = compile_to_code(schema, detailed_exceptions=False, fast_fail=fast_fail) + scope = {} + exec(code, scope) + validator = scope['validate'] + else: + validator = compile(schema, detailed_exceptions=False, fast_fail=fast_fail) + + value = {'hello': 'world'} + assert validator(value) is value