Skip to content

Commit

Permalink
Add support for marshalling dict-like objects.
Browse files Browse the repository at this point in the history
The `is_dict_like` function in `schema.py` was just checking if the
object's type was a dict.  This causes it to treat any dict subclass as
a model, which fails because dict subclasses are not models.

Updating to check if the item is an instance of `collections.Mapping`
(or `collections.abc.Mapping` on python 3) fixes this.
  • Loading branch information
obmarg committed Nov 26, 2015
1 parent 7f32ca2 commit dc46329
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 2 deletions.
8 changes: 6 additions & 2 deletions bravado_core/schema.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
from bravado_core.exception import SwaggerMappingError

try:
from collections import Mapping
except ImportError:
from collections.abc import Mapping

# 'object' and 'array' are omitted since this should really be read as
# "Swagger types that map to python primitives"
SWAGGER_PRIMITIVES = (
Expand Down Expand Up @@ -45,8 +50,7 @@ def is_dict_like(spec):
:param spec: swagger object specification in dict form
:rtype: boolean
"""
# TODO: check magic method instead
return type(spec) == dict
return isinstance(spec, Mapping)


def is_list_like(spec):
Expand Down
24 changes: 24 additions & 0 deletions tests/marshal/marshal_schema_object_test.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import copy
from collections import OrderedDict

import pytest

Expand Down Expand Up @@ -29,6 +30,29 @@ def test_dicts_can_be_used_instead_of_models(petstore_dict):
assert expected == result


def test_ordered_dicts_can_be_used_instead_of_models(petstore_dict):
petstore_spec = Spec.from_dict(petstore_dict)
pet_spec = petstore_spec.spec_dict['definitions']['Pet']
pet = OrderedDict({
'id': 1,
'name': 'Fido',
'status': 'sold',
'photoUrls': ['wagtail.png', 'bark.png'],
'category': {
'id': 200,
'name': 'friendly',
},
'tags': [
{'id': 99, 'name': 'mini'},
{'id': 100, 'name': 'brown'},
],
})
expected = copy.deepcopy(pet)
result = marshal_schema_object(petstore_spec, pet_spec, pet)
assert expected == result



def test_unknown_type_raises_error(empty_swagger_spec):
invalid_spec = {'type': 'foo'}
with pytest.raises(SwaggerMappingError) as excinfo:
Expand Down

0 comments on commit dc46329

Please sign in to comment.