aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Jan Tattermusch <jtattermusch@users.noreply.github.com>2016-04-28 18:42:23 -0700
committerGravatar Jan Tattermusch <jtattermusch@users.noreply.github.com>2016-04-28 18:42:23 -0700
commit2e4bfed08209f1382f1bac82013a7481ffec3f4e (patch)
treea4f95daa527d64d134dc28360ffc3d835c369ed0
parent45177c00feba428a78b98bcd5a3a402ffaaf59ce (diff)
parent832ae81b21025c415fc183b1aa18e063c44180a3 (diff)
Merge pull request #6330 from soltanmm/6264
Allow additive changes to protos w/o forcing user implementation
-rw-r--r--src/compiler/python_generator.cc10
-rw-r--r--src/python/grpcio/tests/protoc_plugin/beta_python_plugin_test.py41
2 files changed, 46 insertions, 5 deletions
diff --git a/src/compiler/python_generator.cc b/src/compiler/python_generator.cc
index 02c032800b..59137e1c92 100644
--- a/src/compiler/python_generator.cc
+++ b/src/compiler/python_generator.cc
@@ -190,7 +190,7 @@ bool PrintBetaServicer(const ServiceDescriptor* service,
"Documentation", doc,
});
out->Print("\n");
- out->Print(dict, "class Beta$Service$Servicer(six.with_metaclass(abc.ABCMeta, object)):\n");
+ out->Print(dict, "class Beta$Service$Servicer(object):\n");
{
IndentScope raii_class_indent(out);
out->Print(dict, "\"\"\"$Documentation$\"\"\"\n");
@@ -198,12 +198,11 @@ bool PrintBetaServicer(const ServiceDescriptor* service,
auto meth = service->method(i);
grpc::string arg_name = meth->client_streaming() ?
"request_iterator" : "request";
- out->Print("@abc.abstractmethod\n");
out->Print("def $Method$(self, $ArgName$, context):\n",
"Method", meth->name(), "ArgName", arg_name);
{
IndentScope raii_method_indent(out);
- out->Print("raise NotImplementedError()\n");
+ out->Print("context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)\n");
}
}
}
@@ -218,7 +217,7 @@ bool PrintBetaStub(const ServiceDescriptor* service,
"Documentation", doc,
});
out->Print("\n");
- out->Print(dict, "class Beta$Service$Stub(six.with_metaclass(abc.ABCMeta, object)):\n");
+ out->Print(dict, "class Beta$Service$Stub(object):\n");
{
IndentScope raii_class_indent(out);
out->Print(dict, "\"\"\"$Documentation$\"\"\"\n");
@@ -227,7 +226,6 @@ bool PrintBetaStub(const ServiceDescriptor* service,
grpc::string arg_name = meth->client_streaming() ?
"request_iterator" : "request";
auto methdict = ListToDict({"Method", meth->name(), "ArgName", arg_name});
- out->Print("@abc.abstractmethod\n");
out->Print(methdict, "def $Method$(self, $ArgName$, timeout):\n");
{
IndentScope raii_method_indent(out);
@@ -450,6 +448,8 @@ bool PrintPreamble(const FileDescriptor* file,
out->Print("import six\n");
out->Print("from $Package$ import implementations as beta_implementations\n",
"Package", config.beta_package_root);
+ out->Print("from $Package$ import interfaces as beta_interfaces\n",
+ "Package", config.beta_package_root);
out->Print("from grpc.framework.common import cardinality\n");
out->Print("from grpc.framework.interfaces.face import utilities as face_utilities\n");
return true;
diff --git a/src/python/grpcio/tests/protoc_plugin/beta_python_plugin_test.py b/src/python/grpcio/tests/protoc_plugin/beta_python_plugin_test.py
index 6fba3d4271..3dc3042e38 100644
--- a/src/python/grpcio/tests/protoc_plugin/beta_python_plugin_test.py
+++ b/src/python/grpcio/tests/protoc_plugin/beta_python_plugin_test.py
@@ -45,6 +45,7 @@ import unittest
from six import moves
from grpc.beta import implementations
+from grpc.beta import interfaces
from grpc.framework.foundation import future
from grpc.framework.interfaces.face import face
from tests.unit.framework.common import test_constants
@@ -178,6 +179,36 @@ def _CreateService(test_pb2):
server.stop(0)
+@contextlib.contextmanager
+def _CreateIncompleteService(test_pb2):
+ """Provides a servicer backend that fails to implement methods and its stub.
+
+ The servicer is just the implementation of the actual servicer passed to the
+ face player of the python RPC implementation; the two are detached.
+
+ Args:
+ test_pb2: The test_pb2 module generated by this test.
+
+ Yields:
+ A (servicer_methods, stub) pair where servicer_methods is the back-end of
+ the service bound to the stub and and stub is the stub on which to invoke
+ RPCs.
+ """
+ servicer_methods = _ServicerMethods(test_pb2)
+
+ class Servicer(getattr(test_pb2, SERVICER_IDENTIFIER)):
+ pass
+
+ servicer = Servicer()
+ server = getattr(test_pb2, SERVER_FACTORY_IDENTIFIER)(servicer)
+ port = server.add_insecure_port('[::]:0')
+ server.start()
+ channel = implementations.insecure_channel('localhost', port)
+ stub = getattr(test_pb2, STUB_FACTORY_IDENTIFIER)(channel)
+ yield servicer_methods, stub
+ server.stop(0)
+
+
def _streaming_input_request_iterator(test_pb2):
for _ in range(3):
request = test_pb2.StreamingInputCallRequest()
@@ -264,6 +295,16 @@ class PythonPluginTest(unittest.TestCase):
with _CreateService(test_pb2) as (servicer, stub):
request = test_pb2.SimpleRequest(response_size=13)
+ def testIncompleteServicer(self):
+ import protoc_plugin_test_pb2 as test_pb2
+ moves.reload_module(test_pb2)
+ with _CreateIncompleteService(test_pb2) as (servicer, stub):
+ request = test_pb2.SimpleRequest(response_size=13)
+ try:
+ response = stub.UnaryCall(request, test_constants.LONG_TIMEOUT)
+ except face.AbortionError as error:
+ self.assertEqual(interfaces.StatusCode.UNIMPLEMENTED, error.code)
+
def testUnaryCall(self):
import protoc_plugin_test_pb2 as test_pb2 # pylint: disable=g-import-not-at-top
moves.reload_module(test_pb2)