This is best illustrated as an example (protobuf files at the bottom of the post):
Python 3.7.10 (default, Nov 21 2022, 05:08:58)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.34.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: from hioscar.rpc.example import counter_pb2
In [2]: counter_pb2.DESCRIPTOR.services_by_name
Out[2]: {'Counter': <google._upb._message.ServiceDescriptor object at 0xffff8f18fd50>}
In [3]: counter_pb2.DESCRIPTOR.services_by_name['Greeter'] # Expect KeyError.
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-3-8c213b6bde3f> in <module>
----> 1 counter_pb2.DESCRIPTOR.services_by_name['Greeter']
KeyError: 'Greeter'
In [4]: from hioscar.rpc.example import helloworld_pb2
In [5]: counter_pb2.DESCRIPTOR.services_by_name # Appears unchanged.
Out[5]: {'Counter': <google._upb._message.ServiceDescriptor object at 0xffff8f18fd50>}
In [6]: counter_pb2.DESCRIPTOR.services_by_name['Greeter'] # WTF, we should get a KeyError!
Out[6]: <google._upb._message.ServiceDescriptor at 0xffff8ee415d0>
In [7]: helloworld_pb2.DESCRIPTOR.services_by_name['Greeter'] is counter_pb2.DESCRIPTOR.services_by_name['Greeter']
Out[7]: True
Expected behavior:
- Importing helloworld_pb2 should not cause
'Greeter' to be a subscriptable key in counter_pb2.DESCRIPTOR.services_by_name.
Actual behavior:
- Although
counter_pb2.DESCRIPTOR.services_by_name.keys() returns the expected results (['Counter']), subscripting and the "contains" operator both show 'Greeter' as a valid key in counter_pb2.DESCRIPTOR.services_by_name.
- If I switch to the pure python implementation, I see the expected behavior instead.
Protobuf version: protobuf==4.21.12 (Python)
Protobuf build: protobuf-4.21.12-cp37-abi3-manylinux2014_aarch64
hioscar/rpc/example/counter.proto
syntax = "proto3";
// ignored when generating python code
package hioscar.rpc.example;
service Counter {
// Service that keeps track of how many times a key has been sent to it
// Meant to be used as an example of how to integrate various data stores
rpc IncrementCount (CountRequest) returns (CountReply) {
}
rpc GetCount (CountRequest) returns (CountReply) {
}
rpc GetCounts (CountsRequest) returns (stream CountReply) {
}
}
// The request message containing the key
message CountRequest {
string key = 1;
}
message CountsRequest {
}
// The response message containing the count of how many times the key has been sent
message CountReply {
string key = 1;
int32 count = 2;
}
hioscar/rpc/example/helloworld.proto
syntax = "proto3";
// ignored when generating python code
package hioscar.rpc.example;
option go_package = "stash.hioscar.com/datago/hioscar/rpc/example";
import "hioscar/extensions/security.proto";
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {
}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
string secret_identity = 2 [(hioscar.extensions.security.secure) = true];
}
// The response message containing the greetings
message HelloReply {
string message = 1;
enum Error {
SUCCESS = 0;
BAD_NAME = 1;
BAD_SECRET_IDENTITY = 2;
}
Error error = 2;
string error_message = 3;
}
message IntToStringMap {
map<int64, string> my_map = 1;
}
This is best illustrated as an example (protobuf files at the bottom of the post):
Expected behavior:
'Greeter'to be a subscriptable key incounter_pb2.DESCRIPTOR.services_by_name.Actual behavior:
counter_pb2.DESCRIPTOR.services_by_name.keys()returns the expected results (['Counter']), subscripting and the "contains" operator both show'Greeter'as a valid key incounter_pb2.DESCRIPTOR.services_by_name.Protobuf version: protobuf==4.21.12 (Python)
Protobuf build: protobuf-4.21.12-cp37-abi3-manylinux2014_aarch64
hioscar/rpc/example/counter.proto
hioscar/rpc/example/helloworld.proto