mirror of
https://github.com/correl/openapi-core.git
synced 2025-01-04 03:00:15 +00:00
Merge pull request #133 from crunchr/support-any-type-with-one-of-rb1
Add support for one-of with any type
This commit is contained in:
commit
0df1d051b4
3 changed files with 58 additions and 11 deletions
|
@ -2,7 +2,6 @@
|
||||||
import attr
|
import attr
|
||||||
import functools
|
import functools
|
||||||
import logging
|
import logging
|
||||||
from base64 import b64decode, b64encode
|
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from datetime import date, datetime
|
from datetime import date, datetime
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
@ -229,6 +228,9 @@ class Schema(object):
|
||||||
else:
|
else:
|
||||||
raise InvalidSchemaValue(msg, value, self.format)
|
raise InvalidSchemaValue(msg, value, self.format)
|
||||||
else:
|
else:
|
||||||
|
if self.enum and value not in self.enum:
|
||||||
|
raise InvalidSchemaValue(
|
||||||
|
"Value {value} not in enum choices: {type}", value, self.enum)
|
||||||
formatstring = self.STRING_FORMAT_CALLABLE_GETTER[schema_format]
|
formatstring = self.STRING_FORMAT_CALLABLE_GETTER[schema_format]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -278,13 +280,30 @@ class Schema(object):
|
||||||
SchemaType.INTEGER, SchemaType.NUMBER, SchemaType.STRING,
|
SchemaType.INTEGER, SchemaType.NUMBER, SchemaType.STRING,
|
||||||
]
|
]
|
||||||
cast_mapping = self.get_cast_mapping()
|
cast_mapping = self.get_cast_mapping()
|
||||||
for schema_type in types_resolve_order:
|
if self.one_of:
|
||||||
cast_callable = cast_mapping[schema_type]
|
result = None
|
||||||
try:
|
for subschema in self.one_of:
|
||||||
return cast_callable(value)
|
try:
|
||||||
# @todo: remove ValueError when validation separated
|
casted = subschema.cast(value, custom_formatters)
|
||||||
except (OpenAPISchemaError, TypeError, ValueError):
|
except (OpenAPISchemaError, TypeError, ValueError):
|
||||||
continue
|
continue
|
||||||
|
else:
|
||||||
|
if result is not None:
|
||||||
|
raise MultipleOneOfSchema(self.type)
|
||||||
|
result = casted
|
||||||
|
|
||||||
|
if result is None:
|
||||||
|
raise NoOneOfSchema(self.type)
|
||||||
|
|
||||||
|
return result
|
||||||
|
else:
|
||||||
|
for schema_type in types_resolve_order:
|
||||||
|
cast_callable = cast_mapping[schema_type]
|
||||||
|
try:
|
||||||
|
return cast_callable(value)
|
||||||
|
# @todo: remove ValueError when validation separated
|
||||||
|
except (OpenAPISchemaError, TypeError, ValueError):
|
||||||
|
continue
|
||||||
|
|
||||||
raise NoValidSchema(value)
|
raise NoValidSchema(value)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import json
|
import json
|
||||||
import pytest
|
import pytest
|
||||||
|
from datetime import datetime
|
||||||
from base64 import b64encode
|
from base64 import b64encode
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
from six import iteritems, text_type
|
from six import iteritems, text_type
|
||||||
|
@ -19,7 +20,7 @@ from openapi_core.schema.request_bodies.models import RequestBody
|
||||||
from openapi_core.schema.responses.models import Response
|
from openapi_core.schema.responses.models import Response
|
||||||
from openapi_core.schema.schemas.enums import SchemaType
|
from openapi_core.schema.schemas.enums import SchemaType
|
||||||
from openapi_core.schema.schemas.exceptions import (
|
from openapi_core.schema.schemas.exceptions import (
|
||||||
NoValidSchema, InvalidSchemaProperty, InvalidSchemaValue,
|
InvalidSchemaProperty, InvalidSchemaValue,
|
||||||
)
|
)
|
||||||
from openapi_core.schema.schemas.models import Schema
|
from openapi_core.schema.schemas.models import Schema
|
||||||
from openapi_core.schema.servers.exceptions import InvalidServer
|
from openapi_core.schema.servers.exceptions import InvalidServer
|
||||||
|
@ -1213,7 +1214,7 @@ class TestPetstore(object):
|
||||||
|
|
||||||
assert parameters == {}
|
assert parameters == {}
|
||||||
assert isinstance(body, BaseModel)
|
assert isinstance(body, BaseModel)
|
||||||
assert body.created == created
|
assert body.created == datetime(2016, 4, 16, 16, 6, 5)
|
||||||
assert body.name == pet_name
|
assert body.name == pet_name
|
||||||
|
|
||||||
code = 400
|
code = 400
|
||||||
|
@ -1257,7 +1258,7 @@ class TestPetstore(object):
|
||||||
)
|
)
|
||||||
|
|
||||||
parameters = request.get_parameters(spec)
|
parameters = request.get_parameters(spec)
|
||||||
with pytest.raises(NoValidSchema):
|
with pytest.raises(InvalidMediaTypeValue):
|
||||||
request.get_body(spec)
|
request.get_body(spec)
|
||||||
|
|
||||||
assert parameters == {}
|
assert parameters == {}
|
||||||
|
|
|
@ -300,6 +300,33 @@ class TestSchemaUnmarshal(object):
|
||||||
|
|
||||||
assert result == 1.2
|
assert result == 1.2
|
||||||
|
|
||||||
|
def test_schema_any_one_of(self):
|
||||||
|
schema = Schema(one_of=[
|
||||||
|
Schema('string'),
|
||||||
|
Schema('array', items=Schema('string')),
|
||||||
|
])
|
||||||
|
assert schema.unmarshal(['hello']) == ['hello']
|
||||||
|
|
||||||
|
def test_schema_any_one_of_mutiple(self):
|
||||||
|
schema = Schema(one_of=[
|
||||||
|
Schema('array', items=Schema('string')),
|
||||||
|
Schema('array', items=Schema('number')),
|
||||||
|
])
|
||||||
|
with pytest.raises(MultipleOneOfSchema):
|
||||||
|
schema.unmarshal([])
|
||||||
|
|
||||||
|
def test_schema_any_one_of_no_valid(self):
|
||||||
|
schema = Schema(one_of=[
|
||||||
|
Schema('array', items=Schema('string')),
|
||||||
|
Schema('array', items=Schema('number')),
|
||||||
|
])
|
||||||
|
with pytest.raises(NoOneOfSchema):
|
||||||
|
schema.unmarshal({})
|
||||||
|
|
||||||
|
def test_schema_any(self):
|
||||||
|
schema = Schema()
|
||||||
|
assert schema.unmarshal('string') == 'string'
|
||||||
|
|
||||||
|
|
||||||
class TestSchemaValidate(object):
|
class TestSchemaValidate(object):
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue