Repository: Azure/msrest-for-python

Issue:
Serialization for non-standard types yields incorrect output
Hi,

I am using the event grid client SDK in python to generate custom events. I have come across an issue I can't seem to solve without going away from the event grid SDK. 

The problem is that the event grid model serializer does not give me the correct output for when including types that are not the basic types. A simple reproducible example:

```
from azure.eventgrid.models import EventGridEvent
import datetime
import uuid

event=EventGridEvent(
            topic="test",
            id=uuid.uuid4(),
            subject="testUpdated",
            data={"time":datetime.datetime.now().replace(tzinfo=datetime.timezone.utc)},
            event_type="test.test",
            event_time=datetime.datetime.now().replace(tzinfo=datetime.timezone.utc),
            data_version=2.0,
)

print(event.serialize())
```

This would return

`
{'id': '3e02a22c-f327-4f62-af25-b71e0865888b',
 'topic': 'product',
 'subject': 'ProductUpdated',
 'data': {'time': '2020-09-07 10:37:08.348679+00:00'},
 'eventType': 'supplychain.product',
 'eventTime': '2020-09-07T10:37:08.348679Z',
 'dataVersion': '2.0'}
`

the serialize is not called by me in the code I actually use, but it looks like that is what is called behind the scenes when I send off the event. I want the datetime (the key "time" in the above example) to be serialized just as the parent-level "event_time". My problem is not only with datetime as in the current example, but also with decimals.

I guess this fits in this repo and not in the EventGrid SDK repo, but feel free to redirect me there.






