OpenAPITools / openapi-generator

OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an OpenAPI Spec (v2, v3)
https://openapi-generator.tech
Apache License 2.0
21.69k stars 6.55k forks source link

[BUG][python] deepcopy of model gives KeyError: '_data_store' #9669

Open mfmarche opened 3 years ago

mfmarche commented 3 years ago

Bug Report Checklist

Description

I ran into this as I was attempting to use dataclasses.asdict(obj). I tracked it down to use of a deepcopy call. While copying the openapi model object, I believe the default deepcopy is missing the object attributes.

openapi-generator version

master

OpenAPI declaration file content or url

I used the sample petstore api in: samples/openapi3/client/petstore/python

Generation Details

N/A

Steps to reproduce
from copy import deepcopy
from petstore_api.model.banana import Banana
first = Banana(5.2)
second = deepcopy(first)

<snip>
KeyError: '_data_store'
Related issues/PRs
Suggest a fix

I came up with a solution to this by updating the model_utils.py, specifically the OpenApiModel, adding:

    def __copy__(self):
        cls = self.__class__
        result = cls.__new__(cls)
        result.__dict__.update(self.__dict__)
        return result

    def __deepcopy__(self, memo):
        cls = self.__class__
        result = cls.__new__(cls)
        for k, v in self.__dict__.items():
            setattr(result, k, deepcopy(v, memo))
        return result

Note that this worked only for a Normal object without a discriminator. I ran into a separate issue (might be unrelated?), where the same test with a discriminator gave the following:

from copy import deepcopy
from petstore_api.model.mammal import Mammal
deeepcopy(Mammal())

<snip>
petstore_api.exceptions.ApiValueError: Cannot deserialize input data due to missing discriminator. The discriminator property 'className' is missing at path: ()

Could there be other pitfalls with implementation of the deepcopy above?

mfmarche commented 3 years ago

I had a bug in the last portion of the test, I missed the class_name. This works correctly with the suggested patch with copy and deepcopy with a discriminator type model as well.

deeppcopy(Mammal(class_name="BasquePig"))
kiernangeorge commented 2 years ago

Will this be addressed soon? I am running into the same issue in my own project and having to implement workarounds in the meantime.