Skip to content

Commit f606cfb

Browse files
committed
adds Recursive Discriminator support
1 parent 9d4c211 commit f606cfb

2 files changed

Lines changed: 38 additions & 2 deletions

File tree

modules/openapi-generator/src/main/resources/python/python-experimental/model_utils.mustache

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -592,8 +592,11 @@ def deserialize_model(model_data, model_class, path_to_item, check_type,
592592

593593
used_model_class = model_class
594594
if model_class.discriminator() is not None:
595-
used_model_class = model_class.get_discriminator_class(
596-
from_server, model_data)
595+
used_model_class = recursive_discriminator_lookup(model_class, from_server, model_data)
596+
597+
# This is the case if the used_model_class isn't a subclass but rather the parent class itself
598+
if not used_model_class:
599+
used_model_class = model_class
597600

598601
if issubclass(used_model_class, ModelSimple):
599602
instance = used_model_class(value=model_data, **kw_args)
@@ -609,6 +612,35 @@ def deserialize_model(model_data, model_class, path_to_item, check_type,
609612
instance = used_model_class(**kw_args)
610613
return instance
611614

615+
recursive_discriminators_cache = {}
616+
617+
def recursive_discriminators(model_class):
618+
"""
619+
Return the discriminator mapping for all possible subtypes (recursively found down to the leaves)
620+
:param model_class:
621+
:return:
622+
"""
623+
if model_class in recursive_discriminators_cache:
624+
return recursive_discriminators_cache[model_class]
625+
recursive_discriminated_types = model_class.discriminator()
626+
if not recursive_discriminated_types:
627+
return {}
628+
for discriminator_key, discriminator_dict in model_class.discriminator().items():
629+
for child_class in discriminator_dict.values():
630+
for child_discriminator_key, child_discriminator_dict in recursive_discriminators(child_class).items():
631+
if child_discriminator_key in recursive_discriminated_types:
632+
recursive_discriminated_types[child_discriminator_key].update(child_discriminator_dict)
633+
else:
634+
recursive_discriminated_types[child_discriminator_key] = child_discriminator_dict
635+
recursive_discriminators_cache[model_class] = recursive_discriminated_types
636+
return recursive_discriminated_types
637+
638+
def recursive_discriminator_lookup(model_class, from_server, model_data):
639+
discr_propertyname_py = list(model_class.discriminator().keys())[0]
640+
try:
641+
return recursive_discriminators(model_class)[discr_propertyname_py][model_data[model_class.attribute_map[discr_propertyname_py]]]
642+
except KeyError as e:
643+
return
612644

613645
def deserialize_file(response_data, configuration, content_disposition=None):
614646
"""Deserializes body to file

samples/client/petstore/python-experimental/petstore_api/model_utils.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -849,6 +849,10 @@ def deserialize_model(model_data, model_class, path_to_item, check_type,
849849
used_model_class = model_class.get_discriminator_class(
850850
from_server, model_data)
851851

852+
# This is the case if the used_model_class isn't a subclass but rather the parent class itself
853+
if not used_model_class:
854+
used_model_class = model_class
855+
852856
if issubclass(used_model_class, ModelSimple):
853857
instance = used_model_class(value=model_data, **kw_args)
854858
return instance

0 commit comments

Comments
 (0)