[python] Fixes a breakage while deserializing the read-only attributes (#10155)

* fixes a breakage while deserializing the read-only attributes

* updating generated samples

* taking care of the PR comments

* updating samples

* protect against cases where _spec_property_naming may not be present

* updating samples

* adding tests for this issue

* other generated files

* taking care of the comments

* updating the generated samples

Co-authored-by: Aanisha Mishra <aanisha.mishra05@gmail.com>
This commit is contained in:
Vikrant Balyan
2021-08-19 00:31:58 +05:30
committed by GitHub
parent a7de7095a7
commit 245aec14eb
16 changed files with 176 additions and 24 deletions

View File

@@ -1450,7 +1450,10 @@ def get_allof_instances(self, model_args, constant_args):
for allof_class in self._composed_schemas['allOf']:
try:
allof_instance = allof_class(**model_args, **constant_args)
if constant_args.get('_spec_property_naming'):
allof_instance = allof_class._from_openapi_data(**model_args, **constant_args)
else:
allof_instance = allof_class(**model_args, **constant_args)
composed_instances.append(allof_instance)
except Exception as ex:
raise ApiValueError(
@@ -1512,10 +1515,16 @@ def get_oneof_instance(cls, model_kwargs, constant_kwargs, model_arg=None):
try:
if not single_value_input:
oneof_instance = oneof_class(**model_kwargs, **constant_kwargs)
if constant_kwargs.get('_spec_property_naming'):
oneof_instance = oneof_class._from_openapi_data(**model_kwargs, **constant_kwargs)
else:
oneof_instance = oneof_class(**model_kwargs, **constant_kwargs)
else:
if issubclass(oneof_class, ModelSimple):
oneof_instance = oneof_class(model_arg, **constant_kwargs)
if constant_kwargs.get('_spec_property_naming'):
oneof_instance = oneof_class._from_openapi_data(model_arg, **constant_kwargs)
else:
oneof_instance = oneof_class(model_arg, **constant_kwargs)
elif oneof_class in PRIMITIVE_TYPES:
oneof_instance = validate_and_convert_types(
model_arg,
@@ -1570,7 +1579,10 @@ def get_anyof_instances(self, model_args, constant_args):
continue
try:
anyof_instance = anyof_class(**model_args, **constant_args)
if constant_args.get('_spec_property_naming'):
anyof_instance = anyof_class._from_openapi_data(**model_args, **constant_args)
else:
anyof_instance = anyof_class(**model_args, **constant_args)
anyof_instances.append(anyof_instance)
except Exception:
pass

View File

@@ -1666,6 +1666,10 @@ components:
color:
type: string
default: red
tail:
type: boolean
default: true
readOnly: true
AnimalFarm:
type: array
items:

View File

@@ -1747,7 +1747,10 @@ def get_allof_instances(self, model_args, constant_args):
for allof_class in self._composed_schemas['allOf']:
try:
allof_instance = allof_class(**model_args, **constant_args)
if constant_args.get('_spec_property_naming'):
allof_instance = allof_class._from_openapi_data(**model_args, **constant_args)
else:
allof_instance = allof_class(**model_args, **constant_args)
composed_instances.append(allof_instance)
except Exception as ex:
raise ApiValueError(
@@ -1809,10 +1812,16 @@ def get_oneof_instance(cls, model_kwargs, constant_kwargs, model_arg=None):
try:
if not single_value_input:
oneof_instance = oneof_class(**model_kwargs, **constant_kwargs)
if constant_kwargs.get('_spec_property_naming'):
oneof_instance = oneof_class._from_openapi_data(**model_kwargs, **constant_kwargs)
else:
oneof_instance = oneof_class(**model_kwargs, **constant_kwargs)
else:
if issubclass(oneof_class, ModelSimple):
oneof_instance = oneof_class(model_arg, **constant_kwargs)
if constant_kwargs.get('_spec_property_naming'):
oneof_instance = oneof_class._from_openapi_data(model_arg, **constant_kwargs)
else:
oneof_instance = oneof_class(model_arg, **constant_kwargs)
elif oneof_class in PRIMITIVE_TYPES:
oneof_instance = validate_and_convert_types(
model_arg,
@@ -1867,7 +1876,10 @@ def get_anyof_instances(self, model_args, constant_args):
continue
try:
anyof_instance = anyof_class(**model_args, **constant_args)
if constant_args.get('_spec_property_naming'):
anyof_instance = anyof_class._from_openapi_data(**model_args, **constant_args)
else:
anyof_instance = anyof_class(**model_args, **constant_args)
anyof_instances.append(anyof_instance)
except Exception:
pass

View File

@@ -1747,7 +1747,10 @@ def get_allof_instances(self, model_args, constant_args):
for allof_class in self._composed_schemas['allOf']:
try:
allof_instance = allof_class(**model_args, **constant_args)
if constant_args.get('_spec_property_naming'):
allof_instance = allof_class._from_openapi_data(**model_args, **constant_args)
else:
allof_instance = allof_class(**model_args, **constant_args)
composed_instances.append(allof_instance)
except Exception as ex:
raise ApiValueError(
@@ -1809,10 +1812,16 @@ def get_oneof_instance(cls, model_kwargs, constant_kwargs, model_arg=None):
try:
if not single_value_input:
oneof_instance = oneof_class(**model_kwargs, **constant_kwargs)
if constant_kwargs.get('_spec_property_naming'):
oneof_instance = oneof_class._from_openapi_data(**model_kwargs, **constant_kwargs)
else:
oneof_instance = oneof_class(**model_kwargs, **constant_kwargs)
else:
if issubclass(oneof_class, ModelSimple):
oneof_instance = oneof_class(model_arg, **constant_kwargs)
if constant_kwargs.get('_spec_property_naming'):
oneof_instance = oneof_class._from_openapi_data(model_arg, **constant_kwargs)
else:
oneof_instance = oneof_class(model_arg, **constant_kwargs)
elif oneof_class in PRIMITIVE_TYPES:
oneof_instance = validate_and_convert_types(
model_arg,
@@ -1867,7 +1876,10 @@ def get_anyof_instances(self, model_args, constant_args):
continue
try:
anyof_instance = anyof_class(**model_args, **constant_args)
if constant_args.get('_spec_property_naming'):
anyof_instance = anyof_class._from_openapi_data(**model_args, **constant_args)
else:
anyof_instance = anyof_class(**model_args, **constant_args)
anyof_instances.append(anyof_instance)
except Exception:
pass

View File

@@ -1747,7 +1747,10 @@ def get_allof_instances(self, model_args, constant_args):
for allof_class in self._composed_schemas['allOf']:
try:
allof_instance = allof_class(**model_args, **constant_args)
if constant_args.get('_spec_property_naming'):
allof_instance = allof_class._from_openapi_data(**model_args, **constant_args)
else:
allof_instance = allof_class(**model_args, **constant_args)
composed_instances.append(allof_instance)
except Exception as ex:
raise ApiValueError(
@@ -1809,10 +1812,16 @@ def get_oneof_instance(cls, model_kwargs, constant_kwargs, model_arg=None):
try:
if not single_value_input:
oneof_instance = oneof_class(**model_kwargs, **constant_kwargs)
if constant_kwargs.get('_spec_property_naming'):
oneof_instance = oneof_class._from_openapi_data(**model_kwargs, **constant_kwargs)
else:
oneof_instance = oneof_class(**model_kwargs, **constant_kwargs)
else:
if issubclass(oneof_class, ModelSimple):
oneof_instance = oneof_class(model_arg, **constant_kwargs)
if constant_kwargs.get('_spec_property_naming'):
oneof_instance = oneof_class._from_openapi_data(model_arg, **constant_kwargs)
else:
oneof_instance = oneof_class(model_arg, **constant_kwargs)
elif oneof_class in PRIMITIVE_TYPES:
oneof_instance = validate_and_convert_types(
model_arg,
@@ -1867,7 +1876,10 @@ def get_anyof_instances(self, model_args, constant_args):
continue
try:
anyof_instance = anyof_class(**model_args, **constant_args)
if constant_args.get('_spec_property_naming'):
anyof_instance = anyof_class._from_openapi_data(**model_args, **constant_args)
else:
anyof_instance = anyof_class(**model_args, **constant_args)
anyof_instances.append(anyof_instance)
except Exception:
pass

View File

@@ -1747,7 +1747,10 @@ def get_allof_instances(self, model_args, constant_args):
for allof_class in self._composed_schemas['allOf']:
try:
allof_instance = allof_class(**model_args, **constant_args)
if constant_args.get('_spec_property_naming'):
allof_instance = allof_class._from_openapi_data(**model_args, **constant_args)
else:
allof_instance = allof_class(**model_args, **constant_args)
composed_instances.append(allof_instance)
except Exception as ex:
raise ApiValueError(
@@ -1809,10 +1812,16 @@ def get_oneof_instance(cls, model_kwargs, constant_kwargs, model_arg=None):
try:
if not single_value_input:
oneof_instance = oneof_class(**model_kwargs, **constant_kwargs)
if constant_kwargs.get('_spec_property_naming'):
oneof_instance = oneof_class._from_openapi_data(**model_kwargs, **constant_kwargs)
else:
oneof_instance = oneof_class(**model_kwargs, **constant_kwargs)
else:
if issubclass(oneof_class, ModelSimple):
oneof_instance = oneof_class(model_arg, **constant_kwargs)
if constant_kwargs.get('_spec_property_naming'):
oneof_instance = oneof_class._from_openapi_data(model_arg, **constant_kwargs)
else:
oneof_instance = oneof_class(model_arg, **constant_kwargs)
elif oneof_class in PRIMITIVE_TYPES:
oneof_instance = validate_and_convert_types(
model_arg,
@@ -1867,7 +1876,10 @@ def get_anyof_instances(self, model_args, constant_args):
continue
try:
anyof_instance = anyof_class(**model_args, **constant_args)
if constant_args.get('_spec_property_naming'):
anyof_instance = anyof_class._from_openapi_data(**model_args, **constant_args)
else:
anyof_instance = anyof_class(**model_args, **constant_args)
anyof_instances.append(anyof_instance)
except Exception:
pass

View File

@@ -6,6 +6,7 @@ Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**class_name** | **str** | |
**color** | **str** | | [optional] if omitted the server will use the default value of "red"
**tail** | **bool** | | [optional] [readonly] if omitted the server will use the default value of True
**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

View File

@@ -7,6 +7,7 @@ Name | Type | Description | Notes
**class_name** | **str** | |
**declawed** | **bool** | | [optional]
**color** | **str** | | [optional] if omitted the server will use the default value of "red"
**tail** | **bool** | | [optional] [readonly] if omitted the server will use the default value of True
**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

View File

@@ -6,6 +6,7 @@ this is a model that allows payloads of type object or number
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**color** | **str** | | [optional] if omitted the server will use the default value of "red"
**tail** | **bool** | | [optional] [readonly] if omitted the server will use the default value of True
**class_name** | **str** | | [optional]
**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional]

View File

@@ -7,6 +7,7 @@ Name | Type | Description | Notes
**class_name** | **str** | |
**breed** | **str** | | [optional]
**color** | **str** | | [optional] if omitted the server will use the default value of "red"
**tail** | **bool** | | [optional] [readonly] if omitted the server will use the default value of True
**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

View File

@@ -91,6 +91,7 @@ class Animal(ModelNormal):
return {
'class_name': (str,), # noqa: E501
'color': (str,), # noqa: E501
'tail': (bool,), # noqa: E501
}
@cached_property
@@ -107,9 +108,11 @@ class Animal(ModelNormal):
attribute_map = {
'class_name': 'className', # noqa: E501
'color': 'color', # noqa: E501
'tail': 'tail', # noqa: E501
}
read_only_vars = {
'tail', # noqa: E501
}
_composed_schemas = {}
@@ -154,6 +157,7 @@ class Animal(ModelNormal):
through its discriminator because we passed in
_visited_composed_classes = (Animal,)
color (str): [optional] if omitted the server will use the default value of "red" # noqa: E501
tail (bool): [optional] if omitted the server will use the default value of True # noqa: E501
"""
_check_type = kwargs.pop('_check_type', True)
@@ -240,6 +244,7 @@ class Animal(ModelNormal):
through its discriminator because we passed in
_visited_composed_classes = (Animal,)
color (str): [optional] if omitted the server will use the default value of "red" # noqa: E501
tail (bool): [optional] if omitted the server will use the default value of True # noqa: E501
"""
_check_type = kwargs.pop('_check_type', True)

View File

@@ -92,6 +92,7 @@ class Cat(ModelComposed):
'class_name': (str,), # noqa: E501
'declawed': (bool,), # noqa: E501
'color': (str,), # noqa: E501
'tail': (bool,), # noqa: E501
}
@cached_property
@@ -106,9 +107,11 @@ class Cat(ModelComposed):
'class_name': 'className', # noqa: E501
'declawed': 'declawed', # noqa: E501
'color': 'color', # noqa: E501
'tail': 'tail', # noqa: E501
}
read_only_vars = {
'tail', # noqa: E501
}
@classmethod
@@ -150,6 +153,7 @@ class Cat(ModelComposed):
_visited_composed_classes = (Animal,)
declawed (bool): [optional] # noqa: E501
color (str): [optional] if omitted the server will use the default value of "red" # noqa: E501
tail (bool): [optional] if omitted the server will use the default value of True # noqa: E501
"""
_check_type = kwargs.pop('_check_type', True)
@@ -252,6 +256,7 @@ class Cat(ModelComposed):
_visited_composed_classes = (Animal,)
declawed (bool): [optional] # noqa: E501
color (str): [optional] if omitted the server will use the default value of "red" # noqa: E501
tail (bool): [optional] if omitted the server will use the default value of True # noqa: E501
"""
_check_type = kwargs.pop('_check_type', True)

View File

@@ -90,6 +90,7 @@ class ComposedOneOfNumberWithValidations(ModelComposed):
lazy_import()
return {
'color': (str,), # noqa: E501
'tail': (bool,), # noqa: E501
'class_name': (str,), # noqa: E501
}
@@ -100,10 +101,12 @@ class ComposedOneOfNumberWithValidations(ModelComposed):
attribute_map = {
'color': 'color', # noqa: E501
'tail': 'tail', # noqa: E501
'class_name': 'className', # noqa: E501
}
read_only_vars = {
'tail', # noqa: E501
}
@classmethod
@@ -143,6 +146,7 @@ class ComposedOneOfNumberWithValidations(ModelComposed):
through its discriminator because we passed in
_visited_composed_classes = (Animal,)
color (str): [optional] if omitted the server will use the default value of "red" # noqa: E501
tail (bool): [optional] if omitted the server will use the default value of True # noqa: E501
class_name (str): [optional] # noqa: E501
"""
@@ -244,6 +248,7 @@ class ComposedOneOfNumberWithValidations(ModelComposed):
through its discriminator because we passed in
_visited_composed_classes = (Animal,)
color (str): [optional] if omitted the server will use the default value of "red" # noqa: E501
tail (bool): [optional] if omitted the server will use the default value of True # noqa: E501
class_name (str): [optional] # noqa: E501
"""

View File

@@ -92,6 +92,7 @@ class Dog(ModelComposed):
'class_name': (str,), # noqa: E501
'breed': (str,), # noqa: E501
'color': (str,), # noqa: E501
'tail': (bool,), # noqa: E501
}
@cached_property
@@ -106,9 +107,11 @@ class Dog(ModelComposed):
'class_name': 'className', # noqa: E501
'breed': 'breed', # noqa: E501
'color': 'color', # noqa: E501
'tail': 'tail', # noqa: E501
}
read_only_vars = {
'tail', # noqa: E501
}
@classmethod
@@ -150,6 +153,7 @@ class Dog(ModelComposed):
_visited_composed_classes = (Animal,)
breed (str): [optional] # noqa: E501
color (str): [optional] if omitted the server will use the default value of "red" # noqa: E501
tail (bool): [optional] if omitted the server will use the default value of True # noqa: E501
"""
_check_type = kwargs.pop('_check_type', True)
@@ -252,6 +256,7 @@ class Dog(ModelComposed):
_visited_composed_classes = (Animal,)
breed (str): [optional] # noqa: E501
color (str): [optional] if omitted the server will use the default value of "red" # noqa: E501
tail (bool): [optional] if omitted the server will use the default value of True # noqa: E501
"""
_check_type = kwargs.pop('_check_type', True)

View File

@@ -1747,7 +1747,10 @@ def get_allof_instances(self, model_args, constant_args):
for allof_class in self._composed_schemas['allOf']:
try:
allof_instance = allof_class(**model_args, **constant_args)
if constant_args.get('_spec_property_naming'):
allof_instance = allof_class._from_openapi_data(**model_args, **constant_args)
else:
allof_instance = allof_class(**model_args, **constant_args)
composed_instances.append(allof_instance)
except Exception as ex:
raise ApiValueError(
@@ -1809,10 +1812,16 @@ def get_oneof_instance(cls, model_kwargs, constant_kwargs, model_arg=None):
try:
if not single_value_input:
oneof_instance = oneof_class(**model_kwargs, **constant_kwargs)
if constant_kwargs.get('_spec_property_naming'):
oneof_instance = oneof_class._from_openapi_data(**model_kwargs, **constant_kwargs)
else:
oneof_instance = oneof_class(**model_kwargs, **constant_kwargs)
else:
if issubclass(oneof_class, ModelSimple):
oneof_instance = oneof_class(model_arg, **constant_kwargs)
if constant_kwargs.get('_spec_property_naming'):
oneof_instance = oneof_class._from_openapi_data(model_arg, **constant_kwargs)
else:
oneof_instance = oneof_class(model_arg, **constant_kwargs)
elif oneof_class in PRIMITIVE_TYPES:
oneof_instance = validate_and_convert_types(
model_arg,
@@ -1867,7 +1876,10 @@ def get_anyof_instances(self, model_args, constant_args):
continue
try:
anyof_instance = anyof_class(**model_args, **constant_args)
if constant_args.get('_spec_property_naming'):
anyof_instance = anyof_class._from_openapi_data(**model_args, **constant_args)
else:
anyof_instance = anyof_class(**model_args, **constant_args)
anyof_instances.append(anyof_instance)
except Exception:
pass

View File

@@ -0,0 +1,52 @@
# coding: utf-8
"""
OpenAPI Petstore
This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ # noqa: E501
The version of the OpenAPI document: 1.0.0
Generated by: https://openapi-generator.tech
"""
import sys
import unittest
import json
from collections import namedtuple
import petstore_api
from petstore_api.model.animal import Animal
from petstore_api.model.dog import Dog
class TestReadOnlyForComposedSchema(unittest.TestCase):
"""TestReadOnlyForComposedSchema unit test"""
def setUp(self):
pass
def tearDown(self):
pass
def testReadOnlyForComposedSchema(self):
"""Test ReadOnlyForComposedSchema"""
MockResponse = namedtuple('MockResponse', 'data')
client = petstore_api.ApiClient()
""" deserialize dict(str, Enum_Test) """
data = {
"Dog": {
"class_name": "Dog",
"breed": "BullDog",
"color": "Black",
"tail": True
}
}
response = MockResponse(data=json.dumps(data))
deserialized = client.deserialize(response, ({str: (Dog,)},), True)
assert isinstance(deserialized, dict)
assert isinstance(deserialized['Dog'], Dog)
if __name__ == '__main__':
unittest.main()