Skip to content

Commit 72d21a2

Browse files
authored
Merge pull request #1 from p1c2u/master
Merge from upstream
2 parents 7993de8 + 97ec8c7 commit 72d21a2

File tree

7 files changed

+50
-13
lines changed

7 files changed

+50
-13
lines changed

openapi_core/unmarshalling/schemas/unmarshallers.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from functools import partial
22
import logging
33

4+
from isodate.isodatetime import parse_datetime
5+
46
from openapi_schema_validator._types import (
57
is_array, is_bool, is_integer,
68
is_object, is_number, is_string,
@@ -20,7 +22,7 @@
2022
)
2123
from openapi_core.unmarshalling.schemas.formatters import Formatter
2224
from openapi_core.unmarshalling.schemas.util import (
23-
forcebool, format_date, format_datetime, format_byte, format_uuid,
25+
forcebool, format_date, format_byte, format_uuid,
2426
format_number,
2527
)
2628

@@ -77,7 +79,7 @@ class StringUnmarshaller(PrimitiveTypeUnmarshaller):
7779
partial(oas30_format_checker.check, format='date'), format_date),
7880
SchemaFormat.DATETIME: Formatter.from_callables(
7981
partial(oas30_format_checker.check, format='date-time'),
80-
format_datetime),
82+
parse_datetime),
8183
SchemaFormat.BINARY: Formatter.from_callables(
8284
partial(oas30_format_checker.check, format='binary'), binary_type),
8385
SchemaFormat.UUID: Formatter.from_callables(
@@ -157,9 +159,16 @@ class ObjectUnmarshaller(ComplexUnmarshaller):
157159
def model_factory(self):
158160
return ModelFactory()
159161

160-
def __call__(self, value=NoValue):
161-
value = super(ObjectUnmarshaller, self).__call__(value)
162+
def unmarshal(self, value):
163+
try:
164+
value = self.formatter.unmarshal(value)
165+
except ValueError as exc:
166+
raise InvalidSchemaFormatValue(
167+
value, self.schema.format, exc)
168+
else:
169+
return self._unmarshal_object(value)
162170

171+
def _unmarshal_object(self, value=NoValue):
163172
if self.schema.one_of:
164173
properties = None
165174
for one_of_schema in self.schema.one_of:

openapi_core/unmarshalling/schemas/util.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import datetime
44
from distutils.util import strtobool
55
from six import string_types, text_type, integer_types
6-
import strict_rfc3339
76
from uuid import UUID
87

98

@@ -18,11 +17,6 @@ def format_date(value):
1817
return datetime.datetime.strptime(value, '%Y-%m-%d').date()
1918

2019

21-
def format_datetime(value):
22-
timestamp = strict_rfc3339.rfc3339_to_timestamp(value)
23-
return datetime.datetime.utcfromtimestamp(timestamp)
24-
25-
2620
def format_uuid(value):
2721
if isinstance(value, UUID):
2822
return value

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
isodate==0.6.0
12
openapi-spec-validator
23
openapi-schema-validator
34
six

requirements_2.7.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
isodate==0.6.0
12
openapi-spec-validator
23
openapi-schema-validator
34
six

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ python_requires = >= 2.7, != 3.0.*, != 3.1.*, != 3.2.*, != 3.3.*, != 3.4.*
2323
setup_requires =
2424
setuptools
2525
install_requires =
26+
isodate
2627
openapi-spec-validator
2728
openapi-schema-validator
2829
six

tests/integration/validation/test_petstore.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from datetime import datetime
44
from base64 import b64encode
55
from uuid import UUID
6+
from isodate.tzinfo import UTC
67
from six import text_type
78

89
from openapi_core.casting.schemas.exceptions import CastError
@@ -1090,7 +1091,7 @@ def test_post_tags_created_datetime(
10901091

10911092
assert parameters == RequestParameters()
10921093
assert isinstance(body, BaseModel)
1093-
assert body.created == datetime(2016, 4, 16, 16, 6, 5)
1094+
assert body.created == datetime(2016, 4, 16, 16, 6, 5, tzinfo=UTC)
10941095
assert body.name == pet_name
10951096

10961097
code = 400

tests/unit/unmarshalling/test_unmarshal.py

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import datetime
22
import uuid
33

4+
from isodate.tzinfo import UTC, FixedOffset
45
import pytest
56

67
from openapi_core.schema.media_types.models import MediaType
@@ -199,13 +200,30 @@ def test_string_format_date(self, unmarshaller_factory):
199200

200201
assert result == datetime.date(2018, 1, 2)
201202

202-
def test_string_format_datetime(self, unmarshaller_factory):
203+
def test_string_format_datetime_invalid(self, unmarshaller_factory):
204+
schema = Schema('string', schema_format='date-time')
205+
value = '2018-01-02T00:00:00'
206+
207+
with pytest.raises(InvalidSchemaValue):
208+
unmarshaller_factory(schema)(value)
209+
210+
def test_string_format_datetime_utc(self, unmarshaller_factory):
203211
schema = Schema('string', schema_format='date-time')
204212
value = '2018-01-02T00:00:00Z'
205213

206214
result = unmarshaller_factory(schema)(value)
207215

208-
assert result == datetime.datetime(2018, 1, 2, 0, 0)
216+
tzinfo = UTC
217+
assert result == datetime.datetime(2018, 1, 2, 0, 0, tzinfo=tzinfo)
218+
219+
def test_string_format_datetime_tz(self, unmarshaller_factory):
220+
schema = Schema('string', schema_format='date-time')
221+
value = '2020-04-01T12:00:00+02:00'
222+
223+
result = unmarshaller_factory(schema)(value)
224+
225+
tzinfo = FixedOffset(2)
226+
assert result == datetime.datetime(2020, 4, 1, 12, 0, 0, tzinfo=tzinfo)
209227

210228
def test_string_format_custom(self, unmarshaller_factory):
211229
formatted = 'x-custom'
@@ -408,6 +426,18 @@ def test_number_format_double(self, unmarshaller_factory):
408426

409427
assert result == 1.2
410428

429+
def test_object_nullable(self, unmarshaller_factory):
430+
schema = Schema(
431+
'object',
432+
properties={
433+
'foo': Schema('object', nullable=True),
434+
},
435+
)
436+
value = {'foo': None}
437+
result = unmarshaller_factory(schema)(value)
438+
439+
assert result == {'foo': None}
440+
411441
def test_schema_any_one_of(self, unmarshaller_factory):
412442
schema = Schema(one_of=[
413443
Schema('string'),

0 commit comments

Comments
 (0)