python-betterproto icon indicating copy to clipboard operation
python-betterproto copied to clipboard

Invalid Enum member names which contain the Enum name

Open connorbrinton opened this issue 1 year ago • 3 comments

Summary

2.0.0b7 breaks enums with underscores in field names

Reproduction Steps

Test proto definition, in test.proto:

syntax = "proto3";

package hello;

// Greeting represents a message you can tell a user.
message Greeting {
  Risk risk = 1;
}

enum Risk {
    LOW_RISK = 0;
    HIGH_RISK = 1;
}

Protoc compiler invocation:

$ protoc -I . --python_betterproto_out=lib test.proto

Expected Results

2.0.0b6 output (lib/hello/__init__.py):

# Generated by the protocol buffer compiler.  DO NOT EDIT!
# sources: test.proto
# plugin: python-betterproto
# This file has been @generated

from dataclasses import dataclass

import betterproto


class Risk(betterproto.Enum):
    LOW_RISK = 0
    HIGH_RISK = 1


@dataclass(eq=False, repr=False)
class Greeting(betterproto.Message):
    """Greeting represents a message you can tell a user."""

    risk: "Risk" = betterproto.enum_field(1)

Actual Results

2.0.0b7 output (lib/hello/__init__.py):

# Generated by the protocol buffer compiler.  DO NOT EDIT!
# sources: test.proto
# plugin: python-betterproto
# This file has been @generated

from dataclasses import dataclass

import betterproto


class Risk(betterproto.Enum):
    _ = 0
    _ = 1


@dataclass(eq=False, repr=False)
class Greeting(betterproto.Message):
    """Greeting represents a message you can tell a user."""

    risk: "Risk" = betterproto.enum_field(1)

System Information

  • Protoc version: libprotoc 27.3
  • Python version: Python 3.11.7
  • Betterproto version:
Name: betterproto
Version: 2.0.0b7
Summary: A better Protobuf / gRPC generator & library
Home-page: https://github.com/danielgtaylor/python-betterproto
Author: Daniel G. Taylor
Author-email: [email protected]
License: MIT
Location: /Users/connor/Code/tests/test070/.venv/lib/python3.11/site-packages
Requires: grpclib, python-dateutil, typing-extensions
Required-by:

Checklist

  • [X] I have searched the issues for duplicates.
  • [X] I have shown the entire traceback, if possible.
  • [X] I have verified this issue occurs on the latest prelease of betterproto which can be installed using pip install -U --pre betterproto, if possible.

connorbrinton avatar Aug 29 '24 16:08 connorbrinton

Regression caused by the last change to https://github.com/danielgtaylor/python-betterproto/blob/bd7de203e16e949666b2844b3dec1eb7c4ed523c/src/betterproto/compile/naming.py

Gobot1234 avatar Aug 31 '24 14:08 Gobot1234

Would be fixed by #589 though I'll have a think about whether to change the function t ostrip the name

Gobot1234 avatar Aug 31 '24 14:08 Gobot1234

Smart-stripping by default may lead to confusion, and should be mentioned on the homepage/docs.

Tests

def pythonize_enum_member_name(name: str, enum_name: str) -> str:
    enum_name = casing.snake_case(enum_name).upper()
    find = name.find(enum_name)
    if find != -1:
        name = name[find + len(enum_name) :].strip("_")
    return casing.sanitize_name(name)
>>> pythonize_enum_member_name("UNKNOWN_COLOR", "Color")
'_'

>>> pythonize_enum_member_name("SWIFTUI", "UI")
'_'

>>> pythonize_enum_member_name("MONGODB", "DB")
'_'

>>> pythonize_enum_member_name("BLACKBIRD", "Bird")
'_'

>>> pythonize_enum_member_name("SUNFLOWER", "Flower")
'_'

>>> pythonize_enum_member_name("FOOTBALL", "Ball")
'_'

>>> pythonize_enum_member_name("SOCCER_BALL", "Ball")
'_'

>>> pythonize_enum_member_name("EMPLOYEE_ID_NUMBER", "ID")
'NUMBER'

>>> pythonize_enum_member_name("WIFI_NETWORK", "Net")
'WORK'

>>> pythonize_enum_member_name("OAUTH_LOGIN", "Auth")
'LOGIN'

>>> pythonize_enum_member_name("KEYWORDS", "Word")
'S'

# This one is OK:
>>> pythonize_enum_member_name("X11_METHOD_NONE", "X11Method")
'NONE'

>>> pythonize_enum_member_name("A11Y_METHOD_NONE", "A11YMethod")
'A11Y_METHOD_NONE'

>>> pythonize_enum_member_name("DTYPE_NONE", "DType")
'DTYPE_NONE'

Warnings

Perhaps produce a warning if the input may cause issues or if the output is "_". For example:

Warning: Generated python name "_" from the C++ "{name}" member of enum "{enum_name}".
To avoid confusion, it is recommended to prefix the enum with its snake-case version "{casing.snake_case(enum_name).upper()}".

YodaEmbedding avatar Jan 29 '25 06:01 YodaEmbedding