aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/python
diff options
context:
space:
mode:
authorGravatar Craig Tiller <ctiller@google.com>2017-01-26 13:58:52 -0800
committerGravatar Craig Tiller <ctiller@google.com>2017-01-26 13:58:52 -0800
commit48af8b2721c2819eebdaad41872b694377d33876 (patch)
tree47e2b5dc98227bae141baa5be6b5796087e560be /src/python
parenteb757d24e24149e0d4aacb98e13c58c7ff84f5b6 (diff)
parent1291fd4b2f9f502f412c3d6cd5dd5fdc18092842 (diff)
Merge github.com:grpc/grpc into bwest
Diffstat (limited to 'src/python')
-rw-r--r--src/python/grpcio/commands.py12
-rw-r--r--src/python/grpcio/grpc/_channel.py4
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi15
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi14
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi11
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi50
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/records.pxd.pxi12
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi155
-rw-r--r--src/python/grpcio/grpc/_server.py7
-rw-r--r--src/python/grpcio/grpc_core_dependencies.py50
-rw-r--r--src/python/grpcio_tests/commands.py4
-rw-r--r--src/python/grpcio_tests/tests/_loader.py4
-rw-r--r--src/python/grpcio_tests/tests/_runner.py4
-rw-r--r--src/python/grpcio_tests/tests/interop/methods.py15
-rw-r--r--src/python/grpcio_tests/tests/qps/worker_server.py8
-rw-r--r--src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py18
-rw-r--r--src/python/grpcio_tests/tests/unit/_empty_message_test.py8
-rw-r--r--src/python/grpcio_tests/tests/unit/_rpc_test.py5
18 files changed, 207 insertions, 189 deletions
diff --git a/src/python/grpcio/commands.py b/src/python/grpcio/commands.py
index e09f922591..d813df5f44 100644
--- a/src/python/grpcio/commands.py
+++ b/src/python/grpcio/commands.py
@@ -271,12 +271,12 @@ class BuildExt(build_ext.build_ext):
compiler = self.compiler.compiler_type
if compiler in BuildExt.C_OPTIONS:
for extension in self.extensions:
- extension.extra_compile_args += list(BuildExt.C_OPTIONS[
- compiler])
+ extension.extra_compile_args += list(
+ BuildExt.C_OPTIONS[compiler])
if compiler in BuildExt.LINK_OPTIONS:
for extension in self.extensions:
- extension.extra_link_args += list(BuildExt.LINK_OPTIONS[
- compiler])
+ extension.extra_link_args += list(
+ BuildExt.LINK_OPTIONS[compiler])
if not check_and_update_cythonization(self.extensions):
self.extensions = try_cythonize(self.extensions)
try:
@@ -284,8 +284,8 @@ class BuildExt(build_ext.build_ext):
except Exception as error:
formatted_exception = traceback.format_exc()
support.diagnose_build_ext_error(self, error, formatted_exception)
- raise CommandError("Failed `build_ext` step:\n{}".format(
- formatted_exception))
+ raise CommandError(
+ "Failed `build_ext` step:\n{}".format(formatted_exception))
class Gather(setuptools.Command):
diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py
index 77412236cc..5a8a3d487a 100644
--- a/src/python/grpcio/grpc/_channel.py
+++ b/src/python/grpcio/grpc/_channel.py
@@ -842,8 +842,8 @@ def _poll_connectivity(state, channel, initial_try_to_connect):
connectivity = channel.check_connectivity_state(try_to_connect)
with state.lock:
state.connectivity = (
- _common.CYGRPC_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY[
- connectivity])
+ _common.
+ CYGRPC_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY[connectivity])
callbacks = tuple(callback
for callback, unused_but_known_to_be_none_connectivity
in state.callbacks_and_connectivities)
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
index 246e8399bc..73d1ff7b97 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
@@ -60,25 +60,20 @@ cdef class Channel:
method, host, Timespec deadline not None):
if queue.is_shutting_down:
raise ValueError("queue must not be shutting down or shutdown")
- cdef grpc_slice method_slice = _slice_from_bytes(method)
- cdef grpc_slice host_slice
- cdef grpc_slice *host_slice_ptr = NULL
+ cdef char *method_c_string = method
+ cdef char *host_c_string = NULL
if host is not None:
- host_slice = _slice_from_bytes(host)
- host_slice_ptr = &host_slice
+ host_c_string = host
cdef Call operation_call = Call()
- operation_call.references = [self, queue]
+ operation_call.references = [self, method, host, queue]
cdef grpc_call *parent_call = NULL
if parent is not None:
parent_call = parent.c_call
with nogil:
operation_call.c_call = grpc_channel_create_call(
self.c_channel, parent_call, flags,
- queue.c_completion_queue, method_slice, host_slice_ptr,
+ queue.c_completion_queue, method_c_string, host_c_string,
deadline.c_time, NULL)
- grpc_slice_unref(method_slice)
- if host_slice_ptr:
- grpc_slice_unref(host_slice)
return operation_call
def check_connectivity_state(self, bint try_to_connect):
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi
index d8df6c2ef4..a258ba4063 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi
@@ -51,7 +51,6 @@ cdef class CompletionQueue:
cdef CallDetails request_call_details = None
cdef Metadata request_metadata = None
cdef Operations batch_operations = None
- cdef Operation batch_operation = None
if event.type == GRPC_QUEUE_TIMEOUT:
return Event(
event.type, False, None, None, None, None, False, None)
@@ -70,15 +69,8 @@ cdef class CompletionQueue:
user_tag = tag.user_tag
operation_call = tag.operation_call
request_call_details = tag.request_call_details
- if tag.request_metadata is not None:
- request_metadata = tag.request_metadata
- request_metadata._claim_slice_ownership()
+ request_metadata = tag.request_metadata
batch_operations = tag.batch_operations
- if tag.batch_operations is not None:
- for op in batch_operations.operations:
- batch_operation = <Operation>op
- if batch_operation._received_metadata is not None:
- batch_operation._received_metadata._claim_slice_ownership()
if tag.is_new_request:
# Stuff in the tag not explicitly handled by us needs to live through
# the life of the call
@@ -99,7 +91,7 @@ cdef class CompletionQueue:
c_deadline = gpr_inf_future(GPR_CLOCK_REALTIME)
if deadline is not None:
c_deadline = deadline.c_time
-
+
while True:
c_timeout = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), c_increment)
if gpr_time_cmp(c_timeout, c_deadline) > 0:
@@ -108,7 +100,7 @@ cdef class CompletionQueue:
self.c_completion_queue, c_timeout, NULL)
if event.type != GRPC_QUEUE_TIMEOUT or gpr_time_cmp(c_timeout, c_deadline) == 0:
break;
-
+
# Handle any signals
with gil:
cpython.PyErr_CheckSignals()
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
index 04872b9c09..4d988192df 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
@@ -29,6 +29,8 @@
cimport cpython
+import traceback
+
cdef class ChannelCredentials:
@@ -138,15 +140,22 @@ cdef class AuthMetadataContext:
cdef void plugin_get_metadata(
void *state, grpc_auth_metadata_context context,
grpc_credentials_plugin_metadata_cb cb, void *user_data) with gil:
+ called_flag = [False]
def python_callback(
Metadata metadata, grpc_status_code status,
bytes error_details):
cb(user_data, metadata.c_metadata_array.metadata,
metadata.c_metadata_array.count, status, error_details)
+ called_flag[0] = True
cdef CredentialsMetadataPlugin self = <CredentialsMetadataPlugin>state
cdef AuthMetadataContext cy_context = AuthMetadataContext()
cy_context.context = context
- self.plugin_callback(cy_context, python_callback)
+ try:
+ self.plugin_callback(cy_context, python_callback)
+ except Exception as error:
+ if not called_flag[0]:
+ cb(user_data, Metadata([]).c_metadata_array.metadata,
+ 0, StatusCode.unknown, traceback.format_exc().encode())
cdef void plugin_destroy_c_plugin_state(void *state) with gil:
cpython.Py_DECREF(<CredentialsMetadataPlugin>state)
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
index 141580b82a..348d42cb0b 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
@@ -51,13 +51,6 @@ cdef extern from "grpc/byte_buffer_reader.h":
pass
-cdef extern from "grpc/impl/codegen/exec_ctx_fwd.h":
-
- struct grpc_exec_ctx:
- # We don't care about the internals
- pass
-
-
cdef extern from "grpc/grpc.h":
ctypedef struct grpc_slice:
@@ -67,7 +60,6 @@ cdef extern from "grpc/grpc.h":
grpc_slice grpc_slice_ref(grpc_slice s) nogil
void grpc_slice_unref(grpc_slice s) nogil
- grpc_slice grpc_empty_slice() nogil
grpc_slice grpc_slice_new(void *p, size_t len, void (*destroy)(void *)) nogil
grpc_slice grpc_slice_new_with_len(
void *p, size_t len, void (*destroy)(void *, size_t)) nogil
@@ -183,7 +175,7 @@ cdef extern from "grpc/grpc.h":
ctypedef struct grpc_arg_pointer_vtable:
void *(*copy)(void *)
- void (*destroy)(grpc_exec_ctx *, void *)
+ void (*destroy)(void *)
int (*cmp)(void *, void *)
ctypedef struct grpc_arg_value_pointer:
@@ -225,8 +217,9 @@ cdef extern from "grpc/grpc.h":
GRPC_CHANNEL_SHUTDOWN
ctypedef struct grpc_metadata:
- grpc_slice key
- grpc_slice value
+ const char *key
+ const char *value
+ size_t value_length
# ignore the 'internal_data.obfuscated' fields.
ctypedef enum grpc_completion_type:
@@ -248,8 +241,10 @@ cdef extern from "grpc/grpc.h":
void grpc_metadata_array_destroy(grpc_metadata_array *array) nogil
ctypedef struct grpc_call_details:
- grpc_slice method
- grpc_slice host
+ char *method
+ size_t method_capacity
+ char *host
+ size_t host_capacity
gpr_timespec deadline
void grpc_call_details_init(grpc_call_details *details) nogil
@@ -273,22 +268,32 @@ cdef extern from "grpc/grpc.h":
size_t trailing_metadata_count
grpc_metadata *trailing_metadata
grpc_status_code status
- grpc_slice *status_details
+ const char *status_details
ctypedef struct grpc_op_data_recv_status_on_client:
grpc_metadata_array *trailing_metadata
grpc_status_code *status
- grpc_slice *status_details
+ char **status_details
+ size_t *status_details_capacity
ctypedef struct grpc_op_data_recv_close_on_server:
int *cancelled
+ ctypedef struct grpc_op_data_send_message:
+ grpc_byte_buffer *send_message
+
+ ctypedef struct grpc_op_data_receive_message:
+ grpc_byte_buffer **receive_message "recv_message"
+
+ ctypedef struct grpc_op_data_receive_initial_metadata:
+ grpc_metadata_array *receive_initial_metadata "recv_initial_metadata"
+
union grpc_op_data:
grpc_op_data_send_initial_metadata send_initial_metadata
- grpc_byte_buffer *send_message
+ grpc_op_data_send_message send_message
grpc_op_data_send_status_from_server send_status_from_server
- grpc_metadata_array *receive_initial_metadata "recv_initial_metadata"
- grpc_byte_buffer **receive_message "recv_message"
+ grpc_op_data_receive_initial_metadata receive_initial_metadata "recv_initial_metadata"
+ grpc_op_data_receive_message receive_message "recv_message"
grpc_op_data_recv_status_on_client receive_status_on_client "recv_status_on_client"
grpc_op_data_recv_close_on_server receive_close_on_server "recv_close_on_server"
@@ -325,9 +330,9 @@ cdef extern from "grpc/grpc.h":
const grpc_channel_args *args,
void *reserved) nogil
grpc_call *grpc_channel_create_call(
- grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask,
- grpc_completion_queue *completion_queue, grpc_slice method,
- const grpc_slice *host, gpr_timespec deadline, void *reserved) nogil
+ grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask,
+ grpc_completion_queue *completion_queue, const char *method,
+ const char *host, gpr_timespec deadline, void *reserved) nogil
grpc_connectivity_state grpc_channel_check_connectivity_state(
grpc_channel *channel, int try_to_connect) nogil
void grpc_channel_watch_connectivity_state(
@@ -477,7 +482,8 @@ cdef extern from "grpc/compression.h":
grpc_compression_algorithm default_compression_algorithm
int grpc_compression_algorithm_parse(
- grpc_slice value, grpc_compression_algorithm *algorithm) nogil
+ const char *name, size_t name_length,
+ grpc_compression_algorithm *algorithm) nogil
int grpc_compression_algorithm_name(grpc_compression_algorithm algorithm,
char **name) nogil
grpc_compression_algorithm grpc_compression_algorithm_for_level(
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/records.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/records.pxd.pxi
index c4a17118c0..00ec91b131 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/records.pxd.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/records.pxd.pxi
@@ -28,11 +28,6 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-cdef bytes _slice_bytes(grpc_slice slice)
-cdef grpc_slice _copy_slice(grpc_slice slice) nogil
-cdef grpc_slice _slice_from_bytes(bytes value) nogil
-
-
cdef class Timespec:
cdef gpr_timespec c_time
@@ -102,13 +97,13 @@ cdef class ChannelArgs:
cdef class Metadatum:
cdef grpc_metadata c_metadata
- cdef void _copy_metadatum(self, grpc_metadata *destination) nogil
+ cdef object _key, _value
cdef class Metadata:
cdef grpc_metadata_array c_metadata_array
- cdef void _claim_slice_ownership(self)
+ cdef object metadata
cdef class Operation:
@@ -117,7 +112,8 @@ cdef class Operation:
cdef ByteBuffer _received_message
cdef Metadata _received_metadata
cdef grpc_status_code _received_status_code
- cdef grpc_slice _status_details
+ cdef char *_received_status_details
+ cdef size_t _received_status_details_capacity
cdef int _received_cancelled
cdef readonly bint is_valid
cdef object references
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi
index d052b3f8bc..07385129ef 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi
@@ -29,26 +29,6 @@
from libc.stdint cimport intptr_t
-
-cdef bytes _slice_bytes(grpc_slice slice):
- cdef void *start = grpc_slice_start_ptr(slice)
- cdef size_t length = grpc_slice_length(slice)
- return (<const char *>start)[:length]
-
-cdef grpc_slice _copy_slice(grpc_slice slice) nogil:
- cdef void *start = grpc_slice_start_ptr(slice)
- cdef size_t length = grpc_slice_length(slice)
- return grpc_slice_from_copied_buffer(<const char *>start, length)
-
-cdef grpc_slice _slice_from_bytes(bytes value) nogil:
- cdef const char *value_ptr
- cdef size_t length
- with gil:
- value_ptr = <const char *>value
- length = len(value)
- return grpc_slice_from_copied_buffer(value_ptr, length)
-
-
class ConnectivityState:
idle = GRPC_CHANNEL_IDLE
connecting = GRPC_CHANNEL_CONNECTING
@@ -194,6 +174,25 @@ cdef class Timespec:
def infinite_past():
return Timespec(float("-inf"))
+ def __richcmp__(Timespec self not None, Timespec other not None, int op):
+ cdef gpr_timespec self_c_time = self.c_time
+ cdef gpr_timespec other_c_time = other.c_time
+ cdef int result = gpr_time_cmp(self_c_time, other_c_time)
+ if op == 0: # <
+ return result < 0
+ elif op == 2: # ==
+ return result == 0
+ elif op == 4: # >
+ return result > 0
+ elif op == 1: # <=
+ return result <= 0
+ elif op == 3: # !=
+ return result != 0
+ elif op == 5: # >=
+ return result >= 0
+ else:
+ raise ValueError('__richcmp__ `op` contract violated')
+
cdef class CallDetails:
@@ -209,11 +208,17 @@ cdef class CallDetails:
@property
def method(self):
- return _slice_bytes(self.c_details.method)
+ if self.c_details.method != NULL:
+ return <bytes>self.c_details.method
+ else:
+ return None
@property
def host(self):
- return _slice_bytes(self.c_details.host)
+ if self.c_details.host != NULL:
+ return <bytes>self.c_details.host
+ else:
+ return None
@property
def deadline(self):
@@ -324,7 +329,7 @@ cdef void* copy_ptr(void* ptr):
return ptr
-cdef void destroy_ptr(grpc_exec_ctx* ctx, void* ptr):
+cdef void destroy_ptr(void* ptr):
pass
@@ -397,20 +402,19 @@ cdef class ChannelArgs:
cdef class Metadatum:
def __cinit__(self, bytes key, bytes value):
- self.c_metadata.key = _slice_from_bytes(key)
- self.c_metadata.value = _slice_from_bytes(value)
-
- cdef void _copy_metadatum(self, grpc_metadata *destination) nogil:
- destination[0].key = _copy_slice(self.c_metadata.key)
- destination[0].value = _copy_slice(self.c_metadata.value)
+ self._key = key
+ self._value = value
+ self.c_metadata.key = self._key
+ self.c_metadata.value = self._value
+ self.c_metadata.value_length = len(self._value)
@property
def key(self):
- return _slice_bytes(self.c_metadata.key)
+ return <bytes>self.c_metadata.key
@property
def value(self):
- return _slice_bytes(self.c_metadata.value)
+ return <bytes>self.c_metadata.value[:self.c_metadata.value_length]
def __len__(self):
return 2
@@ -426,9 +430,6 @@ cdef class Metadatum:
def __iter__(self):
return iter((self.key, self.value))
- def __dealloc__(self):
- grpc_slice_unref(self.c_metadata.key)
- grpc_slice_unref(self.c_metadata.value)
cdef class _MetadataIterator:
@@ -453,65 +454,51 @@ cdef class _MetadataIterator:
cdef class Metadata:
- def __cinit__(self, metadata_iterable):
- with nogil:
- grpc_init()
- grpc_metadata_array_init(&self.c_metadata_array)
- metadata = list(metadata_iterable)
+ def __cinit__(self, metadata):
+ grpc_init()
+ self.metadata = list(metadata)
for metadatum in metadata:
if not isinstance(metadatum, Metadatum):
raise TypeError("expected list of Metadatum")
- self.c_metadata_array.count = len(metadata)
- self.c_metadata_array.capacity = len(metadata)
+ with nogil:
+ grpc_metadata_array_init(&self.c_metadata_array)
+ self.c_metadata_array.count = len(self.metadata)
+ self.c_metadata_array.capacity = len(self.metadata)
with nogil:
self.c_metadata_array.metadata = <grpc_metadata *>gpr_malloc(
self.c_metadata_array.count*sizeof(grpc_metadata)
)
for i in range(self.c_metadata_array.count):
- (<Metadatum>metadata[i])._copy_metadatum(&self.c_metadata_array.metadata[i])
+ self.c_metadata_array.metadata[i] = (
+ (<Metadatum>self.metadata[i]).c_metadata)
def __dealloc__(self):
- with nogil:
- # this frees the allocated memory for the grpc_metadata_array (although
- # it'd be nice if that were documented somewhere...)
- # TODO(atash): document this in the C core
- grpc_metadata_array_destroy(&self.c_metadata_array)
- grpc_shutdown()
+ # this frees the allocated memory for the grpc_metadata_array (although
+ # it'd be nice if that were documented somewhere...)
+ # TODO(atash): document this in the C core
+ grpc_metadata_array_destroy(&self.c_metadata_array)
+ grpc_shutdown()
def __len__(self):
return self.c_metadata_array.count
def __getitem__(self, size_t i):
- if i >= self.c_metadata_array.count:
- raise IndexError
- key = _slice_bytes(self.c_metadata_array.metadata[i].key)
- value = _slice_bytes(self.c_metadata_array.metadata[i].value)
- return Metadatum(key=key, value=value)
+ return Metadatum(
+ key=<bytes>self.c_metadata_array.metadata[i].key,
+ value=<bytes>self.c_metadata_array.metadata[i].value[
+ :self.c_metadata_array.metadata[i].value_length])
def __iter__(self):
return _MetadataIterator(self)
- cdef void _claim_slice_ownership(self):
- cdef grpc_metadata_array new_c_metadata_array
- grpc_metadata_array_init(&new_c_metadata_array)
- new_c_metadata_array.metadata = <grpc_metadata *>gpr_malloc(
- self.c_metadata_array.count*sizeof(grpc_metadata))
- new_c_metadata_array.count = self.c_metadata_array.count
- for i in range(self.c_metadata_array.count):
- new_c_metadata_array.metadata[i].key = _copy_slice(
- self.c_metadata_array.metadata[i].key)
- new_c_metadata_array.metadata[i].value = _copy_slice(
- self.c_metadata_array.metadata[i].value)
- grpc_metadata_array_destroy(&self.c_metadata_array)
- self.c_metadata_array = new_c_metadata_array
-
cdef class Operation:
def __cinit__(self):
grpc_init()
self.references = []
- self._status_details = grpc_empty_slice()
+ self._received_status_details = NULL
+ self._received_status_details_capacity = 0
self.is_valid = False
@property
@@ -568,13 +555,19 @@ cdef class Operation:
def received_status_details(self):
if self.c_op.type != GRPC_OP_RECV_STATUS_ON_CLIENT:
raise TypeError("self must be an operation receiving status details")
- return _slice_bytes(self._status_details)
+ if self._received_status_details:
+ return self._received_status_details
+ else:
+ return None
@property
def received_status_details_or_none(self):
if self.c_op.type != GRPC_OP_RECV_STATUS_ON_CLIENT:
return None
- return _slice_bytes(self._status_details)
+ if self._received_status_details:
+ return self._received_status_details
+ else:
+ return None
@property
def received_cancelled(self):
@@ -590,7 +583,11 @@ cdef class Operation:
return False if self._received_cancelled == 0 else True
def __dealloc__(self):
- grpc_slice_unref(self._status_details)
+ # We *almost* don't need to do anything; most of the objects are handled by
+ # Python. The remaining one(s) are primitive fields filled in by GRPC core.
+ # This means that we need to clean up after receive_status_on_client.
+ if self.c_op.type == GRPC_OP_RECV_STATUS_ON_CLIENT:
+ gpr_free(self._received_status_details)
grpc_shutdown()
def operation_send_initial_metadata(Metadata metadata, int flags):
@@ -609,7 +606,7 @@ def operation_send_message(data, int flags):
op.c_op.type = GRPC_OP_SEND_MESSAGE
op.c_op.flags = flags
byte_buffer = ByteBuffer(data)
- op.c_op.data.send_message = byte_buffer.c_byte_buffer
+ op.c_op.data.send_message.send_message = byte_buffer.c_byte_buffer
op.references.append(byte_buffer)
op.is_valid = True
return op
@@ -631,10 +628,9 @@ def operation_send_status_from_server(
op.c_op.data.send_status_from_server.trailing_metadata = (
metadata.c_metadata_array.metadata)
op.c_op.data.send_status_from_server.status = code
- grpc_slice_unref(op._status_details)
- op._status_details = _slice_from_bytes(details)
- op.c_op.data.send_status_from_server.status_details = &op._status_details
+ op.c_op.data.send_status_from_server.status_details = details
op.references.append(metadata)
+ op.references.append(details)
op.is_valid = True
return op
@@ -643,7 +639,7 @@ def operation_receive_initial_metadata(int flags):
op.c_op.type = GRPC_OP_RECV_INITIAL_METADATA
op.c_op.flags = flags
op._received_metadata = Metadata([])
- op.c_op.data.receive_initial_metadata = (
+ op.c_op.data.receive_initial_metadata.receive_initial_metadata = (
&op._received_metadata.c_metadata_array)
op.is_valid = True
return op
@@ -656,7 +652,8 @@ def operation_receive_message(int flags):
# n.b. the c_op.data.receive_message field needs to be deleted by us,
# anyway, so we just let that be handled by the ByteBuffer() we allocated
# the line before.
- op.c_op.data.receive_message = &op._received_message.c_byte_buffer
+ op.c_op.data.receive_message.receive_message = (
+ &op._received_message.c_byte_buffer)
op.is_valid = True
return op
@@ -670,7 +667,9 @@ def operation_receive_status_on_client(int flags):
op.c_op.data.receive_status_on_client.status = (
&op._received_status_code)
op.c_op.data.receive_status_on_client.status_details = (
- &op._status_details)
+ &op._received_status_details)
+ op.c_op.data.receive_status_on_client.status_details_capacity = (
+ &op._received_status_details_capacity)
op.is_valid = True
return op
diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py
index 7b7b4d5dab..cbbe2dcbf5 100644
--- a/src/python/grpcio/grpc/_server.py
+++ b/src/python/grpcio/grpc/_server.py
@@ -233,8 +233,9 @@ class _Context(grpc.ServicerContext):
return self._state.client is not _CANCELLED and not self._state.statused
def time_remaining(self):
- return max(self._rpc_event.request_call_details.deadline - time.time(),
- 0)
+ return max(
+ float(self._rpc_event.request_call_details.deadline) - time.time(),
+ 0)
def cancel(self):
self._rpc_event.operation_call.cancel()
@@ -591,8 +592,6 @@ def _handle_with_method_handler(rpc_event, method_handler, thread_pool):
def _handle_call(rpc_event, generic_handlers, thread_pool):
- if not rpc_event.success:
- return None
if rpc_event.request_call_details.method is not None:
method_handler = _find_method_handler(rpc_event, generic_handlers)
if method_handler is None:
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index 470576be51..8a4e7d0fba 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -159,8 +159,6 @@ CORE_SOURCE_FILES = [
'src/core/lib/slice/percent_encoding.c',
'src/core/lib/slice/slice.c',
'src/core/lib/slice/slice_buffer.c',
- 'src/core/lib/slice/slice_hash_table.c',
- 'src/core/lib/slice/slice_intern.c',
'src/core/lib/slice/slice_string_helpers.c',
'src/core/lib/surface/alarm.c',
'src/core/lib/surface/api_trace.c',
@@ -183,13 +181,12 @@ CORE_SOURCE_FILES = [
'src/core/lib/transport/bdp_estimator.c',
'src/core/lib/transport/byte_stream.c',
'src/core/lib/transport/connectivity_state.c',
- 'src/core/lib/transport/error_utils.c',
+ 'src/core/lib/transport/mdstr_hash_table.c',
'src/core/lib/transport/metadata.c',
'src/core/lib/transport/metadata_batch.c',
'src/core/lib/transport/pid_controller.c',
'src/core/lib/transport/service_config.c',
'src/core/lib/transport/static_metadata.c',
- 'src/core/lib/transport/status_conversion.c',
'src/core/lib/transport/timeout_encoding.c',
'src/core/lib/transport/transport.c',
'src/core/lib/transport/transport_op_string.c',
@@ -210,6 +207,7 @@ CORE_SOURCE_FILES = [
'src/core/ext/transport/chttp2/transport/huffsyms.c',
'src/core/ext/transport/chttp2/transport/incoming_metadata.c',
'src/core/ext/transport/chttp2/transport/parsing.c',
+ 'src/core/ext/transport/chttp2/transport/status_conversion.c',
'src/core/ext/transport/chttp2/transport/stream_lists.c',
'src/core/ext/transport/chttp2/transport/stream_map.c',
'src/core/ext/transport/chttp2/transport/varint.c',
@@ -251,11 +249,14 @@ CORE_SOURCE_FILES = [
'src/core/ext/client_channel/connector.c',
'src/core/ext/client_channel/default_initial_connect_string.c',
'src/core/ext/client_channel/http_connect_handshaker.c',
+ 'src/core/ext/client_channel/http_proxy.c',
'src/core/ext/client_channel/initial_connect_string.c',
'src/core/ext/client_channel/lb_policy.c',
'src/core/ext/client_channel/lb_policy_factory.c',
'src/core/ext/client_channel/lb_policy_registry.c',
'src/core/ext/client_channel/parse_address.c',
+ 'src/core/ext/client_channel/proxy_mapper.c',
+ 'src/core/ext/client_channel/proxy_mapper_registry.c',
'src/core/ext/client_channel/resolver.c',
'src/core/ext/client_channel/resolver_factory.c',
'src/core/ext/client_channel/resolver_registry.c',
@@ -299,7 +300,6 @@ CORE_SOURCE_FILES = [
'third_party/boringssl/crypto/aes/mode_wrappers.c',
'third_party/boringssl/crypto/asn1/a_bitstr.c',
'third_party/boringssl/crypto/asn1/a_bool.c',
- 'third_party/boringssl/crypto/asn1/a_bytes.c',
'third_party/boringssl/crypto/asn1/a_d2i_fp.c',
'third_party/boringssl/crypto/asn1/a_dup.c',
'third_party/boringssl/crypto/asn1/a_enum.c',
@@ -318,18 +318,14 @@ CORE_SOURCE_FILES = [
'third_party/boringssl/crypto/asn1/asn1_lib.c',
'third_party/boringssl/crypto/asn1/asn1_par.c',
'third_party/boringssl/crypto/asn1/asn_pack.c',
- 'third_party/boringssl/crypto/asn1/bio_asn1.c',
- 'third_party/boringssl/crypto/asn1/bio_ndef.c',
'third_party/boringssl/crypto/asn1/f_enum.c',
'third_party/boringssl/crypto/asn1/f_int.c',
'third_party/boringssl/crypto/asn1/f_string.c',
'third_party/boringssl/crypto/asn1/t_bitst.c',
- 'third_party/boringssl/crypto/asn1/t_pkey.c',
'third_party/boringssl/crypto/asn1/tasn_dec.c',
'third_party/boringssl/crypto/asn1/tasn_enc.c',
'third_party/boringssl/crypto/asn1/tasn_fre.c',
'third_party/boringssl/crypto/asn1/tasn_new.c',
- 'third_party/boringssl/crypto/asn1/tasn_prn.c',
'third_party/boringssl/crypto/asn1/tasn_typ.c',
'third_party/boringssl/crypto/asn1/tasn_utl.c',
'third_party/boringssl/crypto/asn1/x_bignum.c',
@@ -359,6 +355,7 @@ CORE_SOURCE_FILES = [
'third_party/boringssl/crypto/bn/generic.c',
'third_party/boringssl/crypto/bn/kronecker.c',
'third_party/boringssl/crypto/bn/montgomery.c',
+ 'third_party/boringssl/crypto/bn/montgomery_inv.c',
'third_party/boringssl/crypto/bn/mul.c',
'third_party/boringssl/crypto/bn/prime.c',
'third_party/boringssl/crypto/bn/random.c',
@@ -370,8 +367,7 @@ CORE_SOURCE_FILES = [
'third_party/boringssl/crypto/bytestring/ber.c',
'third_party/boringssl/crypto/bytestring/cbb.c',
'third_party/boringssl/crypto/bytestring/cbs.c',
- 'third_party/boringssl/crypto/chacha/chacha_generic.c',
- 'third_party/boringssl/crypto/chacha/chacha_vec.c',
+ 'third_party/boringssl/crypto/chacha/chacha.c',
'third_party/boringssl/crypto/cipher/aead.c',
'third_party/boringssl/crypto/cipher/cipher.c',
'third_party/boringssl/crypto/cipher/derive_key.c',
@@ -386,10 +382,14 @@ CORE_SOURCE_FILES = [
'third_party/boringssl/crypto/cipher/tls_cbc.c',
'third_party/boringssl/crypto/cmac/cmac.c',
'third_party/boringssl/crypto/conf/conf.c',
+ 'third_party/boringssl/crypto/cpu-aarch64-linux.c',
+ 'third_party/boringssl/crypto/cpu-arm-linux.c',
'third_party/boringssl/crypto/cpu-arm.c',
'third_party/boringssl/crypto/cpu-intel.c',
+ 'third_party/boringssl/crypto/cpu-ppc64le.c',
'third_party/boringssl/crypto/crypto.c',
'third_party/boringssl/crypto/curve25519/curve25519.c',
+ 'third_party/boringssl/crypto/curve25519/spake25519.c',
'third_party/boringssl/crypto/curve25519/x25519-x86_64.c',
'third_party/boringssl/crypto/des/des.c',
'third_party/boringssl/crypto/dh/check.c',
@@ -398,8 +398,6 @@ CORE_SOURCE_FILES = [
'third_party/boringssl/crypto/dh/params.c',
'third_party/boringssl/crypto/digest/digest.c',
'third_party/boringssl/crypto/digest/digests.c',
- 'third_party/boringssl/crypto/directory_posix.c',
- 'third_party/boringssl/crypto/directory_win.c',
'third_party/boringssl/crypto/dsa/dsa.c',
'third_party/boringssl/crypto/dsa/dsa_asn1.c',
'third_party/boringssl/crypto/ec/ec.c',
@@ -418,7 +416,6 @@ CORE_SOURCE_FILES = [
'third_party/boringssl/crypto/ecdsa/ecdsa_asn1.c',
'third_party/boringssl/crypto/engine/engine.c',
'third_party/boringssl/crypto/err/err.c',
- 'third_party/boringssl/crypto/evp/algorithm.c',
'third_party/boringssl/crypto/evp/digestsign.c',
'third_party/boringssl/crypto/evp/evp.c',
'third_party/boringssl/crypto/evp/evp_asn1.c',
@@ -429,6 +426,7 @@ CORE_SOURCE_FILES = [
'third_party/boringssl/crypto/evp/p_rsa.c',
'third_party/boringssl/crypto/evp/p_rsa_asn1.c',
'third_party/boringssl/crypto/evp/pbkdf.c',
+ 'third_party/boringssl/crypto/evp/print.c',
'third_party/boringssl/crypto/evp/sign.c',
'third_party/boringssl/crypto/ex_data.c',
'third_party/boringssl/crypto/hkdf/hkdf.c',
@@ -442,6 +440,12 @@ CORE_SOURCE_FILES = [
'third_party/boringssl/crypto/modes/ctr.c',
'third_party/boringssl/crypto/modes/gcm.c',
'third_party/boringssl/crypto/modes/ofb.c',
+ 'third_party/boringssl/crypto/newhope/error_correction.c',
+ 'third_party/boringssl/crypto/newhope/newhope.c',
+ 'third_party/boringssl/crypto/newhope/ntt.c',
+ 'third_party/boringssl/crypto/newhope/poly.c',
+ 'third_party/boringssl/crypto/newhope/precomp.c',
+ 'third_party/boringssl/crypto/newhope/reduce.c',
'third_party/boringssl/crypto/obj/obj.c',
'third_party/boringssl/crypto/obj/obj_xref.c',
'third_party/boringssl/crypto/pem/pem_all.c',
@@ -459,6 +463,7 @@ CORE_SOURCE_FILES = [
'third_party/boringssl/crypto/poly1305/poly1305.c',
'third_party/boringssl/crypto/poly1305/poly1305_arm.c',
'third_party/boringssl/crypto/poly1305/poly1305_vec.c',
+ 'third_party/boringssl/crypto/rand/deterministic.c',
'third_party/boringssl/crypto/rand/rand.c',
'third_party/boringssl/crypto/rand/urandom.c',
'third_party/boringssl/crypto/rand/windows.c',
@@ -483,11 +488,13 @@ CORE_SOURCE_FILES = [
'third_party/boringssl/crypto/x509/a_sign.c',
'third_party/boringssl/crypto/x509/a_strex.c',
'third_party/boringssl/crypto/x509/a_verify.c',
+ 'third_party/boringssl/crypto/x509/algorithm.c',
'third_party/boringssl/crypto/x509/asn1_gen.c',
'third_party/boringssl/crypto/x509/by_dir.c',
'third_party/boringssl/crypto/x509/by_file.c',
'third_party/boringssl/crypto/x509/i2d_pr.c',
'third_party/boringssl/crypto/x509/pkcs7.c',
+ 'third_party/boringssl/crypto/x509/rsa_pss.c',
'third_party/boringssl/crypto/x509/t_crl.c',
'third_party/boringssl/crypto/x509/t_req.c',
'third_party/boringssl/crypto/x509/t_x509.c',
@@ -562,21 +569,17 @@ CORE_SOURCE_FILES = [
'third_party/boringssl/crypto/x509v3/v3_utl.c',
'third_party/boringssl/ssl/custom_extensions.c',
'third_party/boringssl/ssl/d1_both.c',
- 'third_party/boringssl/ssl/d1_clnt.c',
'third_party/boringssl/ssl/d1_lib.c',
- 'third_party/boringssl/ssl/d1_meth.c',
'third_party/boringssl/ssl/d1_pkt.c',
'third_party/boringssl/ssl/d1_srtp.c',
- 'third_party/boringssl/ssl/d1_srvr.c',
+ 'third_party/boringssl/ssl/dtls_method.c',
'third_party/boringssl/ssl/dtls_record.c',
- 'third_party/boringssl/ssl/pqueue/pqueue.c',
+ 'third_party/boringssl/ssl/handshake_client.c',
+ 'third_party/boringssl/ssl/handshake_server.c',
'third_party/boringssl/ssl/s3_both.c',
- 'third_party/boringssl/ssl/s3_clnt.c',
'third_party/boringssl/ssl/s3_enc.c',
'third_party/boringssl/ssl/s3_lib.c',
- 'third_party/boringssl/ssl/s3_meth.c',
'third_party/boringssl/ssl/s3_pkt.c',
- 'third_party/boringssl/ssl/s3_srvr.c',
'third_party/boringssl/ssl/ssl_aead_ctx.c',
'third_party/boringssl/ssl/ssl_asn1.c',
'third_party/boringssl/ssl/ssl_buffer.c',
@@ -590,6 +593,11 @@ CORE_SOURCE_FILES = [
'third_party/boringssl/ssl/ssl_stat.c',
'third_party/boringssl/ssl/t1_enc.c',
'third_party/boringssl/ssl/t1_lib.c',
+ 'third_party/boringssl/ssl/tls13_both.c',
+ 'third_party/boringssl/ssl/tls13_client.c',
+ 'third_party/boringssl/ssl/tls13_enc.c',
+ 'third_party/boringssl/ssl/tls13_server.c',
+ 'third_party/boringssl/ssl/tls_method.c',
'third_party/boringssl/ssl/tls_record.c',
'third_party/zlib/adler32.c',
'third_party/zlib/compress.c',
diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py
index 845b7f598c..af0ffe3475 100644
--- a/src/python/grpcio_tests/commands.py
+++ b/src/python/grpcio_tests/commands.py
@@ -121,8 +121,8 @@ class BuildProtoModules(setuptools.Command):
'--grpc_python_out={}'.format(PROTO_STEM),
] + [path]
if protoc.main(command) != 0:
- sys.stderr.write('warning: Command:\n{}\nFailed'.format(
- command))
+ sys.stderr.write(
+ 'warning: Command:\n{}\nFailed'.format(command))
# Generated proto directories dont include __init__.py, but
# these are needed for python package resolution
diff --git a/src/python/grpcio_tests/tests/_loader.py b/src/python/grpcio_tests/tests/_loader.py
index 42cf9ab4ca..165bc53fb7 100644
--- a/src/python/grpcio_tests/tests/_loader.py
+++ b/src/python/grpcio_tests/tests/_loader.py
@@ -116,5 +116,5 @@ def iterate_suite_cases(suite):
elif isinstance(item, unittest.TestCase):
yield item
else:
- raise ValueError('unexpected suite item of type {}'.format(
- type(item)))
+ raise ValueError(
+ 'unexpected suite item of type {}'.format(type(item)))
diff --git a/src/python/grpcio_tests/tests/_runner.py b/src/python/grpcio_tests/tests/_runner.py
index 59964b271c..1138a2279d 100644
--- a/src/python/grpcio_tests/tests/_runner.py
+++ b/src/python/grpcio_tests/tests/_runner.py
@@ -196,8 +196,8 @@ class Runner(object):
# Run the tests
result.startTestRun()
for augmented_case in augmented_cases:
- sys.stdout.write('Running {}\n'.format(augmented_case.case.id(
- )))
+ sys.stdout.write(
+ 'Running {}\n'.format(augmented_case.case.id()))
sys.stdout.flush()
case_thread = threading.Thread(
target=augmented_case.case.run, args=(result,))
diff --git a/src/python/grpcio_tests/tests/interop/methods.py b/src/python/grpcio_tests/tests/interop/methods.py
index e1f8722168..bdb258591e 100644
--- a/src/python/grpcio_tests/tests/interop/methods.py
+++ b/src/python/grpcio_tests/tests/interop/methods.py
@@ -428,8 +428,8 @@ def _compute_engine_creds(stub, args):
def _oauth2_auth_token(stub, args):
- json_key_filename = os.environ[
- oauth2client_client.GOOGLE_APPLICATION_CREDENTIALS]
+ json_key_filename = os.environ[oauth2client_client.
+ GOOGLE_APPLICATION_CREDENTIALS]
wanted_email = json.load(open(json_key_filename, 'rb'))['client_email']
response = _large_unary_common_behavior(stub, True, True, None)
if wanted_email != response.username:
@@ -441,8 +441,8 @@ def _oauth2_auth_token(stub, args):
def _jwt_token_creds(stub, args):
- json_key_filename = os.environ[
- oauth2client_client.GOOGLE_APPLICATION_CREDENTIALS]
+ json_key_filename = os.environ[oauth2client_client.
+ GOOGLE_APPLICATION_CREDENTIALS]
wanted_email = json.load(open(json_key_filename, 'rb'))['client_email']
response = _large_unary_common_behavior(stub, True, False, None)
if wanted_email != response.username:
@@ -451,11 +451,10 @@ def _jwt_token_creds(stub, args):
def _per_rpc_creds(stub, args):
- json_key_filename = os.environ[
- oauth2client_client.GOOGLE_APPLICATION_CREDENTIALS]
+ json_key_filename = os.environ[oauth2client_client.
+ GOOGLE_APPLICATION_CREDENTIALS]
wanted_email = json.load(open(json_key_filename, 'rb'))['client_email']
- credentials = oauth2client_client.GoogleCredentials.get_application_default(
- )
+ credentials = oauth2client_client.GoogleCredentials.get_application_default()
scoped_credentials = credentials.create_scoped([args.oauth_scope])
# TODO(https://github.com/grpc/grpc/issues/6799): Eliminate this last
# remaining use of the Beta API.
diff --git a/src/python/grpcio_tests/tests/qps/worker_server.py b/src/python/grpcio_tests/tests/qps/worker_server.py
index 1deb7ed698..ca1a777611 100644
--- a/src/python/grpcio_tests/tests/qps/worker_server.py
+++ b/src/python/grpcio_tests/tests/qps/worker_server.py
@@ -102,8 +102,8 @@ class WorkerServer(services_pb2.WorkerServiceServicer):
'grpc.testing.BenchmarkService', method_implementations)
server.add_generic_rpc_handlers((handler,))
else:
- raise Exception('Unsupported server type {}'.format(
- config.server_type))
+ raise Exception(
+ 'Unsupported server type {}'.format(config.server_type))
if config.HasField('security_params'): # Use SSL
server_creds = grpc.ssl_server_credentials((
@@ -171,8 +171,8 @@ class WorkerServer(services_pb2.WorkerServiceServicer):
else:
raise Exception('Async streaming client not supported')
else:
- raise Exception('Unsupported client type {}'.format(
- config.client_type))
+ raise Exception(
+ 'Unsupported client type {}'.format(config.client_type))
# In multi-channel tests, we split the load across all channels
load_factor = float(config.client_channels)
diff --git a/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py b/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py
index 7aec316b95..b4efe87730 100644
--- a/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py
+++ b/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py
@@ -95,8 +95,18 @@ class TypeSmokeTest(unittest.TestCase):
def testTimespec(self):
now = time.time()
- timespec = cygrpc.Timespec(now)
- self.assertAlmostEqual(now, float(timespec), places=8)
+ now_timespec_a = cygrpc.Timespec(now)
+ now_timespec_b = cygrpc.Timespec(now)
+ self.assertAlmostEqual(now, float(now_timespec_a), places=8)
+ self.assertEqual(now_timespec_a, now_timespec_b)
+ self.assertLess(cygrpc.Timespec(now - 1), cygrpc.Timespec(now))
+ self.assertGreater(cygrpc.Timespec(now + 1), cygrpc.Timespec(now))
+ self.assertGreaterEqual(cygrpc.Timespec(now + 1), cygrpc.Timespec(now))
+ self.assertGreaterEqual(cygrpc.Timespec(now), cygrpc.Timespec(now))
+ self.assertLessEqual(cygrpc.Timespec(now - 1), cygrpc.Timespec(now))
+ self.assertLessEqual(cygrpc.Timespec(now), cygrpc.Timespec(now))
+ self.assertNotEqual(cygrpc.Timespec(now - 1), cygrpc.Timespec(now))
+ self.assertNotEqual(cygrpc.Timespec(now + 1), cygrpc.Timespec(now))
def testCompletionQueueUpDown(self):
completion_queue = cygrpc.CompletionQueue()
@@ -204,8 +214,8 @@ class ServerClientMixin(object):
self.assertTrue(event.success)
self.assertIs(tag, event.tag)
except Exception as error:
- raise Exception("Error in '{}': {}".format(description,
- error.message))
+ raise Exception(
+ "Error in '{}': {}".format(description, error.message))
return event
return test_utilities.SimpleFuture(performer)
diff --git a/src/python/grpcio_tests/tests/unit/_empty_message_test.py b/src/python/grpcio_tests/tests/unit/_empty_message_test.py
index 4588688ea6..155173807f 100644
--- a/src/python/grpcio_tests/tests/unit/_empty_message_test.py
+++ b/src/python/grpcio_tests/tests/unit/_empty_message_test.py
@@ -122,13 +122,13 @@ class EmptyMessageTest(unittest.TestCase):
list(response_iterator))
def testStreamUnary(self):
- response = self._channel.stream_unary(_STREAM_UNARY)(iter(
- [_REQUEST] * test_constants.STREAM_LENGTH))
+ response = self._channel.stream_unary(_STREAM_UNARY)(
+ iter([_REQUEST] * test_constants.STREAM_LENGTH))
self.assertEqual(_RESPONSE, response)
def testStreamStream(self):
- response_iterator = self._channel.stream_stream(_STREAM_STREAM)(iter(
- [_REQUEST] * test_constants.STREAM_LENGTH))
+ response_iterator = self._channel.stream_stream(_STREAM_STREAM)(
+ iter([_REQUEST] * test_constants.STREAM_LENGTH))
self.assertSequenceEqual([_RESPONSE] * test_constants.STREAM_LENGTH,
list(response_iterator))
diff --git a/src/python/grpcio_tests/tests/unit/_rpc_test.py b/src/python/grpcio_tests/tests/unit/_rpc_test.py
index 2cf6dfea62..2b1c85a82d 100644
--- a/src/python/grpcio_tests/tests/unit/_rpc_test.py
+++ b/src/python/grpcio_tests/tests/unit/_rpc_test.py
@@ -81,6 +81,11 @@ class _Handler(object):
servicer_context.set_trailing_metadata(((
'testkey',
'testvalue',),))
+ # TODO(https://github.com/grpc/grpc/issues/8483): test the values
+ # returned by these methods rather than only "smoke" testing that
+ # the return after having been called.
+ servicer_context.is_active()
+ servicer_context.time_remaining()
return request
def handle_unary_stream(self, request, servicer_context):