swagger-api / swagger-api/swagger-codegen
[PYTHON] Maps of Lists are not converted to Dictionaries
Nobody has claimed this yet.
- Dominant language
- Mustache
- Stars
- 17.8k
- Forks
- 6k
- PR merge metrics
- No merged PRs in 30d
Description
Description
Per this documentation (https://swagger.io/docs/specification/data-models/dictionaries/)
the following is a valid swagger definition for a map with a string key and a value type of a list Of other objects...
someName:
description: string map of lists example.
type: object
additionalProperties:
type: array
items:
$ref: '#/definitions/SomeOtherObject'
However when an object with the property someName is converted to a dictionary using the generated to_dict method, someName will still contain a dictionary of a list of objects rather than a dictionary of a list of dictionaries i.e. the conversion does not recurse into the list.
Swagger-codegen version
bug seems to be in latest version of source
Steps to reproduce
- Create Yaml definition with above syntax
- Generate python library
- Create an instance of an object with affected property
- call to_dict on the instance
- verify that the type() of the list items is still an Object, not a dict.
Related issues/PRs
this PR came close to fixing things but not quite..
https://github.com/swagger-api/swagger-codegen/pull/2063/files
Suggest a fix/enhancement
It's a bit of a brain twister but I think to_dict should look more like this:-
def to_dict(self):
"""Returns the model properties as a dict"""
def val_to_dict(val):
if hasattr(val, "to_dict"):
return val.to_dict()
elif isinstance(val, list):
return list(map(
lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
val
))
else:
return val
result = {}
for attr, _ in six.iteritems(self.swagger_types):
value = getattr(self, attr)
if isinstance(value, list):
result[attr] = list(map(
lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
value
))
elif hasattr(value, "to_dict"):
result[attr] = value.to_dict()
elif isinstance(value, dict):
result[attr] = dict(map(
lambda item: (item[0], val_to_dict(item[1])),
value.items()
))
else:
result[attr] = value
return result
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by generating a Python library from the Swagger definition in the reproduction steps and inspect the generated model's to_dict method. Reproduce the map-of-lists case, then compare the resulting value types with the expected nested dictionaries. Done means list items inside dictionary values are recursively converted without leaving generated objects in the result.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100