Search code examples
protocprotobuf-python

Protobuf file not generating correct Python code with 'protoc --python_out' command


I have a .proto file defining a message called 'DeviationCreate'.

syntax = "proto3";

package proto;

option go_package = "proto";
option java_package = "deviationalert";

message DeviationCreate {
  int64 alertKey = 1;
}

I'm trying to generate Python code from this file using the 'protoc --python_out' command, but the generated Python code is not correct. The generated code seems to be missing fields and has syntax errors. this is command:

protoc --proto_path=C:\proto --python_out=C:\proto tst.proto

and this is generated content:

# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler.  DO NOT EDIT!
# source: tst.proto
"""Generated protocol buffer code."""
from google.protobuf.internal import builder as _builder
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)

_sym_db = _symbol_database.Default()




DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\ttst.proto\x12\x05proto\"#\n\x0f\x44\x65viationCreate\x12\x10\n\x08\x61lertKey\x18\x01 \x01(\x03\x42\x17\n\x0e\x64\x65viationalertZ\x05protob\x06proto3')

_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'tst_pb2', globals())
if _descriptor._USE_C_DESCRIPTORS == False:

  DESCRIPTOR._options = None
  DESCRIPTOR._serialized_options = b'\n\016deviationalertZ\005proto'
  _DEVIATIONCREATE._serialized_start=20
  _DEVIATIONCREATE._serialized_end=55
# @@protoc_insertion_point(module_scope)

I tried running the 'protoc --python_out' command with the correct options and the path to my .proto file. I was expecting the generated Python code to correctly reflect the fields and syntax defined in the .proto file. However, the generated Python code has errors and is missing fields, so it does not match the .proto file. my protoc version is 3.21.7


Solution

  • The generated code works, try it out:

    import python_out.example_pb2 as example
    
    if __name__ == "__main__":
      proto = example.DeviationCreate()
      proto.alertKey = 20
      print(proto)
    

    Running this prints

    alertKey: 20
    

    According the docs, the python protobuf implementation uses meta-classes, essentially creating all the fields you're expecting in this line:

    DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\ttst.proto\x12\x05proto\"#\n\x0f\x44\x65viationCreate\x12\x10\n\x08\x61lertKey\x18\x01 \x01(\x03\x42\x17\n\x0e\x64\x65viationalertZ\x05protob\x06proto3')
    

    If you look closely, it contains the definition of everything you need.