Skip to content

Service descriptor cross-contamination in UPB implementation #13740

@taliastocks

Description

@taliastocks

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;
}

Metadata

Metadata

Assignees

Labels

inactiveDenotes the issue/PR has not seen activity in the last 90 days.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions