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

TypeError: Couldn't build proto file into descriptor pool: duplicate symbol 'MyRequest' #18463

Open
afarber opened this issue Sep 22, 2024 · 2 comments

Comments

@afarber
Copy link

afarber commented Sep 22, 2024

What version of protobuf and what language are you using?
protoc 28.1
python 3.12.6

What operating system (Linux, Windows, ...) and version?
macOS 14.6.1

What runtime / compiler are you using (e.g., python version or gcc version)
I am not sure, sorry. I just use the protoc and python from the homebrew

What did you do?

MyProtoV1.proto:

syntax = "proto3";

message MyRequest {
    uint32 version = 1;
    string userId = 2;
}

message MyResponse {
    uint64 id = 1;
    bool pull = 2;
}

MyProtoV2.proto:

syntax = "proto3";

message MyRequest {
    uint32 version = 1;
    string userId = 2;
}

message MyResponse {
    reserved 1, 2;
    repeated uint64 pullIds = 3;
}

my_proto.py:

import My.ProtoV1_pb2 as V1
import My.ProtoV2_pb2 as V2

request1 = V1.MyRequest()
request1.version = 1
request1.userId = "user1"
print("request1", request1)

request2 = V2.MyRequest()
request2.version = 2
request2.userId = "user2"
print("request2", request2)

Commands I run:

protoc --python_out=. My.ProtoV1.proto
protoc --python_out=. My.ProtoV2.proto
python -m venv ./venv
. ./venv/bin/activate
python -m pip install google protobuf
python my_proto.py

What did you expect to see

The script whould print request1 and request2 objects

What did you see instead?

/test/venv/lib/python3.12/site-packages/google/protobuf/runtime_version.py:112: UserWarning: Protobuf gencode version 5.28.1 is older than the runtime version 5.28.2 at My.ProtoV1.proto. Please avoid checked-in Protobuf gencode that can be obsolete.
  warnings.warn(
/test/venv/lib/python3.12/site-packages/google/protobuf/runtime_version.py:112: UserWarning: Protobuf gencode version 5.28.1 is older than the runtime version 5.28.2 at My.ProtoV2.proto. Please avoid checked-in Protobuf gencode that can be obsolete.
  warnings.warn(
Traceback (most recent call last):
  File "/test/my_proto.py", line 10, in <module>
    import My.ProtoV2_pb2 as V2
  File "/test/My/ProtoV2_pb2.py", line 27, in <module>
    DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x10My.ProtoV2.proto\",\n\tMyRequest\x12\x0f\n\x07version\x18\x01 \x01(\r\x12\x0e\n\x06userId\x18\x02 \x01(\t\")\n\nMyResponse\x12\x0f\n\x07pullIds\x18\x03 \x03(\x04J\x04\x08\x01\x10\x02J\x04\x08\x02\x10\x03\x62\x06proto3')
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Couldn't build proto file into descriptor pool: duplicate symbol 'MyRequest'

Anything else we should know about your project / environment

I was expecting being able using both versions of MyProtoV1.proto and MyProtoV2.proto in the same script (to support different clients in my server).

Thank you!

@afarber afarber added the untriaged auto added to all issues by default when created. label Sep 22, 2024
@afarber
Copy link
Author

afarber commented Sep 22, 2024

I have also unsuccessfully tried:

from My.ProtoV1_pb2 import MyRequest as MyRequestV1
from My.ProtoV2_pb2 import MyRequest as MyRequestV2

request1 = MyRequestV1()
request1.version = 1
request1.userId = "user1"
print("request1", request1)

request2 = MyRequestV2()
request2.version = 2
request2.userId = "user2"
print("request2", request2)

which results in the similar error:

  File "/test/my_proto.py", line 10, in <module>
    from My.ProtoV2_pb2 import MyRequest as MyRequestV2
  File "/test/My/ProtoV2_pb2.py", line 27, in <module>
    DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x10My.ProtoV2.proto\",\n\tMyRequest\x12\x0f\n\x07version\x18\x01 \x01(\r\x12\x0e\n\x06userId\x18\x02 \x01(\t\")\n\nMyResponse\x12\x0f\n\x07pullIds\x18\x03 \x03(\x04J\x04\x08\x01\x10\x02J\x04\x08\x02\x10\x03\x62\x06proto3')
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Couldn't build proto file into descriptor pool: duplicate symbol 'MyRequest'

@JasonLunn
Copy link
Contributor

This is working as expected - both of the proto files you're importing attempt to define the same messages, which is an error.

Typically when evolving schema, changes are done in place so that you can continue serving clients that have the old schema and may not be aware of the latest changes.

Consider the following as the only proto you script imports:

syntax = "proto3";

message MyRequest {
    uint32 version = 1;
    string userId = 2;
}

message MyResponse {
    uint64 id = 1;
    bool pull = 2;
    repeated uint64 pullIds = 3;
}

Legacy clients will continue populating the original id and pull fields, while newer clients will populate pullIds instead.
You can also add the [deprecated = true] field option to the old fields. Protobuf Python may not do anything with that field option yet but may in the future, but consider adding it to id and pull now if you have Java or C++ clients.

If you absolutely have to have completely separate schema for each version, than you'll need avoid the name collisions by either changing the message name in one of the proto files, or separating them into distinct directories so that they have different package prefixes. See https://protobuf.dev/reference/python/python-generated/#package for more details.

@JasonLunn JasonLunn added python wait for user action and removed untriaged auto added to all issues by default when created. labels Oct 7, 2024
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

2 participants