Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,23 @@

def __getattr__(self, attr):
"""get the value of an attribute using dot notation: `instance.attr`"""
return self.{{#attrNoneIfUnset}}get{{/attrNoneIfUnset}}{{^attrNoneIfUnset}}__getitem__{{/attrNoneIfUnset}}(attr)
return self.{{#attrNoneIfUnset}}get{{/attrNoneIfUnset}}{{^attrNoneIfUnset}}__getitem__{{/attrNoneIfUnset}}(attr)

def __copy__(self):
cls = self.__class__
if self.get("_spec_property_naming", False):
return cls._new_from_openapi_data(**self.__dict__)
else:
return new_cls.__new__(cls, **self.__dict__)

def __deepcopy__(self, memo):
cls = self.__class__

if self.get("_spec_property_naming", False):
new_inst = cls._new_from_openapi_data()
else:
new_inst = cls.__new__(cls)

for k, v in self.__dict__.items():
setattr(new_inst, k, deepcopy(v, memo))
return new_inst
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{{>partial_header}}

from datetime import date, datetime # noqa: F401
from copy import deepcopy
import inspect
import io
import os
Expand Down Expand Up @@ -223,8 +224,13 @@ class OpenApiModel(object):
self_inst = super(OpenApiModel, cls).__new__(cls)
self_inst.__init__(*args, **kwargs)

new_inst = new_cls.__new__(new_cls, *args, **kwargs)
new_inst.__init__(*args, **kwargs)
if kwargs.get("_spec_property_naming", False):
# when true, implies new is from deserialization
new_inst = new_cls._new_from_openapi_data(*args, **kwargs)
else:
new_inst = new_cls.__new__(new_cls, *args, **kwargs)
new_inst.__init__(*args, **kwargs)

return new_inst


Expand Down
30 changes: 28 additions & 2 deletions samples/client/petstore/python/petstore_api/model_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@


from datetime import date, datetime # noqa: F401
from copy import deepcopy
import inspect
import io
import os
Expand Down Expand Up @@ -186,6 +187,26 @@ def __getattr__(self, attr):
"""get the value of an attribute using dot notation: `instance.attr`"""
return self.__getitem__(attr)

def __copy__(self):
cls = self.__class__
if self.get("_spec_property_naming", False):
return cls._new_from_openapi_data(**self.__dict__)
else:
return new_cls.__new__(cls, **self.__dict__)

def __deepcopy__(self, memo):
cls = self.__class__

if self.get("_spec_property_naming", False):
new_inst = cls._new_from_openapi_data()
else:
new_inst = cls.__new__(cls)

for k, v in self.__dict__.items():
setattr(new_inst, k, deepcopy(v, memo))
return new_inst


def __new__(cls, *args, **kwargs):
# this function uses the discriminator to
# pick a new schema/class to instantiate because a discriminator
Expand Down Expand Up @@ -295,8 +316,13 @@ def __new__(cls, *args, **kwargs):
self_inst = super(OpenApiModel, cls).__new__(cls)
self_inst.__init__(*args, **kwargs)

new_inst = new_cls.__new__(new_cls, *args, **kwargs)
new_inst.__init__(*args, **kwargs)
if kwargs.get("_spec_property_naming", False):
# when true, implies new is from deserialization
new_inst = new_cls._new_from_openapi_data(*args, **kwargs)
else:
new_inst = new_cls.__new__(new_cls, *args, **kwargs)
new_inst.__init__(*args, **kwargs)

return new_inst


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@


from datetime import date, datetime # noqa: F401
from copy import deepcopy
import inspect
import io
import os
Expand Down Expand Up @@ -186,6 +187,26 @@ def __getattr__(self, attr):
"""get the value of an attribute using dot notation: `instance.attr`"""
return self.__getitem__(attr)

def __copy__(self):
cls = self.__class__
if self.get("_spec_property_naming", False):
return cls._new_from_openapi_data(**self.__dict__)
else:
return new_cls.__new__(cls, **self.__dict__)

def __deepcopy__(self, memo):
cls = self.__class__

if self.get("_spec_property_naming", False):
new_inst = cls._new_from_openapi_data()
else:
new_inst = cls.__new__(cls)

for k, v in self.__dict__.items():
setattr(new_inst, k, deepcopy(v, memo))
Copy link
Contributor

@spacether spacether Sep 7, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about grabbing all of these properties before passing them into
_new_from_openapi_data and __new__?

kwargs = {}
for k, v in self.__dict__.items():
    kwargs[key] = deepcopy(v, memo)

if self.get("_spec_property_naming", False):
    new_inst = cls._new_from_openapi_data(**kwargs)
else:
    new_inst = cls.__new__(cls, **kwargs)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason setattr is used rather than kwargs, is that the dictionary set of values (such as the properties), are stored in dict["_data_store"]. In order to pass as kwargs, I would need to interpret the data (handle the _data_store as a special case), and pass that in as the kwargs. Rather, using setinst sets the key/value as is without any interpretation, a more resilent solution IMO.

return new_inst


def __new__(cls, *args, **kwargs):
# this function uses the discriminator to
# pick a new schema/class to instantiate because a discriminator
Expand Down Expand Up @@ -295,8 +316,13 @@ def __new__(cls, *args, **kwargs):
self_inst = super(OpenApiModel, cls).__new__(cls)
self_inst.__init__(*args, **kwargs)

new_inst = new_cls.__new__(new_cls, *args, **kwargs)
new_inst.__init__(*args, **kwargs)
if kwargs.get("_spec_property_naming", False):
# when true, implies new is from deserialization
new_inst = new_cls._new_from_openapi_data(*args, **kwargs)
else:
new_inst = new_cls.__new__(new_cls, *args, **kwargs)
new_inst.__init__(*args, **kwargs)

return new_inst


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@


from datetime import date, datetime # noqa: F401
from copy import deepcopy
import inspect
import io
import os
Expand Down Expand Up @@ -186,6 +187,26 @@ def __getattr__(self, attr):
"""get the value of an attribute using dot notation: `instance.attr`"""
return self.__getitem__(attr)

def __copy__(self):
cls = self.__class__
if self.get("_spec_property_naming", False):
return cls._new_from_openapi_data(**self.__dict__)
else:
return new_cls.__new__(cls, **self.__dict__)

def __deepcopy__(self, memo):
cls = self.__class__

if self.get("_spec_property_naming", False):
new_inst = cls._new_from_openapi_data()
else:
new_inst = cls.__new__(cls)

for k, v in self.__dict__.items():
setattr(new_inst, k, deepcopy(v, memo))
return new_inst


def __new__(cls, *args, **kwargs):
# this function uses the discriminator to
# pick a new schema/class to instantiate because a discriminator
Expand Down Expand Up @@ -295,8 +316,13 @@ def __new__(cls, *args, **kwargs):
self_inst = super(OpenApiModel, cls).__new__(cls)
self_inst.__init__(*args, **kwargs)

new_inst = new_cls.__new__(new_cls, *args, **kwargs)
new_inst.__init__(*args, **kwargs)
if kwargs.get("_spec_property_naming", False):
# when true, implies new is from deserialization
new_inst = new_cls._new_from_openapi_data(*args, **kwargs)
else:
new_inst = new_cls.__new__(new_cls, *args, **kwargs)
new_inst.__init__(*args, **kwargs)

return new_inst


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@


from datetime import date, datetime # noqa: F401
from copy import deepcopy
import inspect
import io
import os
Expand Down Expand Up @@ -186,6 +187,26 @@ def __getattr__(self, attr):
"""get the value of an attribute using dot notation: `instance.attr`"""
return self.__getitem__(attr)

def __copy__(self):
cls = self.__class__
if self.get("_spec_property_naming", False):
return cls._new_from_openapi_data(**self.__dict__)
else:
return new_cls.__new__(cls, **self.__dict__)

def __deepcopy__(self, memo):
cls = self.__class__

if self.get("_spec_property_naming", False):
new_inst = cls._new_from_openapi_data()
else:
new_inst = cls.__new__(cls)

for k, v in self.__dict__.items():
setattr(new_inst, k, deepcopy(v, memo))
return new_inst


def __new__(cls, *args, **kwargs):
# this function uses the discriminator to
# pick a new schema/class to instantiate because a discriminator
Expand Down Expand Up @@ -295,8 +316,13 @@ def __new__(cls, *args, **kwargs):
self_inst = super(OpenApiModel, cls).__new__(cls)
self_inst.__init__(*args, **kwargs)

new_inst = new_cls.__new__(new_cls, *args, **kwargs)
new_inst.__init__(*args, **kwargs)
if kwargs.get("_spec_property_naming", False):
# when true, implies new is from deserialization
new_inst = new_cls._new_from_openapi_data(*args, **kwargs)
else:
new_inst = new_cls.__new__(new_cls, *args, **kwargs)
new_inst.__init__(*args, **kwargs)

return new_inst


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@


from datetime import date, datetime # noqa: F401
from copy import deepcopy
import inspect
import io
import os
Expand Down Expand Up @@ -186,6 +187,26 @@ def __getattr__(self, attr):
"""get the value of an attribute using dot notation: `instance.attr`"""
return self.__getitem__(attr)

def __copy__(self):
cls = self.__class__
if self.get("_spec_property_naming", False):
return cls._new_from_openapi_data(**self.__dict__)
else:
return new_cls.__new__(cls, **self.__dict__)

def __deepcopy__(self, memo):
cls = self.__class__

if self.get("_spec_property_naming", False):
new_inst = cls._new_from_openapi_data()
else:
new_inst = cls.__new__(cls)

for k, v in self.__dict__.items():
setattr(new_inst, k, deepcopy(v, memo))
return new_inst


def __new__(cls, *args, **kwargs):
# this function uses the discriminator to
# pick a new schema/class to instantiate because a discriminator
Expand Down Expand Up @@ -295,8 +316,13 @@ def __new__(cls, *args, **kwargs):
self_inst = super(OpenApiModel, cls).__new__(cls)
self_inst.__init__(*args, **kwargs)

new_inst = new_cls.__new__(new_cls, *args, **kwargs)
new_inst.__init__(*args, **kwargs)
if kwargs.get("_spec_property_naming", False):
# when true, implies new is from deserialization
new_inst = new_cls._new_from_openapi_data(*args, **kwargs)
else:
new_inst = new_cls.__new__(new_cls, *args, **kwargs)
new_inst.__init__(*args, **kwargs)

return new_inst


Expand Down
34 changes: 34 additions & 0 deletions samples/openapi3/client/petstore/python/tests_manual/test_copy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from copy import deepcopy
import unittest
from petstore_api.model.mammal import Mammal
from petstore_api.model.triangle import Triangle


class TestCopy(unittest.TestCase):
"""TestCopy unit test stubs"""

def setUp(self):
pass

def tearDown(self):
pass

def testDeepCopyOneOf(self):
"""test deepcopy"""
obj = deepcopy(Mammal(class_name="whale"))
assert id(deepcopy(obj)) != id(obj)
assert deepcopy(obj) == obj

def testDeepCopyAllOf(self):
"""test deepcopy"""
obj = Triangle(shape_type="Triangle", triangle_type="EquilateralTriangle", foo="blah")
assert id(deepcopy(obj)) != id(obj)
assert deepcopy(obj) == obj

obj = Triangle._new_from_openapi_data(shape_type="Triangle", triangle_type="EquilateralTriangle", foo="blah")
assert id(deepcopy(obj)) != id(obj)
assert deepcopy(obj) == obj


if __name__ == '__main__':
unittest.main()