Discussion:
codecov-commenter: # [Codecov](https://codecov.io/gh/Azure/msrest-for-python/pull/224?src=pr&el=h1) Report
> Merging [#224](https://codecov.io/gh/Azure/msrest-for-python/pull/224?src=pr&el=desc) into [master](https://codecov.io/gh/Azure/msrest-for-python/commit/98e2ebe7e5ed8a656f333963339ad8d20fc330d3?el=desc) will **decrease** coverage by `4.01%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/Azure/msrest-for-python/pull/224/graphs/tree.svg?width=650&height=150&src=pr&token=Lny6ZO1MUF)](https://codecov.io/gh/Azure/msrest-for-python/pull/224?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #224      +/-   ##
==========================================
- Coverage   86.23%   82.21%   -4.02%     
==========================================
  Files          25       16       -9     
  Lines        2738     2266     -472     
==========================================
- Hits         2361     1863     -498     
- Misses        377      403      +26     
```


| [Impacted Files](https://codecov.io/gh/Azure/msrest-for-python/pull/224?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [msrest/serialization.py](https://codecov.io/gh/Azure/msrest-for-python/pull/224/diff?src=pr&el=tree#diff-bXNyZXN0L3NlcmlhbGl6YXRpb24ucHk=) | `82.97% <100.00%> (-8.15%)` | :arrow_down: |
| [msrest/polling/\_\_init\_\_.py](https://codecov.io/gh/Azure/msrest-for-python/pull/224/diff?src=pr&el=tree#diff-bXNyZXN0L3BvbGxpbmcvX19pbml0X18ucHk=) | `66.66% <0.00%> (-33.34%)` | :arrow_down: |
| [msrest/pipeline/universal.py](https://codecov.io/gh/Azure/msrest-for-python/pull/224/diff?src=pr&el=tree#diff-bXNyZXN0L3BpcGVsaW5lL3VuaXZlcnNhbC5weQ==) | `90.19% <0.00%> (-4.04%)` | :arrow_down: |
| [msrest/paging.py](https://codecov.io/gh/Azure/msrest-for-python/pull/224/diff?src=pr&el=tree#diff-bXNyZXN0L3BhZ2luZy5weQ==) | `87.71% <0.00%> (-3.81%)` | :arrow_down: |
| [msrest/universal\_http/\_\_init\_\_.py](https://codecov.io/gh/Azure/msrest-for-python/pull/224/diff?src=pr&el=tree#diff-bXNyZXN0L3VuaXZlcnNhbF9odHRwL19faW5pdF9fLnB5) | `71.50% <0.00%> (-2.74%)` | :arrow_down: |
| [msrest/pipeline/\_\_init\_\_.py](https://codecov.io/gh/Azure/msrest-for-python/pull/224/diff?src=pr&el=tree#diff-bXNyZXN0L3BpcGVsaW5lL19faW5pdF9fLnB5) | `88.00% <0.00%> (-2.63%)` | :arrow_down: |
| [msrest/configuration.py](https://codecov.io/gh/Azure/msrest-for-python/pull/224/diff?src=pr&el=tree#diff-bXNyZXN0L2NvbmZpZ3VyYXRpb24ucHk=) | `75.86% <0.00%> (-2.27%)` | :arrow_down: |
| [msrest/polling/poller.py](https://codecov.io/gh/Azure/msrest-for-python/pull/224/diff?src=pr&el=tree#diff-bXNyZXN0L3BvbGxpbmcvcG9sbGVyLnB5) | `97.80% <0.00%> (-2.20%)` | :arrow_down: |
| [msrest/service\_client.py](https://codecov.io/gh/Azure/msrest-for-python/pull/224/diff?src=pr&el=tree#diff-bXNyZXN0L3NlcnZpY2VfY2xpZW50LnB5) | `79.57% <0.00%> (-2.12%)` | :arrow_down: |
| ... and [11 more](https://codecov.io/gh/Azure/msrest-for-python/pull/224/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/Azure/msrest-for-python/pull/224?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/Azure/msrest-for-python/pull/224?src=pr&el=footer). Last update [98e2ebe...b5d2aac](https://codecov.io/gh/Azure/msrest-for-python/pull/224?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/msrest/serialization.py b/msrest/serialization.py
index f9037b9..378de20 100644
--- a/msrest/serialization.py
+++ b/msrest/serialization.py
@@ -953,6 +953,16 @@ class Serializer(object):
             return self.serialize_long(attr)
         if obj_type is unicode_str:
             return self.serialize_unicode(attr)
+        if obj_type is datetime.datetime:
+            return self.serialize_iso(attr)
+        if obj_type is datetime.date:
+            return self.serialize_date(attr)
+        if obj_type is datetime.time:
+            return self.serialize_time(attr)
+        if obj_type is datetime.timedelta:
+            return self.serialize_duration(attr)
+        if obj_type is decimal.Decimal:
+            return self.serialize_decimal(attr)
 
         # If it's a model or I know this dependency, serialize as a Model
         elif obj_type in self.dependencies.values() or isinstance(attr, Model):


Test patch:
diff --git a/tests/test_serialization.py b/tests/test_serialization.py
index ab04cfd..6837bad 100644
--- a/tests/test_serialization.py
+++ b/tests/test_serialization.py
@@ -25,6 +25,7 @@
 #
 #--------------------------------------------------------------------------
 
+from decimal import Decimal
 import sys
 import json
 import isodate
@@ -1395,6 +1396,42 @@ class TestRuntimeSerialized(unittest.TestCase):
             'data': {'id': u"\ua015"}
         }
 
+    def test_datetime_types_as_type_object(self):
+        """https://github.com/Azure/msrest-for-python/issues/223
+        """
+
+        class TestModel(Model):
+            _attribute_map = {'data': {'key': 'data', 'type': 'object'}}
+
+        m = TestModel(data = {
+            'datetime': isodate.parse_datetime('2012-02-24T00:53:52.780Z'),
+            'date': date(2019,5,1),
+            'time': time(11,12,13),
+            'timedelta': timedelta(56)
+        })
+        serialized = m.serialize()
+        assert serialized['data'] == {
+            'datetime': '2012-02-24T00:53:52.780Z',
+            'date': '2019-05-01',
+            'time': '11:12:13',
+            'timedelta': 'P56D'
+        }
+
+    def test_decimal_types_as_type_object(self):
+        """https://github.com/Azure/msrest-for-python/issues/223
+        """
+
+        class TestModel(Model):
+            _attribute_map = {'data': {'key': 'data', 'type': 'object'}}
+
+        m = TestModel(data = {
+            'decimal': Decimal('1.1'),
+        })
+        serialized = m.serialize()
+        assert serialized['data'] == {
+            'decimal': 1.1
+        }
+
     def test_json_with_xml_map(self):
         basic_json = {'age': 37, 'country': 'france'}