Skip to content

Optional array field generates with empty list [] instead of UNSET in from_dict method #1305

@kwinstonix

Description

@kwinstonix

Describe the bug
Optional array field generates with empty list [] instead of UNSET in from_dict method

Desktop (please complete the following information):

  • OS: macOS 13.3
  • Python Version: 3.10.12
  • openapi-python-client version:0.25.3

When an optional array field is not specified as required in the OpenAPI schema, openapi-python-client incorrectly generates the from_dict method. The generated code initializes the field with an empty list [] instead of the sentinel UNSET value.

This behavior causes the client to send an empty array in the request body for an optional field that was not provided, which is an incorrect representation of the data. The correct behavior should be to omit the field entirely from the payload.

Expected Behavior

For an optional array field, if the corresponding key is not present in the input dictionary, the generated code should set the attribute to UNSET.

Actual Behavior

The generated from_dict method initializes the array field with an empty list [], regardless of whether the key is present in the input dictionary.

Steps to Reproduce

  1. Use the following minimal OpenAPI specification:

    # mini_example.yaml
    openapi: 3.0.3
    info:
      title: Test API
      version: 1.0.0
    paths: {}
    components:
      schemas:
        ExampleResourceSchema:
          type: object
          properties:
            locations:
              maxItems: 100
              description: 'This is a test array'
              type: array
              items:
                $ref: '#/components/schemas/LocationSchema'
        LocationSchema:
          type: object
          properties:
            name:
              type: string
  2. Run the generation command:

    openapi-python-client generate --path ./mini_example.yaml
  3. Inspect the generated ExampleResourceSchema.from_dict method.

The Problematic Code

The generated from_dict method for ExampleResourceSchema contains the following incorrect logic:

@classmethod
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
    from ..models.location_schema import LocationSchema

    d = dict(src_dict)
    locations = []  # <-- This line incorrectly initializes the field to an empty list
    _locations = d.pop("locations", UNSET)
    for locations_item_data in _locations or []:
        locations_item = LocationSchema.from_dict(locations_item_data)
        locations.append(locations_item)

    example_resource_schema = cls(
        locations=locations,
    )

    example_resource_schema.additional_properties = d
    return example_resource_schema

Proposed Fix

The correct implementation should check for the presence of the UNSET value before initializing the list. A working version of the method would be:

@classmethod
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
    from ..models.location_schema import LocationSchema

    d = dict(src_dict)
    _locations = d.pop("locations", UNSET)
    locations = UNSET  # <-- Initialize with UNSET

    if _locations is not UNSET:
        locations = []
        for locations_item_data in _locations:
            locations_item = LocationSchema.from_dict(locations_item_data)
            locations.append(locations_item)

    example_resource_schema = cls(
        locations=locations,
    )

    example_resource_schema.additional_properties = d
    return example_resource_schema

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions