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

Invalid enum names not properly handled (e.g.: "mro") #873

Closed
DavideWalder opened this issue Oct 16, 2022 · 8 comments · Fixed by #891
Closed

Invalid enum names not properly handled (e.g.: "mro") #873

DavideWalder opened this issue Oct 16, 2022 · 8 comments · Fixed by #891

Comments

@DavideWalder
Copy link

DavideWalder commented Oct 16, 2022

Describe the bug
Enum member names can't be mro, since this clashes with the method resolution order method.

To Reproduce

Example schema:

{
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "enum_with_invalid_value": {
        "type": "string",
        "enum": ["mro"]
      }
    }
  }
}

Used commandline:

datamodel-codegen  --input schema.json  --input-file-type jsonschema --output model.py
python -c "import model" # ValueError: Invalid enum member name: mro

Expected behavior
The name should be adapted. According to PEP-8, the preferred solution is to suffix with an underscore ("mro_" instead of "mro"). Since this is only the enum name it should not have any impact on parsing.

Version:

  • OS: MacOS
  • Python version: 3.10.4
  • datamodel-code-generator version: 0.13.1
@koxudaxi
Copy link
Owner

koxudaxi commented Nov 8, 2022

@DavideWalder
I have released the new version as 0.13.5
Thank you very much!!

@DavideWalder
Copy link
Author

@koxudaxi
I'm testing with 0.17.0 and the issue is still there (same for 0.14.0)

@koxudaxi
Copy link
Owner

koxudaxi commented Jan 31, 2023

@DavideWalder
I tested your example on my machine.
The result looks good.

$ datamodel-codegen  --input schema.json  --input-file-type jsonschema --output model.py
$ python -c "import model"
$ echo $?                 
0
$ datamodel-codegen --version                                                         
0.17.0

model.py

# generated by datamodel-codegen:
#   filename:  schema.json
#   timestamp: 2023-01-31T13:13:09+00:00

from __future__ import annotations

from enum import Enum
from typing import List, Optional

from pydantic import BaseModel


class EnumWithInvalidValue(Enum):
    mro_ = 'mro'


class ModelItem(BaseModel):
    enum_with_invalid_value: Optional[EnumWithInvalidValue] = None


class Model(BaseModel):
    __root__: List[ModelItem]

Have you tried the other input or the same one?

@DavideWalder
Copy link
Author

Found the issue:

input:

openapi: 3.0.3
components:
  schemas:
    TheEnum:
      type: string
      enum:
        - MRO
        - mro

output:

# generated by datamodel-codegen:
#   filename:  datasync.yaml
#   timestamp: 2023-01-31T13:27:19+00:00

from __future__ import annotations

from enum import Enum


class TheEnum(Enum):
    mro = 'MRO'
    mro_ = 'mro'

The underscore is suffixed only when the enum value is lowercase

@koxudaxi
Copy link
Owner

Thank you for explaining the problem.
I will soon change the result to the one below.

class TheEnum(Enum):
    mro_ = 'MRO'
    mro_1 = 'mro'

@DavideWalder
Copy link
Author

Also, this brings up the question of what to do when two entries differ by casing like NAME and name. Probably a clearer solution would be to maintain the casing, as:

class TheEnum(Enum):
    MRO_ = 'MRO'
    mro_ = 'mro'

This would also avoid the issue where changing the order from

openapi: 3.0.3
components:
  schemas:
    TheEnum:
      type: string
      enum:
        - MRO
        - mro
openapi: 3.0.3
components:
  schemas:
    TheEnum:
      type: string
      enum:
        - mro
        - MRO

would change the enum names.

I see that keeping the casing would be a non-backward compatible change though

@koxudaxi
Copy link
Owner

@DavideWalder
Good point.
I want to avoid changing current behavior.
I reccomend to use --snake-case-field or --capitalise-enum-members

without options

class InvalidEnum(Enum):
    MRO = 'MRO'
    mro_ = 'mro'

--snake-case-field

class InvalidEnum(Enum):
   mro_1 = 'MRO'
   mro_ = 'mro'

--capitalise-enum-members

class InvalidEnum(Enum):
    MRO = 'MRO'
    MRO_ = 'mro'

https://github.com/koxudaxi/datamodel-code-generator/pull/1069/files#diff-440ee6529a7880f5b3f955ee7186af0b603ba307adc6991ea004642878e55182R15-R16

@koxudaxi
Copy link
Owner

koxudaxi commented Feb 7, 2023

@DavideWalder
I have released the fix version 0.17.1
Thank you very much!!

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

Successfully merging a pull request may close this issue.

2 participants