Skip to content
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

[BUG][PYTHON][PLUSS OTHERS] Enum variable names not update in all python converters #16560

Open
6 tasks
mwilby opened this issue Sep 11, 2023 · 4 comments
Open
6 tasks

Comments

@mwilby
Copy link

mwilby commented Sep 11, 2023

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?
  • [Optional] Sponsorship to speed up the bug fix or feature request (example)

There is no need for a detailed report. This is a simple problem with a simple fix and it applies to all versions.

Description

There is a problem with the Python family of converters when processing enums.
Basically none of them substitutes the enum var extensions.

So using a simple scheme definition

maitred_format:
   type: integer
   title: Message Format
   enum:
     - 1
     - -1
     - 0
   x-enum-varnames:
     - JSON
     - Unknown
     - SIBEC
   x-enum-descriptions:
     - JSON Descriptions
     - Unknown stuff
     - SIBEC Description

The python converter creates this:

class MaitredFormat(int, Enum):
    """
    Encoding format of Payload.
    """

    """
    allowed enum values
    """
    NUMBER_1 = 1
    NUMBER_MINUS_1 = -1
    NUMBER_0 = 0

    @classmethod
    def from_json(cls, json_str: str) -> MaitredFormat:
        """Create an instance of MaitredFormat from a JSON string"""
        return MaitredFormat(json.loads(json_str))

If you look at the generated model info, the relevant part is found to be.

{
  ...,
  "model" : {
    ...,
    "classname" : "MaitredFormat",
    ...,
    "allowableValues" : {
      "values" : [ 1, -1, 0 ],
      "enumVars" : [ {
        "name" : "NUMBER_1",
        "isString" : false,
        "enumDescription" : "JSON Descriptions",
        "value" : "1"
      }, {
        "name" : "NUMBER_MINUS_1",
        "isString" : false,
        "enumDescription" : "Unknown stuff",
        "value" : "-1"
      }, {
        "name" : "NUMBER_0",
        "isString" : false,
        "enumDescription" : "SIBEC Descriptions.",
        "value" : "0"
      } ]
    },
    ...
  }
}

This is because updateEnumVarsWithExtensions() is never called and to fix it, its a simple matter of adding

    @Override
    public ModelsMap postProcessModels(ModelsMap objs) {
        // process enum in models
        return postProcessModelsEnum(objs);
    }

to the relevant Python????Codegen.java module.

There are a fair number of other language models that don't include a postProcessModels override, not sure if it matters, or not, but it probably does.

Taking a language that does include the call, in this case, csharp, you generate the correct form of enum, i.e.

namespace Org.OpenAPITools.Model
{
    public enum MaitredFormat
    {
        JSON = 1,
        Unknown = -1,
        SIBEC = 0,
    }
}

This is because the model has been processed and looks like this.

{
  ...,
  "model" : {
    ...,
    "classname" : "MaitredFormat",
    ...,
    "allowableValues" : {
      "values" : [ 1, -1, 0 ],
      "enumVars" : [ {
        "name" : "JSON",
        "isString" : false,
        "enumDescription" : "JSON Descriptions",
        "value" : "1"
      }, {
        "name" : "Unknown",
        "isString" : false,
        "enumDescription" : "Unknown stuff",
        "value" : "-1"
      }, {
        "name" : "SIBEC",
        "isString" : false,
        "enumDescription" : "SIBEC Descriptions.",
        "value" : "0"
      } ]
    },
    ...
  }
}
Suggest a fix

Repeat adding

    @Override
    public ModelsMap postProcessModels(ModelsMap objs) {
        // process enum in models
        return postProcessModelsEnum(objs);
    }

to the relevant Python????Codegen.java module.

@wing328
Copy link
Member

wing328 commented Sep 12, 2023

This is because updateEnumVarsWithExtensions() is never called and to fix it, its a simple matter of adding

can you please file a PR with the suggested fix?

@roishacham
Copy link

@wing328 @mwilby

Any updates on a fix for this issue? I'm encountering this as well.

@VBA-N7
Copy link

VBA-N7 commented Jan 25, 2024

I'm encountering the same problem and this is very annoying. It would be great to have some news 😄

openapi: 3.0.0
info:
  version: 1.0.0
  title: Weather API
paths: {}

components:
  schemas:
    WeatherType:
      type: integer
      format: int32
      enum:
        - 42
        - 18
        - 56
      x-enum-descriptions:
        - 'Blue sky'
        - 'Slightly overcast'
        - 'Take an umbrella with you'
      x-enum-varnames:
        - Sunny
        - Cloudy
        - Rainy

The command i used
docker run --rm -v "${PWD}:/local" openapitools/openapi-generator-cli generate -i /local/mon_api.yaml -g python-flask -o /local/dist

The generated python file:

from datetime import date, datetime  # noqa: F401

from typing import List, Dict  # noqa: F401

from openapi_server.models.base_model import Model
from openapi_server import util


class WeatherType(Model):
    """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).

    Do not edit the class manually.
    """

    """
    allowed enum values
    """
    NUMBER_42 = 42
    NUMBER_18 = 18
    NUMBER_56 = 56
    def __init__(self):  # noqa: E501
        """WeatherType - a model defined in OpenAPI

        """
        self.openapi_types = {
        }

        self.attribute_map = {
        }

    @classmethod
    def from_dict(cls, dikt) -> 'WeatherType':
        """Returns the dict as a model

        :param dikt: A dict.
        :type: dict
        :return: The WeatherType of this WeatherType.  # noqa: E501
        :rtype: WeatherType
        """
        return util.deserialize_model(dikt, cls)

@0xMattijs
Copy link
Contributor

0xMattijs commented May 3, 2024

While postProcessModelsEnum is called here:


its effects are overwritten by the code block further down: https://github.com/OpenAPITools/openapi-generator/blob/73f2d8289b2d4069675c79ea5375d9c58ea1853c/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonCodegen.java#L986C1-L998C14

I created PR #18566 preventing the NUMBER_X transformation to run if x-enum-varnames is provided.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants