Skip to content

Client generation error when primitive types precede object types in a required oneOf / anyOf union #603

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jselig-rigetti opened this issue Apr 28, 2022 · 1 comment · Fixed by #642
Labels
🐞bug Something isn't working

Comments

@jselig-rigetti
Copy link
Contributor

The first clause of the to_dict method uses elif instead of if when a model's required property is a oneOf or anyOf union with primitive-type members ordered before object-type members, resulting in a syntax error.

In the mean time, a workaround may be to sort primitive-type members below object-type members as long as each group's members has their ordering maintained among themselves.

Source of issue:

{% if loop.first and property.required and not property.nullable %}{# No if UNSET or if None statement before this #}
if isinstance({{ source }}, {{ inner_property.get_instance_type_string() }}):
{% elif not loop.last or ns.contains_properties_without_transform %}
elif isinstance({{ source }}, {{ inner_property.get_instance_type_string() }}):

Resulting error:

$ openapi-python-client generate --path schema-required-union-ordering.yaml --fail-on-warning
Generating schema-required-union-ordering-client
Error(s) encountered while generating, client was not created

black failed

reformatted schema_required_union_ordering_client/api/__init__.py
reformatted schema_required_union_ordering_client/__init__.py
error: cannot format schema_required_union_ordering_client/models/get_response_200.py: Cannot parse: 23:8:         elif isinstance(self.a, GetResponse200AType1):
reformatted schema_required_union_ordering_client/types.py
reformatted schema_required_union_ordering_client/models/get_response_200a_type_1.py
reformatted schema_required_union_ordering_client/client.py
reformatted schema_required_union_ordering_client/api/default/get.py

Oh no! 💥 💔 💥
6 files reformatted, 2 files left unchanged, 1 file failed to reformat.

Using an example schema-required-union-ordering.yaml file:

openapi: 3.0.2
info:
  title: schema-required-union-ordering
  version: 1.0.0

paths:
  /:
    get:
      description: Test
      responses:
        '200':
          description: Test
          content:
            application/json:
              schema:
                type: object
                required:
                  - a
                properties:
                  a:
                    oneOf: # same error for `anyOf`
                    - type: string
                    - type: object

The problematic schema_required_union_ordering_client/models/get_response_200.py file:

from typing import Any, BinaryIO, Dict, List, Optional, TextIO, Tuple, Type, TypeVar, Union, cast

import attr

from ..models.get_response_200a_type_1 import GetResponse200AType1
from ..types import UNSET, Unset

T = TypeVar("T", bound="GetResponse200")

@attr.s(auto_attribs=True)
class GetResponse200:
    """
    Attributes:
        a (Union[GetResponse200AType1, str]):
    """

    a: Union[GetResponse200AType1, str]
    additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict)


    def to_dict(self) -> Dict[str, Any]:
        
        elif isinstance(self.a, GetResponse200AType1):
            a = self.a.to_dict()

        else:
            a = self.a



        field_dict: Dict[str, Any] = {}
        field_dict.update(self.additional_properties)
        field_dict.update({
            "a": a,
        })

        return field_dict



    @classmethod
    def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
        d = src_dict.copy()
        def _parse_a(data: object) -> Union[GetResponse200AType1, str]:
            try:
                if not isinstance(data, dict):
                    raise TypeError()
                a_type_1 = GetResponse200AType1.from_dict(data)



                return a_type_1
            except: # noqa: E722
                pass
            return cast(Union[GetResponse200AType1, str], data)

        a = _parse_a(d.pop("a"))


        get_response_200 = cls(
            a=a,
        )

        get_response_200.additional_properties = d
        return get_response_200

    @property
    def additional_keys(self) -> List[str]:
        return list(self.additional_properties.keys())

    def __getitem__(self, key: str) -> Any:
        return self.additional_properties[key]

    def __setitem__(self, key: str, value: Any) -> None:
        self.additional_properties[key] = value

    def __delitem__(self, key: str) -> None:
        del self.additional_properties[key]

    def __contains__(self, key: str) -> bool:
        return key in self.additional_properties

Versions

  • Python: 3.7.12
  • openapi-python-client: 0.11.1
@jselig-rigetti jselig-rigetti added the 🐞bug Something isn't working label Apr 28, 2022
@pacificsky
Copy link

We hit this as well, and are stuck on 0.9.2 as a result. All versions newer than 0.9.2 exhibit this behavior. A fix would be great!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐞bug Something isn't working
Projects
None yet
2 participants