danielgtaylor / python-betterproto

Clean, modern, Python 3.6+ code generator & library for Protobuf 3 and async gRPC
MIT License
1.5k stars 209 forks source link

to_dict returns wrong enum fields when numbering is not consecutive #93

Closed michael-sayapin closed 4 years ago

michael-sayapin commented 4 years ago

Protobuf spec file like this:

syntax = "proto3";
package message;
message TeraMessage {
    int64 timestamp = 1;
    enum MessageType {
        MESSAGE_TYPE_UNKNOWN = 0;
        MESSAGE_TYPE_ACTION_MESSAGE = 1;
        // @exclude MESSAGE_TYPE_COMMAND_MESSAGE = 2; // DEPRECATED
        MESSAGE_TYPE_CONFIG_MESSAGE = 3;
        MESSAGE_TYPE_HEARTBEAT_MESSAGE = 4;
    }
    MessageType message_type = 5;
    bytes message = 6;
}

Generates the following Python bindings:

from dataclasses import dataclass
import betterproto

class TeraMessageMessageType(betterproto.Enum):
    MESSAGE_TYPE_UNKNOWN = 0
    MESSAGE_TYPE_ACTION_MESSAGE = 1
    # NB: notice that 2 is missing
    MESSAGE_TYPE_CONFIG_MESSAGE = 3
    MESSAGE_TYPE_HEARTBEAT_MESSAGE = 4

@dataclass
class TeraMessage(betterproto.Message):
    timestamp: int = betterproto.int64_field(1)
    message_type: "TeraMessageMessageType" = betterproto.enum_field(5)
    message: bytes = betterproto.bytes_field(6)

To reproduce the bug:

>>> from my.path.message import TeraMessage, TeraMessageMessageType
>>> message = TeraMessage(message_type=TeraMessageMessageType.MESSAGE_TYPE_CONFIG_MESSAGE)
>>> message.to_dict()
{'messageType': 'MESSAGE_TYPE_HEARTBEAT_MESSAGE'}
>>> message.to_json()
'{"messageType": "MESSAGE_TYPE_HEARTBEAT_MESSAGE"}'
>>> TeraMessage().parse(bytes(message)).message_type == TeraMessageMessageType.MESSAGE_TYPE_CONFIG_MESSAGE
True
boukeversteegh commented 4 years ago

Awesome bugreport! Thanks!

Would you be willing to add this test-case to our standard tests?

You basically only need to:

Details are described here: Standard Tests Development Guide

michael-sayapin commented 4 years ago

Sure @boukeversteegh ! Created a PR https://github.com/danielgtaylor/python-betterproto/pull/94