mirror of
https://github.com/OpenAPITools/openapi-generator.git
synced 2025-12-09 16:56:09 +00:00
Bug - python client deserialization when attribute named self (#9006)
* fix by mapping outside of class
* tests
* regeneration and tests
* server
* INDENT
* a
* enable mapping
* Revert "server"
This reverts commit 6fc9712fb5.
* Samples regenerated
Co-authored-by: Justin Black <justin.a.black@gmail.com>
This commit is contained in:
@@ -1283,11 +1283,16 @@ def get_valid_classes_phrase(input_classes):
|
|||||||
def convert_js_args_to_python_args(fn):
|
def convert_js_args_to_python_args(fn):
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
@wraps(fn)
|
@wraps(fn)
|
||||||
def wrapped_init(self, *args, **kwargs):
|
def wrapped_init(_self, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
An attribute named `self` received from the api will conflicts with the reserved `self`
|
||||||
|
parameter of a class method. During generation, `self` attributes are mapped
|
||||||
|
to `_self` in models. Here, we name `_self` instead of `self` to avoid conflicts.
|
||||||
|
"""
|
||||||
spec_property_naming = kwargs.get('_spec_property_naming', False)
|
spec_property_naming = kwargs.get('_spec_property_naming', False)
|
||||||
if spec_property_naming:
|
if spec_property_naming:
|
||||||
kwargs = change_keys_js_to_python(kwargs, self.__class__)
|
kwargs = change_keys_js_to_python(kwargs, _self.__class__)
|
||||||
return fn(self, *args, **kwargs)
|
return fn(_self, *args, **kwargs)
|
||||||
return wrapped_init
|
return wrapped_init
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2378,6 +2378,11 @@ components:
|
|||||||
SomeObject:
|
SomeObject:
|
||||||
allOf:
|
allOf:
|
||||||
- $ref: '#/components/schemas/ObjectInterface'
|
- $ref: '#/components/schemas/ObjectInterface'
|
||||||
|
SomeObjectWithSelfAttr:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
self:
|
||||||
|
type: string
|
||||||
InlineAdditionalPropertiesRefPayload:
|
InlineAdditionalPropertiesRefPayload:
|
||||||
description: this payload is used for verification that some model_to_dict issues are fixed
|
description: this payload is used for verification that some model_to_dict issues are fixed
|
||||||
type: object
|
type: object
|
||||||
@@ -2392,4 +2397,4 @@ components:
|
|||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
nullable: true
|
nullable: true
|
||||||
|
|||||||
@@ -1565,11 +1565,16 @@ def get_valid_classes_phrase(input_classes):
|
|||||||
def convert_js_args_to_python_args(fn):
|
def convert_js_args_to_python_args(fn):
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
@wraps(fn)
|
@wraps(fn)
|
||||||
def wrapped_init(self, *args, **kwargs):
|
def wrapped_init(_self, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
An attribute named `self` received from the api will conflicts with the reserved `self`
|
||||||
|
parameter of a class method. During generation, `self` attributes are mapped
|
||||||
|
to `_self` in models. Here, we name `_self` instead of `self` to avoid conflicts.
|
||||||
|
"""
|
||||||
spec_property_naming = kwargs.get('_spec_property_naming', False)
|
spec_property_naming = kwargs.get('_spec_property_naming', False)
|
||||||
if spec_property_naming:
|
if spec_property_naming:
|
||||||
kwargs = change_keys_js_to_python(kwargs, self.__class__)
|
kwargs = change_keys_js_to_python(kwargs, _self.__class__)
|
||||||
return fn(self, *args, **kwargs)
|
return fn(_self, *args, **kwargs)
|
||||||
return wrapped_init
|
return wrapped_init
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1565,11 +1565,16 @@ def get_valid_classes_phrase(input_classes):
|
|||||||
def convert_js_args_to_python_args(fn):
|
def convert_js_args_to_python_args(fn):
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
@wraps(fn)
|
@wraps(fn)
|
||||||
def wrapped_init(self, *args, **kwargs):
|
def wrapped_init(_self, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
An attribute named `self` received from the api will conflicts with the reserved `self`
|
||||||
|
parameter of a class method. During generation, `self` attributes are mapped
|
||||||
|
to `_self` in models. Here, we name `_self` instead of `self` to avoid conflicts.
|
||||||
|
"""
|
||||||
spec_property_naming = kwargs.get('_spec_property_naming', False)
|
spec_property_naming = kwargs.get('_spec_property_naming', False)
|
||||||
if spec_property_naming:
|
if spec_property_naming:
|
||||||
kwargs = change_keys_js_to_python(kwargs, self.__class__)
|
kwargs = change_keys_js_to_python(kwargs, _self.__class__)
|
||||||
return fn(self, *args, **kwargs)
|
return fn(_self, *args, **kwargs)
|
||||||
return wrapped_init
|
return wrapped_init
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1565,11 +1565,16 @@ def get_valid_classes_phrase(input_classes):
|
|||||||
def convert_js_args_to_python_args(fn):
|
def convert_js_args_to_python_args(fn):
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
@wraps(fn)
|
@wraps(fn)
|
||||||
def wrapped_init(self, *args, **kwargs):
|
def wrapped_init(_self, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
An attribute named `self` received from the api will conflicts with the reserved `self`
|
||||||
|
parameter of a class method. During generation, `self` attributes are mapped
|
||||||
|
to `_self` in models. Here, we name `_self` instead of `self` to avoid conflicts.
|
||||||
|
"""
|
||||||
spec_property_naming = kwargs.get('_spec_property_naming', False)
|
spec_property_naming = kwargs.get('_spec_property_naming', False)
|
||||||
if spec_property_naming:
|
if spec_property_naming:
|
||||||
kwargs = change_keys_js_to_python(kwargs, self.__class__)
|
kwargs = change_keys_js_to_python(kwargs, _self.__class__)
|
||||||
return fn(self, *args, **kwargs)
|
return fn(_self, *args, **kwargs)
|
||||||
return wrapped_init
|
return wrapped_init
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ docs/ShapeInterface.md
|
|||||||
docs/ShapeOrNull.md
|
docs/ShapeOrNull.md
|
||||||
docs/SimpleQuadrilateral.md
|
docs/SimpleQuadrilateral.md
|
||||||
docs/SomeObject.md
|
docs/SomeObject.md
|
||||||
|
docs/SomeObjectWithSelfAttr.md
|
||||||
docs/SpecialModelName.md
|
docs/SpecialModelName.md
|
||||||
docs/StoreApi.md
|
docs/StoreApi.md
|
||||||
docs/StringBooleanMap.md
|
docs/StringBooleanMap.md
|
||||||
@@ -190,6 +191,7 @@ petstore_api/model/shape_interface.py
|
|||||||
petstore_api/model/shape_or_null.py
|
petstore_api/model/shape_or_null.py
|
||||||
petstore_api/model/simple_quadrilateral.py
|
petstore_api/model/simple_quadrilateral.py
|
||||||
petstore_api/model/some_object.py
|
petstore_api/model/some_object.py
|
||||||
|
petstore_api/model/some_object_with_self_attr.py
|
||||||
petstore_api/model/special_model_name.py
|
petstore_api/model/special_model_name.py
|
||||||
petstore_api/model/string_boolean_map.py
|
petstore_api/model/string_boolean_map.py
|
||||||
petstore_api/model/string_enum.py
|
petstore_api/model/string_enum.py
|
||||||
|
|||||||
@@ -212,6 +212,7 @@ Class | Method | HTTP request | Description
|
|||||||
- [ShapeOrNull](docs/ShapeOrNull.md)
|
- [ShapeOrNull](docs/ShapeOrNull.md)
|
||||||
- [SimpleQuadrilateral](docs/SimpleQuadrilateral.md)
|
- [SimpleQuadrilateral](docs/SimpleQuadrilateral.md)
|
||||||
- [SomeObject](docs/SomeObject.md)
|
- [SomeObject](docs/SomeObject.md)
|
||||||
|
- [SomeObjectWithSelfAttr](docs/SomeObjectWithSelfAttr.md)
|
||||||
- [SpecialModelName](docs/SpecialModelName.md)
|
- [SpecialModelName](docs/SpecialModelName.md)
|
||||||
- [StringBooleanMap](docs/StringBooleanMap.md)
|
- [StringBooleanMap](docs/StringBooleanMap.md)
|
||||||
- [StringEnum](docs/StringEnum.md)
|
- [StringEnum](docs/StringEnum.md)
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
# SomeObjectWithSelfAttr
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
Name | Type | Description | Notes
|
||||||
|
------------ | ------------- | ------------- | -------------
|
||||||
|
**_self** | **str** | | [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)
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,166 @@
|
|||||||
|
"""
|
||||||
|
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 re # noqa: F401
|
||||||
|
import sys # noqa: F401
|
||||||
|
|
||||||
|
from petstore_api.model_utils import ( # noqa: F401
|
||||||
|
ApiTypeError,
|
||||||
|
ModelComposed,
|
||||||
|
ModelNormal,
|
||||||
|
ModelSimple,
|
||||||
|
cached_property,
|
||||||
|
change_keys_js_to_python,
|
||||||
|
convert_js_args_to_python_args,
|
||||||
|
date,
|
||||||
|
datetime,
|
||||||
|
file_type,
|
||||||
|
none_type,
|
||||||
|
validate_get_composed_info,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class SomeObjectWithSelfAttr(ModelNormal):
|
||||||
|
"""NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
Ref: https://openapi-generator.tech
|
||||||
|
|
||||||
|
Do not edit the class manually.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
allowed_values (dict): The key is the tuple path to the attribute
|
||||||
|
and the for var_name this is (var_name,). The value is a dict
|
||||||
|
with a capitalized key describing the allowed value and an allowed
|
||||||
|
value. These dicts store the allowed enum values.
|
||||||
|
attribute_map (dict): The key is attribute name
|
||||||
|
and the value is json key in definition.
|
||||||
|
discriminator_value_class_map (dict): A dict to go from the discriminator
|
||||||
|
variable value to the discriminator class name.
|
||||||
|
validations (dict): The key is the tuple path to the attribute
|
||||||
|
and the for var_name this is (var_name,). The value is a dict
|
||||||
|
that stores validations for max_length, min_length, max_items,
|
||||||
|
min_items, exclusive_maximum, inclusive_maximum, exclusive_minimum,
|
||||||
|
inclusive_minimum, and regex.
|
||||||
|
additional_properties_type (tuple): A tuple of classes accepted
|
||||||
|
as additional properties values.
|
||||||
|
"""
|
||||||
|
|
||||||
|
allowed_values = {
|
||||||
|
}
|
||||||
|
|
||||||
|
validations = {
|
||||||
|
}
|
||||||
|
|
||||||
|
additional_properties_type = None
|
||||||
|
|
||||||
|
_nullable = False
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def openapi_types():
|
||||||
|
"""
|
||||||
|
This must be a method because a model may have properties that are
|
||||||
|
of type self, this must run after the class is loaded
|
||||||
|
|
||||||
|
Returns
|
||||||
|
openapi_types (dict): The key is attribute name
|
||||||
|
and the value is attribute type.
|
||||||
|
"""
|
||||||
|
return {
|
||||||
|
'_self': (str,), # noqa: E501
|
||||||
|
}
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def discriminator():
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
attribute_map = {
|
||||||
|
'_self': 'self', # noqa: E501
|
||||||
|
}
|
||||||
|
|
||||||
|
_composed_schemas = {}
|
||||||
|
|
||||||
|
required_properties = set([
|
||||||
|
'_data_store',
|
||||||
|
'_check_type',
|
||||||
|
'_spec_property_naming',
|
||||||
|
'_path_to_item',
|
||||||
|
'_configuration',
|
||||||
|
'_visited_composed_classes',
|
||||||
|
])
|
||||||
|
|
||||||
|
@convert_js_args_to_python_args
|
||||||
|
def __init__(self, *args, **kwargs): # noqa: E501
|
||||||
|
"""SomeObjectWithSelfAttr - a model defined in OpenAPI
|
||||||
|
|
||||||
|
Keyword Args:
|
||||||
|
_check_type (bool): if True, values for parameters in openapi_types
|
||||||
|
will be type checked and a TypeError will be
|
||||||
|
raised if the wrong type is input.
|
||||||
|
Defaults to True
|
||||||
|
_path_to_item (tuple/list): This is a list of keys or values to
|
||||||
|
drill down to the model in received_data
|
||||||
|
when deserializing a response
|
||||||
|
_spec_property_naming (bool): True if the variable names in the input data
|
||||||
|
are serialized names, as specified in the OpenAPI document.
|
||||||
|
False if the variable names in the input data
|
||||||
|
are pythonic names, e.g. snake case (default)
|
||||||
|
_configuration (Configuration): the instance to use when
|
||||||
|
deserializing a file_type parameter.
|
||||||
|
If passed, type conversion is attempted
|
||||||
|
If omitted no type conversion is done.
|
||||||
|
_visited_composed_classes (tuple): This stores a tuple of
|
||||||
|
classes that we have traveled through so that
|
||||||
|
if we see that class again we will not use its
|
||||||
|
discriminator again.
|
||||||
|
When traveling through a discriminator, the
|
||||||
|
composed schema that is
|
||||||
|
is traveled through is added to this set.
|
||||||
|
For example if Animal has a discriminator
|
||||||
|
petType and we pass in "Dog", and the class Dog
|
||||||
|
allOf includes Animal, we move through Animal
|
||||||
|
once using the discriminator, and pick Dog.
|
||||||
|
Then in Dog, we will make an instance of the
|
||||||
|
Animal class but this time we won't travel
|
||||||
|
through its discriminator because we passed in
|
||||||
|
_visited_composed_classes = (Animal,)
|
||||||
|
_self (str): [optional] # noqa: E501
|
||||||
|
"""
|
||||||
|
|
||||||
|
_check_type = kwargs.pop('_check_type', True)
|
||||||
|
_spec_property_naming = kwargs.pop('_spec_property_naming', False)
|
||||||
|
_path_to_item = kwargs.pop('_path_to_item', ())
|
||||||
|
_configuration = kwargs.pop('_configuration', None)
|
||||||
|
_visited_composed_classes = kwargs.pop('_visited_composed_classes', ())
|
||||||
|
|
||||||
|
if args:
|
||||||
|
raise ApiTypeError(
|
||||||
|
"Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % (
|
||||||
|
args,
|
||||||
|
self.__class__.__name__,
|
||||||
|
),
|
||||||
|
path_to_item=_path_to_item,
|
||||||
|
valid_classes=(self.__class__,),
|
||||||
|
)
|
||||||
|
|
||||||
|
self._data_store = {}
|
||||||
|
self._check_type = _check_type
|
||||||
|
self._spec_property_naming = _spec_property_naming
|
||||||
|
self._path_to_item = _path_to_item
|
||||||
|
self._configuration = _configuration
|
||||||
|
self._visited_composed_classes = _visited_composed_classes + (self.__class__,)
|
||||||
|
|
||||||
|
for var_name, var_value in kwargs.items():
|
||||||
|
if var_name not in self.attribute_map and \
|
||||||
|
self._configuration is not None and \
|
||||||
|
self._configuration.discard_unknown_keys and \
|
||||||
|
self.additional_properties_type is None:
|
||||||
|
# discard variable.
|
||||||
|
continue
|
||||||
|
setattr(self, var_name, var_value)
|
||||||
@@ -1565,11 +1565,16 @@ def get_valid_classes_phrase(input_classes):
|
|||||||
def convert_js_args_to_python_args(fn):
|
def convert_js_args_to_python_args(fn):
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
@wraps(fn)
|
@wraps(fn)
|
||||||
def wrapped_init(self, *args, **kwargs):
|
def wrapped_init(_self, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
An attribute named `self` received from the api will conflicts with the reserved `self`
|
||||||
|
parameter of a class method. During generation, `self` attributes are mapped
|
||||||
|
to `_self` in models. Here, we name `_self` instead of `self` to avoid conflicts.
|
||||||
|
"""
|
||||||
spec_property_naming = kwargs.get('_spec_property_naming', False)
|
spec_property_naming = kwargs.get('_spec_property_naming', False)
|
||||||
if spec_property_naming:
|
if spec_property_naming:
|
||||||
kwargs = change_keys_js_to_python(kwargs, self.__class__)
|
kwargs = change_keys_js_to_python(kwargs, _self.__class__)
|
||||||
return fn(self, *args, **kwargs)
|
return fn(_self, *args, **kwargs)
|
||||||
return wrapped_init
|
return wrapped_init
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ from petstore_api.model.shape_interface import ShapeInterface
|
|||||||
from petstore_api.model.shape_or_null import ShapeOrNull
|
from petstore_api.model.shape_or_null import ShapeOrNull
|
||||||
from petstore_api.model.simple_quadrilateral import SimpleQuadrilateral
|
from petstore_api.model.simple_quadrilateral import SimpleQuadrilateral
|
||||||
from petstore_api.model.some_object import SomeObject
|
from petstore_api.model.some_object import SomeObject
|
||||||
|
from petstore_api.model.some_object_with_self_attr import SomeObjectWithSelfAttr
|
||||||
from petstore_api.model.special_model_name import SpecialModelName
|
from petstore_api.model.special_model_name import SpecialModelName
|
||||||
from petstore_api.model.string_boolean_map import StringBooleanMap
|
from petstore_api.model.string_boolean_map import StringBooleanMap
|
||||||
from petstore_api.model.string_enum import StringEnum
|
from petstore_api.model.string_enum import StringEnum
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
"""
|
||||||
|
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 petstore_api
|
||||||
|
from petstore_api.model.some_object_with_self_attr import SomeObjectWithSelfAttr
|
||||||
|
|
||||||
|
|
||||||
|
class TestSomeObjectWithSelfAttr(unittest.TestCase):
|
||||||
|
"""SomeObjectWithSelfAttr unit test stubs"""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def testSomeObjectWithSelfAttr(self):
|
||||||
|
"""Test SomeObjectWithSelfAttr"""
|
||||||
|
kwargs = {"self": "this is a string", "_spec_property_naming": True}
|
||||||
|
model = SomeObjectWithSelfAttr(**kwargs)
|
||||||
|
assert model._self == "this is a string"
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
||||||
Reference in New Issue
Block a user