serializer: fix and test for KeyError '$type'

This commit is contained in:
Dan Bungert 2022-01-25 13:54:36 -07:00
parent d158d4e701
commit 37cbfb0224
2 changed files with 20 additions and 0 deletions

View File

@ -194,6 +194,13 @@ class Serializer:
args = {} args = {}
fields = {field.name: field for field in attr.fields(annotation)} fields = {field.name: field for field in attr.fields(annotation)}
for key in value.keys(): for key in value.keys():
if key not in fields and key == '$type':
# Union types can contain a '$type' field that is not
# actually one of the keys. This happens if a object is
# serialized as part of a Union, sent to an API caller,
# then received back on a different endpoint that isn't a
# Union.
continue
args.update(self._deserialize_field( args.update(self._deserialize_field(
fields[key], value[key], path)) fields[key], value[key], path))
return annotation(**args) return annotation(**args)

View File

@ -156,6 +156,19 @@ class TestSerializer(CommonSerializerTests, unittest.TestCase):
} }
self.assertSerialization(typing.Union[Data, Container], data, expected) self.assertSerialization(typing.Union[Data, Container], data, expected)
def test_arbitrary_types_may_have_type_field(self):
# The serializer will add a $type field to data elements in a Union.
# If we then take that serialized value and fling it back to another
# API entrypoint, one that isn't taking a Union, it must be cool with
# the excess $type field.
data = {
'$type': 'Data',
'field1': '1',
'field2': 2,
}
expected = Data(field1='1', field2=2)
self.assertDeserializesTo(Data, data, expected)
class TestCompactSerializer(CommonSerializerTests, unittest.TestCase): class TestCompactSerializer(CommonSerializerTests, unittest.TestCase):