From 3d45523712173e2bba03b82ea91dc5bcded80f93 Mon Sep 17 00:00:00 2001 From: Laurent Mazuel Date: Mon, 6 Apr 2020 09:08:59 -0700 Subject: [PATCH] Add time type to serialization (#196) --- msrest/serialization.py | 30 ++++++++++++++++++++++++++++++ tests/test_serialization.py | 17 ++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/msrest/serialization.py b/msrest/serialization.py index 86bcab7..27fb7e9 100644 --- a/msrest/serialization.py +++ b/msrest/serialization.py @@ -416,6 +416,7 @@ class Serializer(object): 'unix-time': Serializer.serialize_unix, 'duration': Serializer.serialize_duration, 'date': Serializer.serialize_date, + 'time': Serializer.serialize_time, 'decimal': Serializer.serialize_decimal, 'long': Serializer.serialize_long, 'bytearray': Serializer.serialize_bytearray, @@ -999,6 +1000,20 @@ class Serializer(object): t = "{:04}-{:02}-{:02}".format(attr.year, attr.month, attr.day) return t + @staticmethod + def serialize_time(attr, **kwargs): + """Serialize Time object into ISO-8601 formatted string. + + :param datetime.time attr: Object to be serialized. + :rtype: str + """ + if isinstance(attr, str): + attr = isodate.parse_time(attr) + t = "{:02}:{:02}:{:02}".format(attr.hour, attr.minute, attr.second) + if attr.microsecond: + t += ".{:02}".format(attr.microsecond) + return t + @staticmethod def serialize_duration(attr, **kwargs): """Serialize TimeDelta object into ISO-8601 formatted string. @@ -1230,6 +1245,7 @@ class Deserializer(object): 'unix-time': Deserializer.deserialize_unix, 'duration': Deserializer.deserialize_duration, 'date': Deserializer.deserialize_date, + 'time': Deserializer.deserialize_time, 'decimal': Deserializer.deserialize_decimal, 'long': Deserializer.deserialize_long, 'bytearray': Deserializer.deserialize_bytearray, @@ -1763,6 +1779,20 @@ class Deserializer(object): # This must NOT use defaultmonth/defaultday. Using None ensure this raises an exception. return isodate.parse_date(attr, defaultmonth=None, defaultday=None) + @staticmethod + def deserialize_time(attr): + """Deserialize ISO-8601 formatted string into time object. + + :param str attr: response string to be deserialized. + :rtype: datetime.time + :raises: DeserializationError if string format invalid. + """ + if isinstance(attr, ET.Element): + attr = attr.text + if re.search(r"[^\W\d_]", attr, re.I + re.U): + raise DeserializationError("Date must have only digits and -. Received: %s" % attr) + return isodate.parse_time(attr) + @staticmethod def deserialize_rfc(attr): """Deserialize RFC-1123 formatted string into Datetime object. diff --git a/tests/test_serialization.py b/tests/test_serialization.py index b7e98a1..4b3f537 100644 --- a/tests/test_serialization.py +++ b/tests/test_serialization.py @@ -30,7 +30,7 @@ import json import isodate import logging from enum import Enum -from datetime import datetime, timedelta, date +from datetime import datetime, timedelta, date, time import unittest import xml.etree.ElementTree as ET @@ -800,6 +800,14 @@ class TestRuntimeSerialized(unittest.TestCase): date_str = Serializer.serialize_iso(date_obj) assert date_str == '2012-02-24T00:53:52.780Z' + def test_serialize_time(self): + + time_str = Serializer.serialize_time(time(11,22,33)) + assert time_str == "11:22:33" + + time_str = Serializer.serialize_time(time(11,22,33,444)) + assert time_str == "11:22:33.444" + def test_serialize_primitive_types(self): a = self.s.serialize_data(1, 'int') @@ -1814,6 +1822,13 @@ class TestRuntimeDeserialized(unittest.TestCase): with self.assertRaises(DeserializationError): a = Deserializer.deserialize_date('201O-18-90') + def test_deserialize_time(self): + a = Deserializer.deserialize_time('11:22:33') + assert time(11,22,33) == a + + with self.assertRaises(DeserializationError): + Deserializer.deserialize_time('1O:22:33') + def test_deserialize_datetime(self): a = Deserializer.deserialize_iso('9999-12-31T23:59:59+23:59')