From 937b56f57bb74ce3348893c71c20b846d9da25cd Mon Sep 17 00:00:00 2001 From: Nipunn Koorapati Date: Thu, 3 Feb 2022 09:14:44 -0800 Subject: [PATCH] Match service argument names to abstract interface (#9418) The base class/documentation suggest that the argument names are `self` and `done`, while the runtime used argument names `srvc` and `callback`. `mypy.stubtest` was able to identify this - as it compares the types (autogenerated by [`mypy-protobuf`](https://github.com/dropbox/mypy-protobuf/)) to the actual code generated by protoc at runtime. Since the stubs assume the generated code matches the abstract interface in service.py - it saw these differences. --- CONTRIBUTORS.txt | 5 ++++ python/google/protobuf/service_reflection.py | 29 ++++++++++++-------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index b8d97fc23d..c2da98f2c6 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -100,3 +100,8 @@ Patch contributors: Andrew Paprocki * Fixed minor IBM xlC compiler build issues * Added atomicops for AIX (POWER) + Nipunn Koorapati + * Provide a type alias field ValueType on EnumTypeWrapper + * Match service argument names to abstract interface + + diff --git a/python/google/protobuf/service_reflection.py b/python/google/protobuf/service_reflection.py index 75c51ff322..c39a1f5545 100644 --- a/python/google/protobuf/service_reflection.py +++ b/python/google/protobuf/service_reflection.py @@ -133,7 +133,7 @@ class _ServiceBuilder(object): """ self.descriptor = service_descriptor - def BuildService(self, cls): + def BuildService(builder, cls): """Constructs the service class. Args: @@ -143,18 +143,25 @@ class _ServiceBuilder(object): # CallMethod needs to operate with an instance of the Service class. This # internal wrapper function exists only to be able to pass the service # instance to the method that does the real CallMethod work. - def _WrapCallMethod(srvc, method_descriptor, - rpc_controller, request, callback): - return self._CallMethod(srvc, method_descriptor, - rpc_controller, request, callback) - self.cls = cls + # Making sure to use exact argument names from the abstract interface in + # service.py to match the type signature + def _WrapCallMethod(self, method_descriptor, + rpc_controller, request, done): + return builder._CallMethod(self, method_descriptor, + rpc_controller, request, done) + def _WrapGetRequestClass(self, method_descriptor): + return builder._GetRequestClass(method_descriptor) + def _WrapGetResponseClass(self, method_descriptor): + return builder._GetResponseClass(method_descriptor) + + builder.cls = cls cls.CallMethod = _WrapCallMethod - cls.GetDescriptor = staticmethod(lambda: self.descriptor) + cls.GetDescriptor = staticmethod(lambda: builder.descriptor) cls.GetDescriptor.__doc__ = "Returns the service descriptor." - cls.GetRequestClass = self._GetRequestClass - cls.GetResponseClass = self._GetResponseClass - for method in self.descriptor.methods: - setattr(cls, method.name, self._GenerateNonImplementedMethod(method)) + cls.GetRequestClass = _WrapGetRequestClass + cls.GetResponseClass = _WrapGetResponseClass + for method in builder.descriptor.methods: + setattr(cls, method.name, builder._GenerateNonImplementedMethod(method)) def _CallMethod(self, srvc, method_descriptor, rpc_controller, request, callback):