Skip to content

Commit 38e0116

Browse files
committed
Added use_formats parameter
1 parent b0645bf commit 38e0116

File tree

8 files changed

+33
-16
lines changed

8 files changed

+33
-16
lines changed

CHANGELOG.txt

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
=== 2.19.0 (2023-11-14)
2+
3+
* Added `use_formats` parameter to allow disable automatic assertions
4+
15
=== 2.18.1 (2023-10-01)
26

37
* Lazy import of urllib to improve import performance

fastjsonschema/__init__.py

+12-7
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@
123123
)
124124

125125

126-
def validate(definition, data, handlers={}, formats={}, use_default=True):
126+
def validate(definition, data, handlers={}, formats={}, use_default=True, use_formats=True):
127127
"""
128128
Validation function for lazy programmers or for use cases when you need
129129
to call validation only once, so you do not have to compile it first.
@@ -139,12 +139,12 @@ def validate(definition, data, handlers={}, formats={}, use_default=True):
139139
140140
Preferred is to use :any:`compile` function.
141141
"""
142-
return compile(definition, handlers, formats, use_default)(data)
142+
return compile(definition, handlers, formats, use_default, use_formats)(data)
143143

144144

145145
#TODO: Change use_default to False when upgrading to version 3.
146146
# pylint: disable=redefined-builtin,dangerous-default-value,exec-used
147-
def compile(definition, handlers={}, formats={}, use_default=True):
147+
def compile(definition, handlers={}, formats={}, use_default=True, use_formats=True):
148148
"""
149149
Generates validation function for validating JSON schema passed in ``definition``.
150150
Example:
@@ -196,13 +196,17 @@ def compile(definition, handlers={}, formats={}, use_default=True):
196196
'bar': lambda value: value in ('foo', 'bar'),
197197
})
198198
199+
Note that formats are automatically used as assertions. It can be turned
200+
off by passing `use_formats=False`. When disabled, custom formats are
201+
disabled as well. (Added in 2.19.0.)
202+
199203
Exception :any:`JsonSchemaDefinitionException` is raised when generating the
200204
code fails (bad definition).
201205
202206
Exception :any:`JsonSchemaValueException` is raised from generated function when
203207
validation fails (data do not follow the definition).
204208
"""
205-
resolver, code_generator = _factory(definition, handlers, formats, use_default)
209+
resolver, code_generator = _factory(definition, handlers, formats, use_default, use_formats)
206210
global_state = code_generator.global_state
207211
# Do not pass local state so it can recursively call itself.
208212
exec(code_generator.func_code, global_state)
@@ -213,7 +217,7 @@ def compile(definition, handlers={}, formats={}, use_default=True):
213217

214218

215219
# pylint: disable=dangerous-default-value
216-
def compile_to_code(definition, handlers={}, formats={}, use_default=True):
220+
def compile_to_code(definition, handlers={}, formats={}, use_default=True, use_formats=True):
217221
"""
218222
Generates validation code for validating JSON schema passed in ``definition``.
219223
Example:
@@ -236,21 +240,22 @@ def compile_to_code(definition, handlers={}, formats={}, use_default=True):
236240
Exception :any:`JsonSchemaDefinitionException` is raised when generating the
237241
code fails (bad definition).
238242
"""
239-
_, code_generator = _factory(definition, handlers, formats, use_default)
243+
_, code_generator = _factory(definition, handlers, formats, use_default, use_formats)
240244
return (
241245
'VERSION = "' + VERSION + '"\n' +
242246
code_generator.global_state_code + '\n' +
243247
code_generator.func_code
244248
)
245249

246250

247-
def _factory(definition, handlers, formats={}, use_default=True):
251+
def _factory(definition, handlers, formats={}, use_default=True, use_formats=True):
248252
resolver = RefResolver.from_schema(definition, handlers=handlers, store={})
249253
code_generator = _get_code_generator_class(definition)(
250254
definition,
251255
resolver=resolver,
252256
formats=formats,
253257
use_default=use_default,
258+
use_formats=use_formats,
254259
)
255260
return resolver, code_generator
256261

fastjsonschema/draft04.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,10 @@ class CodeGeneratorDraft04(CodeGenerator):
3434
'uri': r'^\w+:(\/?\/?)[^\s]+\Z',
3535
}
3636

37-
def __init__(self, definition, resolver=None, formats={}, use_default=True):
37+
def __init__(self, definition, resolver=None, formats={}, use_default=True, use_formats=True):
3838
super().__init__(definition, resolver)
3939
self._custom_formats = formats
40+
self._use_formats = use_formats
4041
self._use_default = use_default
4142
self._json_keywords_to_function.update((
4243
('type', self.generate_type),
@@ -254,6 +255,8 @@ def generate_format(self):
254255
255256
Valid value for this definition is [email protected] but not @username
256257
"""
258+
if not self._use_formats:
259+
return
257260
with self.l('if isinstance({variable}, str):'):
258261
format_ = self._definition['format']
259262
# Checking custom formats - user is allowed to override default formats.

fastjsonschema/draft06.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ class CodeGeneratorDraft06(CodeGeneratorDraft04):
1616
),
1717
})
1818

19-
def __init__(self, definition, resolver=None, formats={}, use_default=True):
20-
super().__init__(definition, resolver, formats, use_default)
19+
def __init__(self, definition, resolver=None, formats={}, use_default=True, use_formats=True):
20+
super().__init__(definition, resolver, formats, use_default, use_formats)
2121
self._json_keywords_to_function.update((
2222
('exclusiveMinimum', self.generate_exclusive_minimum),
2323
('exclusiveMaximum', self.generate_exclusive_maximum),

fastjsonschema/draft07.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ class CodeGeneratorDraft07(CodeGeneratorDraft06):
1717
),
1818
})
1919

20-
def __init__(self, definition, resolver=None, formats={}, use_default=True):
21-
super().__init__(definition, resolver, formats, use_default)
20+
def __init__(self, definition, resolver=None, formats={}, use_default=True, use_formats=True):
21+
super().__init__(definition, resolver, formats, use_default, use_formats)
2222
# pylint: disable=duplicate-code
2323
self._json_keywords_to_function.update((
2424
('if', self.generate_if_then_else),

fastjsonschema/version.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
VERSION = '2.18.1'
1+
VERSION = '2.19.0'

tests/conftest.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,16 @@ def pytest_configure(config):
2020

2121
@pytest.fixture
2222
def asserter():
23-
def f(definition, value, expected, formats={}):
23+
def f(definition, value, expected, formats={}, use_formats=True):
2424
# When test fails, it will show up code.
25-
code_generator = CodeGeneratorDraft07(definition, formats=formats)
25+
code_generator = CodeGeneratorDraft07(definition, formats=formats, use_formats=use_formats)
2626
print(code_generator.func_code)
2727
pprint(code_generator.global_state)
2828

2929
# By default old tests are written for draft-04.
3030
definition.setdefault('$schema', 'http://json-schema.org/draft-04/schema')
3131

32-
validator = compile(definition, formats=formats)
32+
validator = compile(definition, formats=formats, use_formats=use_formats)
3333
if isinstance(expected, JsonSchemaValueException):
3434
with pytest.raises(JsonSchemaValueException) as exc:
3535
validator(value)

tests/test_format.py

+5
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,8 @@ def test_custom_format_override(asserter):
5656
asserter({'format': 'date-time'}, 'a', 'a', formats={
5757
'date-time': r'^[ab]$',
5858
})
59+
60+
61+
def test_disable_formats(asserter):
62+
asserter({'format': 'date-time'}, 'bla', 'bla', use_formats=False)
63+

0 commit comments

Comments
 (0)