Skip to content

[BUG] [python-nextgen] Unable to parse responses with oneOf(object, List(object)) #14986

@aimxhaisse

Description

@aimxhaisse

First, thanks for python-nextgen, it looks very promising and really happy to use it :)

Bug Report Checklist

  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator (example)?
  • Have you tested with the latest master to confirm the issue still exists?
  • Have you searched for related issues/PRs?
  • What's the actual output vs expected output?
Description

Python-nextgen is currently confused when oneOf is composed of a mixtures of objects or lists.

openapi-generator version

Master branch

OpenAPI declaration file content or url
      responses:
        '201':
          description: Successful operation
          content:
            "application/json; charset=utf-8":
              schema:
                type: object
                properties:
                  data:
                    oneOf:
                      - $ref: '#/components/schemas/XXX'
                      - $ref: '#/components/schemas/YYY'
[...]

  schema:
    XXX:
      type: array
      items:
        type: object
        properties:
          format:
            type: string
    YYYY:
      type: object
      properties:
        format:
          type: string
Generation Details

The OneOf model template generates something similar to:

    @classmethod                                                                                                                            
    def from_json(cls, json_str: str) -> MyRouteResponse:                                                                        
        """Returns the object represented by the json string"""                                                                             
        instance = cls()                                                                                                                    
        error_messages = []                                                                                                                 
        match = 0                                                                                                                           
                                                                                                                                            
        # deserialize data into List[XXX]                                                                           
        try:                                                                                                                                
            instance.actual_instance = List[XXX].from_json(json_str)                                                
            match += 1                                                                                                                      
        except ValidationError as e:                                                                                                        
            error_messages.append(str(e))                                                                                                   
        # deserialize data into YYY                                                                                    
        try:                                                                                                                                
            instance.actual_instance = YYY.from_json(json_str)                                                         
            match += 1                                                                                                                      
        except ValidationError as e:                                                                                                        
            error_messages.append(str(e))                                                                                                   
                                                                                                                                            
        if match == 0:                                                                                                                      
            # no match                                                                                                                      
            raise ValueError("No match found when deserializing the JSON string into MyRouteResponse with oneOf schemas:  ...")
        else:                                                                                                                               
            return instance                                                                                                                 

The issue here is:

            instance.actual_instance = List[XXX].from_json(json_str)

List has no method from_json.

It typically results in stacktraces similar to:

     78 # deserialize data into List[XXX]
     79 try:
---> 80     instance.actual_instance = List[XXX].from_json(json_str)
     81     match += 1
     82 except ValidationError as e:

[...]

_BaseGenericAlias.__getattr__(self, attr)
    706 def __getattr__(self, attr):
    707     # We are careful for copy and pickle.
    708     # Also for simplicity we don't relay any dunder names
    709     if '__origin__' in self.__dict__ and not _is_dunder(attr):
--> 710         return getattr(self.__origin__, attr)
    711     raise AttributeError(attr)

AttributeError: type object 'list' has no attribute 'from_json'

As python-nextgen works well with responses with List[XXX] without the oneOf, I guess the oneOf template needs to somehow be adapted to use the same logic as the generic template.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions