Skip to content

Commit 5673e8f

Browse files
authored
Merge pull request #292 from p1c2u/fix/format-checker-on-validator-scope
Format checker on validation scope
2 parents 70f05b2 + 90355f8 commit 5673e8f

File tree

5 files changed

+36
-15
lines changed

5 files changed

+36
-15
lines changed

openapi_core/unmarshalling/schemas/factories.py

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
from copy import copy
21
import warnings
32

4-
from openapi_schema_validator import OAS30Validator, oas30_format_checker
3+
from openapi_schema_validator import OAS30Validator
54

65
from openapi_core.schema.schemas.enums import SchemaType, SchemaFormat
76
from openapi_core.schema.schemas.models import Schema
@@ -35,8 +34,11 @@ class SchemaUnmarshallersFactory(object):
3534
UnmarshalContext.RESPONSE: 'read',
3635
}
3736

38-
def __init__(self, resolver=None, custom_formatters=None, context=None):
37+
def __init__(
38+
self, resolver=None, format_checker=None,
39+
custom_formatters=None, context=None):
3940
self.resolver = resolver
41+
self.format_checker = format_checker
4042
if custom_formatters is None:
4143
custom_formatters = {}
4244
self.custom_formatters = custom_formatters
@@ -79,17 +81,10 @@ def get_formatter(self, default_formatters, type_format=SchemaFormat.NONE):
7981
return default_formatters.get(schema_format)
8082

8183
def get_validator(self, schema):
82-
format_checker = self._get_format_checker()
8384
kwargs = {
8485
'resolver': self.resolver,
85-
'format_checker': format_checker,
86+
'format_checker': self.format_checker,
8687
}
8788
if self.context is not None:
8889
kwargs[self.CONTEXT_VALIDATION[self.context]] = True
8990
return OAS30Validator(schema.__dict__, **kwargs)
90-
91-
def _get_format_checker(self):
92-
fc = copy(oas30_format_checker)
93-
for name, formatter in self.custom_formatters.items():
94-
fc.checks(name)(formatter.validate)
95-
return fc

openapi_core/unmarshalling/schemas/util.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
"""OpenAPI core schemas util module"""
22
from base64 import b64decode
3+
from copy import copy
34
import datetime
45
from distutils.util import strtobool
56
from six import string_types, text_type, integer_types
67
from uuid import UUID
78

9+
from openapi_schema_validator import oas30_format_checker
10+
11+
from openapi_core.compat import lru_cache
12+
813

914
def forcebool(val):
1015
if isinstance(val, string_types):
@@ -32,3 +37,14 @@ def format_number(value):
3237
return value
3338

3439
return float(value)
40+
41+
42+
@lru_cache()
43+
def build_format_checker(**custom_formatters):
44+
if not custom_formatters:
45+
return oas30_format_checker
46+
47+
fc = copy(oas30_format_checker)
48+
for name, formatter in custom_formatters.items():
49+
fc.checks(name)(formatter.validate)
50+
return fc

openapi_core/validation/validators.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""OpenAPI core validation validators module"""
2+
from openapi_core.unmarshalling.schemas.util import build_format_checker
23

34

45
class BaseValidator(object):
@@ -10,9 +11,11 @@ def __init__(
1011
):
1112
self.spec = spec
1213
self.base_url = base_url
13-
self.custom_formatters = custom_formatters
14+
self.custom_formatters = custom_formatters or {}
1415
self.custom_media_type_deserializers = custom_media_type_deserializers
1516

17+
self.format_checker = build_format_checker(**self.custom_formatters)
18+
1619
def _find_path(self, request):
1720
from openapi_core.templating.paths.finders import PathFinder
1821
finder = PathFinder(self.spec, base_url=self.base_url)
@@ -45,8 +48,8 @@ def _unmarshal(self, param_or_media_type, value, context):
4548
SchemaUnmarshallersFactory,
4649
)
4750
unmarshallers_factory = SchemaUnmarshallersFactory(
48-
self.spec._resolver, self.custom_formatters,
49-
context=context,
51+
self.spec._resolver, self.format_checker,
52+
self.custom_formatters, context=context,
5053
)
5154
unmarshaller = unmarshallers_factory.create(
5255
param_or_media_type.schema)

tests/unit/unmarshalling/test_unmarshal.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,16 @@
1818
SchemaUnmarshallersFactory,
1919
)
2020
from openapi_core.unmarshalling.schemas.formatters import Formatter
21+
from openapi_core.unmarshalling.schemas.util import build_format_checker
2122

2223

2324
@pytest.fixture
2425
def unmarshaller_factory():
2526
def create_unmarshaller(schema, custom_formatters=None, context=None):
27+
custom_formatters = custom_formatters or {}
28+
format_checker = build_format_checker(**custom_formatters)
2629
return SchemaUnmarshallersFactory(
30+
format_checker=format_checker,
2731
custom_formatters=custom_formatters, context=context).create(
2832
schema)
2933
return create_unmarshaller

tests/unit/unmarshalling/test_validate.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from openapi_core.unmarshalling.schemas.exceptions import (
1313
FormatterNotFoundError, InvalidSchemaValue,
1414
)
15+
from openapi_core.unmarshalling.schemas.util import build_format_checker
1516

1617
from six import b, u
1718

@@ -21,7 +22,9 @@ class TestSchemaValidate(object):
2122
@pytest.fixture
2223
def validator_factory(self):
2324
def create_validator(schema):
24-
return SchemaUnmarshallersFactory().create(schema)
25+
format_checker = build_format_checker()
26+
return SchemaUnmarshallersFactory(
27+
format_checker=format_checker).create(schema)
2528
return create_validator
2629

2730
@pytest.mark.parametrize('schema_type', [

0 commit comments

Comments
 (0)