Skip to content

Commit dc8bd4d

Browse files
committed
Date-time format unmarshal tz fix
1 parent 1270d5a commit dc8bd4d

File tree

7 files changed

+29
-11
lines changed

7 files changed

+29
-11
lines changed

Diff for: openapi_core/unmarshalling/schemas/unmarshallers.py

+4-2
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(

Diff for: openapi_core/unmarshalling/schemas/util.py

-6
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

Diff for: requirements.txt

+1
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

Diff for: requirements_2.7.txt

+1
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

Diff for: setup.cfg

+1
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

Diff for: tests/integration/validation/test_petstore.py

+2-1
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

Diff for: tests/unit/unmarshalling/test_unmarshal.py

+20-2
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'

0 commit comments

Comments
 (0)