openapi-generator icon indicating copy to clipboard operation
openapi-generator copied to clipboard

[BUG] [Python] Object with enum in additionalProperties and RESOLVE_INLINE_ENUMS can not be optional.

Open Leszeg opened this issue 1 year ago • 0 comments

Bug Report Checklist

  • [x] Have you provided a full/minimal spec to reproduce the issue?
  • [x] Have you validated the input using an OpenAPI validator (example)?
  • [x] Have you tested with the latest master to confirm the issue still exists?
  • [x] Have you searched for related issues/PRs?
  • [x] What's the actual output vs expected output?
  • [ ] [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

When having schema where one of properties is optional enum, then generated model method from_dict() is throwing error:

  • AttributeError: 'NoneType' object has no attribute 'items'

Adding 'nullable: true' to property1 is not changing anything.

openapi-generator version

7.5.0

OpenAPI declaration file content or url
IssueSchema:
  type: object
  properties:
    property1:
      type: object
      additionalProperties:
        type: string
        enum:
        - TEXT1
        - TEXT2
        - TEXT3
    property2:
      type: object
      additionalProperties:
        type: boolean
Generation Details

openapi-generator-cli generate -g python -c config.yaml

Config file:

globalProperties:
  apiTests: false
  modelTests: false

additionalProperties: 
  enablePostProcessFile: true

inlineSchemaOptions:
  RESOLVE_INLINE_ENUMS: true

Steps to reproduce

Try tu run method from_dict() of model genrated from provided schema when property1 is not present. For example:

{
    "property2": {
        "key1": "true",
        "key2": "false"  
    }
}
Related issues/PRs
Suggest a fix

Genrated method from_dict() of model is generated as follow:

    @classmethod
    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
        """Create an instance of IssueSchema from a dict"""
        if obj is None:
            return None

        if not isinstance(obj, dict):
            return cls.model_validate(obj)

        _obj = cls.model_validate(
            {
                "property1": dict(
                    (_k, _v) for _k, _v in obj.get("property1").items()  # This line is throwing an error.
                ),
                "property2": obj.get("booleanPermissions"),
            }
        )
        return _obj

When obj.get("property1") is None we can not call items() on it. Simple 'if' statement is fixing issue:

    @classmethod
    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
        """Create an instance of IssueSchema from a dict"""
        if obj is None:
            return None

        if not isinstance(obj, dict):
            return cls.model_validate(obj)

        _obj = cls.model_validate(
            {
                "property1": dict(
                    (_k, _v) for _k, _v in obj.get("property1").items()  # This line is throwing an error.
                ) if obj.get("property1") is not None else None, # This 'if' fix all problem.
                "property2": obj.get("booleanPermissions"),
            }
        )
        return _obj

Leszeg avatar May 09 '24 19:05 Leszeg