Index: third_party/grpc/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi |
diff --git a/third_party/grpc/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi b/third_party/grpc/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi |
new file mode 100644 |
index 0000000000000000000000000000000000000000..fa4ea99ea9e68e0e6ef965bb4ba1655ea0656529 |
--- /dev/null |
+++ b/third_party/grpc/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi |
@@ -0,0 +1,668 @@ |
+# Copyright 2015-2016, Google Inc. |
+# All rights reserved. |
+# |
+# Redistribution and use in source and binary forms, with or without |
+# modification, are permitted provided that the following conditions are |
+# met: |
+# |
+# * Redistributions of source code must retain the above copyright |
+# notice, this list of conditions and the following disclaimer. |
+# * Redistributions in binary form must reproduce the above |
+# copyright notice, this list of conditions and the following disclaimer |
+# in the documentation and/or other materials provided with the |
+# distribution. |
+# * Neither the name of Google Inc. nor the names of its |
+# contributors may be used to endorse or promote products derived from |
+# this software without specific prior written permission. |
+# |
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
+ |
+ |
+class ConnectivityState: |
+ idle = GRPC_CHANNEL_IDLE |
+ connecting = GRPC_CHANNEL_CONNECTING |
+ ready = GRPC_CHANNEL_READY |
+ transient_failure = GRPC_CHANNEL_TRANSIENT_FAILURE |
+ fatal_failure = GRPC_CHANNEL_FATAL_FAILURE |
+ |
+ |
+class ChannelArgKey: |
+ enable_census = GRPC_ARG_ENABLE_CENSUS |
+ max_concurrent_streams = GRPC_ARG_MAX_CONCURRENT_STREAMS |
+ max_message_length = GRPC_ARG_MAX_MESSAGE_LENGTH |
+ http2_initial_sequence_number = GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER |
+ default_authority = GRPC_ARG_DEFAULT_AUTHORITY |
+ primary_user_agent_string = GRPC_ARG_PRIMARY_USER_AGENT_STRING |
+ secondary_user_agent_string = GRPC_ARG_SECONDARY_USER_AGENT_STRING |
+ ssl_target_name_override = GRPC_SSL_TARGET_NAME_OVERRIDE_ARG |
+ |
+ |
+class WriteFlag: |
+ buffer_hint = GRPC_WRITE_BUFFER_HINT |
+ no_compress = GRPC_WRITE_NO_COMPRESS |
+ |
+ |
+class StatusCode: |
+ ok = GRPC_STATUS_OK |
+ cancelled = GRPC_STATUS_CANCELLED |
+ unknown = GRPC_STATUS_UNKNOWN |
+ invalid_argument = GRPC_STATUS_INVALID_ARGUMENT |
+ deadline_exceeded = GRPC_STATUS_DEADLINE_EXCEEDED |
+ not_found = GRPC_STATUS_NOT_FOUND |
+ already_exists = GRPC_STATUS_ALREADY_EXISTS |
+ permission_denied = GRPC_STATUS_PERMISSION_DENIED |
+ unauthenticated = GRPC_STATUS_UNAUTHENTICATED |
+ resource_exhausted = GRPC_STATUS_RESOURCE_EXHAUSTED |
+ failed_precondition = GRPC_STATUS_FAILED_PRECONDITION |
+ aborted = GRPC_STATUS_ABORTED |
+ out_of_range = GRPC_STATUS_OUT_OF_RANGE |
+ unimplemented = GRPC_STATUS_UNIMPLEMENTED |
+ internal = GRPC_STATUS_INTERNAL |
+ unavailable = GRPC_STATUS_UNAVAILABLE |
+ data_loss = GRPC_STATUS_DATA_LOSS |
+ |
+ |
+class CallError: |
+ ok = GRPC_CALL_OK |
+ error = GRPC_CALL_ERROR |
+ not_on_server = GRPC_CALL_ERROR_NOT_ON_SERVER |
+ not_on_client = GRPC_CALL_ERROR_NOT_ON_CLIENT |
+ already_accepted = GRPC_CALL_ERROR_ALREADY_ACCEPTED |
+ already_invoked = GRPC_CALL_ERROR_ALREADY_INVOKED |
+ not_invoked = GRPC_CALL_ERROR_NOT_INVOKED |
+ already_finished = GRPC_CALL_ERROR_ALREADY_FINISHED |
+ too_many_operations = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS |
+ invalid_flags = GRPC_CALL_ERROR_INVALID_FLAGS |
+ invalid_metadata = GRPC_CALL_ERROR_INVALID_METADATA |
+ |
+ |
+class CompletionType: |
+ queue_shutdown = GRPC_QUEUE_SHUTDOWN |
+ queue_timeout = GRPC_QUEUE_TIMEOUT |
+ operation_complete = GRPC_OP_COMPLETE |
+ |
+ |
+class OperationType: |
+ send_initial_metadata = GRPC_OP_SEND_INITIAL_METADATA |
+ send_message = GRPC_OP_SEND_MESSAGE |
+ send_close_from_client = GRPC_OP_SEND_CLOSE_FROM_CLIENT |
+ send_status_from_server = GRPC_OP_SEND_STATUS_FROM_SERVER |
+ receive_initial_metadata = GRPC_OP_RECV_INITIAL_METADATA |
+ receive_message = GRPC_OP_RECV_MESSAGE |
+ receive_status_on_client = GRPC_OP_RECV_STATUS_ON_CLIENT |
+ receive_close_on_server = GRPC_OP_RECV_CLOSE_ON_SERVER |
+ |
+ |
+cdef class Timespec: |
+ |
+ def __cinit__(self, time): |
+ if time is None: |
+ self.c_time = gpr_now(GPR_CLOCK_REALTIME) |
+ return |
+ if isinstance(time, int): |
+ time = float(time) |
+ if isinstance(time, float): |
+ if time == float("+inf"): |
+ self.c_time = gpr_inf_future(GPR_CLOCK_REALTIME) |
+ elif time == float("-inf"): |
+ self.c_time = gpr_inf_past(GPR_CLOCK_REALTIME) |
+ else: |
+ self.c_time.seconds = time |
+ self.c_time.nanoseconds = (time - float(self.c_time.seconds)) * 1e9 |
+ self.c_time.clock_type = GPR_CLOCK_REALTIME |
+ elif isinstance(time, Timespec): |
+ self.c_time = (<Timespec>time).c_time |
+ else: |
+ raise TypeError("expected time to be float, int, or Timespec, not {}" |
+ .format(type(time))) |
+ |
+ @property |
+ def seconds(self): |
+ # TODO(atash) ensure that everywhere a Timespec is created that it's |
+ # converted to GPR_CLOCK_REALTIME then and not every time someone wants to |
+ # read values off in Python. |
+ cdef gpr_timespec real_time = ( |
+ gpr_convert_clock_type(self.c_time, GPR_CLOCK_REALTIME)) |
+ return real_time.seconds |
+ |
+ @property |
+ def nanoseconds(self): |
+ cdef gpr_timespec real_time = ( |
+ gpr_convert_clock_type(self.c_time, GPR_CLOCK_REALTIME)) |
+ return real_time.nanoseconds |
+ |
+ def __float__(self): |
+ cdef gpr_timespec real_time = ( |
+ gpr_convert_clock_type(self.c_time, GPR_CLOCK_REALTIME)) |
+ return <double>real_time.seconds + <double>real_time.nanoseconds / 1e9 |
+ |
+ @staticmethod |
+ def infinite_future(): |
+ return Timespec(float("+inf")) |
+ |
+ @staticmethod |
+ def infinite_past(): |
+ return Timespec(float("-inf")) |
+ |
+ |
+cdef class CallDetails: |
+ |
+ def __cinit__(self): |
+ grpc_call_details_init(&self.c_details) |
+ |
+ def __dealloc__(self): |
+ grpc_call_details_destroy(&self.c_details) |
+ |
+ @property |
+ def method(self): |
+ if self.c_details.method != NULL: |
+ return <bytes>self.c_details.method |
+ else: |
+ return None |
+ |
+ @property |
+ def host(self): |
+ if self.c_details.host != NULL: |
+ return <bytes>self.c_details.host |
+ else: |
+ return None |
+ |
+ @property |
+ def deadline(self): |
+ timespec = Timespec(float("-inf")) |
+ timespec.c_time = self.c_details.deadline |
+ return timespec |
+ |
+ |
+cdef class OperationTag: |
+ |
+ def __cinit__(self, user_tag): |
+ self.user_tag = user_tag |
+ self.references = [] |
+ |
+ |
+cdef class Event: |
+ |
+ def __cinit__(self, grpc_completion_type type, bint success, |
+ object tag, Call operation_call, |
+ CallDetails request_call_details, |
+ Metadata request_metadata, |
+ bint is_new_request, |
+ Operations batch_operations): |
+ self.type = type |
+ self.success = success |
+ self.tag = tag |
+ self.operation_call = operation_call |
+ self.request_call_details = request_call_details |
+ self.request_metadata = request_metadata |
+ self.batch_operations = batch_operations |
+ self.is_new_request = is_new_request |
+ |
+ |
+cdef class ByteBuffer: |
+ |
+ def __cinit__(self, data): |
+ if data is None: |
+ self.c_byte_buffer = NULL |
+ return |
+ if isinstance(data, bytes): |
+ pass |
+ elif isinstance(data, basestring): |
+ data = data.encode() |
+ elif isinstance(data, ByteBuffer): |
+ data = (<ByteBuffer>data).bytes() |
+ if data is None: |
+ self.c_byte_buffer = NULL |
+ return |
+ else: |
+ raise TypeError("expected value to be of type str, bytes, or " |
+ "ByteBuffer, not {}".format(type(data))) |
+ |
+ cdef char *c_data = data |
+ data_slice = gpr_slice_from_copied_buffer(c_data, len(data)) |
+ self.c_byte_buffer = grpc_raw_byte_buffer_create( |
+ &data_slice, 1) |
+ gpr_slice_unref(data_slice) |
+ |
+ def bytes(self): |
+ cdef grpc_byte_buffer_reader reader |
+ cdef gpr_slice data_slice |
+ cdef size_t data_slice_length |
+ cdef void *data_slice_pointer |
+ if self.c_byte_buffer != NULL: |
+ grpc_byte_buffer_reader_init(&reader, self.c_byte_buffer) |
+ result = b"" |
+ while grpc_byte_buffer_reader_next(&reader, &data_slice): |
+ data_slice_pointer = gpr_slice_start_ptr(data_slice) |
+ data_slice_length = gpr_slice_length(data_slice) |
+ result += (<char *>data_slice_pointer)[:data_slice_length] |
+ grpc_byte_buffer_reader_destroy(&reader) |
+ return result |
+ else: |
+ return None |
+ |
+ def __len__(self): |
+ if self.c_byte_buffer != NULL: |
+ return grpc_byte_buffer_length(self.c_byte_buffer) |
+ else: |
+ return 0 |
+ |
+ def __str__(self): |
+ return self.bytes() |
+ |
+ def __dealloc__(self): |
+ if self.c_byte_buffer != NULL: |
+ grpc_byte_buffer_destroy(self.c_byte_buffer) |
+ |
+ |
+cdef class SslPemKeyCertPair: |
+ |
+ def __cinit__(self, private_key, certificate_chain): |
+ if isinstance(private_key, bytes): |
+ self.private_key = private_key |
+ elif isinstance(private_key, basestring): |
+ self.private_key = private_key.encode() |
+ else: |
+ raise TypeError("expected private_key to be of type str or bytes") |
+ if isinstance(certificate_chain, bytes): |
+ self.certificate_chain = certificate_chain |
+ elif isinstance(certificate_chain, basestring): |
+ self.certificate_chain = certificate_chain.encode() |
+ else: |
+ raise TypeError("expected certificate_chain to be of type str or bytes " |
+ "or int") |
+ self.c_pair.private_key = self.private_key |
+ self.c_pair.certificate_chain = self.certificate_chain |
+ |
+ |
+cdef class ChannelArg: |
+ |
+ def __cinit__(self, key, value): |
+ if isinstance(key, bytes): |
+ self.key = key |
+ elif isinstance(key, basestring): |
+ self.key = key.encode() |
+ else: |
+ raise TypeError("expected key to be of type str or bytes") |
+ if isinstance(value, bytes): |
+ self.value = value |
+ self.c_arg.type = GRPC_ARG_STRING |
+ self.c_arg.value.string = self.value |
+ elif isinstance(value, basestring): |
+ self.value = value.encode() |
+ self.c_arg.type = GRPC_ARG_STRING |
+ self.c_arg.value.string = self.value |
+ elif isinstance(value, int): |
+ self.value = int(value) |
+ self.c_arg.type = GRPC_ARG_INTEGER |
+ self.c_arg.value.integer = self.value |
+ else: |
+ raise TypeError("expected value to be of type str or bytes or int") |
+ self.c_arg.key = self.key |
+ |
+ |
+cdef class ChannelArgs: |
+ |
+ def __cinit__(self, args): |
+ self.args = list(args) |
+ for arg in self.args: |
+ if not isinstance(arg, ChannelArg): |
+ raise TypeError("expected list of ChannelArg") |
+ self.c_args.arguments_length = len(self.args) |
+ self.c_args.arguments = <grpc_arg *>gpr_malloc( |
+ self.c_args.arguments_length*sizeof(grpc_arg) |
+ ) |
+ for i in range(self.c_args.arguments_length): |
+ self.c_args.arguments[i] = (<ChannelArg>self.args[i]).c_arg |
+ |
+ def __dealloc__(self): |
+ gpr_free(self.c_args.arguments) |
+ |
+ def __len__(self): |
+ # self.args is never stale; it's only updated from this file |
+ return len(self.args) |
+ |
+ def __getitem__(self, size_t i): |
+ # self.args is never stale; it's only updated from this file |
+ return self.args[i] |
+ |
+ |
+cdef class Metadatum: |
+ |
+ def __cinit__(self, key, value): |
+ if isinstance(key, bytes): |
+ self._key = key |
+ elif isinstance(key, basestring): |
+ self._key = key.encode() |
+ else: |
+ raise TypeError("expected key to be of type str or bytes") |
+ if isinstance(value, bytes): |
+ self._value = value |
+ elif isinstance(value, basestring): |
+ self._value = value.encode() |
+ else: |
+ raise TypeError("expected value to be of type str or bytes") |
+ 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 <bytes>self.c_metadata.key |
+ |
+ @property |
+ def value(self): |
+ return <bytes>self.c_metadata.value[:self.c_metadata.value_length] |
+ |
+ def __len__(self): |
+ return 2 |
+ |
+ def __getitem__(self, size_t i): |
+ if i == 0: |
+ return self.key |
+ elif i == 1: |
+ return self.value |
+ else: |
+ raise IndexError("index must be 0 (key) or 1 (value)") |
+ |
+ def __iter__(self): |
+ return iter((self.key, self.value)) |
+ |
+ |
+cdef class _MetadataIterator: |
+ |
+ cdef size_t i |
+ cdef Metadata metadata |
+ |
+ def __cinit__(self, Metadata metadata not None): |
+ self.i = 0 |
+ self.metadata = metadata |
+ |
+ def __iter__(self): |
+ return self |
+ |
+ def __next__(self): |
+ if self.i < len(self.metadata): |
+ result = self.metadata[self.i] |
+ self.i = self.i + 1 |
+ return result |
+ else: |
+ raise StopIteration |
+ |
+ |
+cdef class Metadata: |
+ |
+ def __cinit__(self, metadata): |
+ self.metadata = list(metadata) |
+ for metadatum in metadata: |
+ if not isinstance(metadatum, Metadatum): |
+ raise TypeError("expected list of Metadatum") |
+ grpc_metadata_array_init(&self.c_metadata_array) |
+ self.c_metadata_array.count = len(self.metadata) |
+ self.c_metadata_array.capacity = len(self.metadata) |
+ 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): |
+ self.c_metadata_array.metadata[i] = ( |
+ (<Metadatum>self.metadata[i]).c_metadata) |
+ |
+ def __dealloc__(self): |
+ # 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) |
+ |
+ def __len__(self): |
+ return self.c_metadata_array.count |
+ |
+ def __getitem__(self, size_t i): |
+ 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 class Operation: |
+ |
+ def __cinit__(self): |
+ self.references = [] |
+ self._received_status_details = NULL |
+ self._received_status_details_capacity = 0 |
+ self.is_valid = False |
+ |
+ @property |
+ def type(self): |
+ return self.c_op.type |
+ |
+ @property |
+ def has_status(self): |
+ return self.c_op.type == GRPC_OP_RECV_STATUS_ON_CLIENT |
+ |
+ @property |
+ def received_message(self): |
+ if self.c_op.type != GRPC_OP_RECV_MESSAGE: |
+ raise TypeError("self must be an operation receiving a message") |
+ return self._received_message |
+ |
+ @property |
+ def received_message_or_none(self): |
+ if self.c_op.type != GRPC_OP_RECV_MESSAGE: |
+ return None |
+ return self._received_message |
+ |
+ @property |
+ def received_metadata(self): |
+ if (self.c_op.type != GRPC_OP_RECV_INITIAL_METADATA and |
+ self.c_op.type != GRPC_OP_RECV_STATUS_ON_CLIENT): |
+ raise TypeError("self must be an operation receiving metadata") |
+ return self._received_metadata |
+ |
+ @property |
+ def received_metadata_or_none(self): |
+ if (self.c_op.type != GRPC_OP_RECV_INITIAL_METADATA and |
+ self.c_op.type != GRPC_OP_RECV_STATUS_ON_CLIENT): |
+ return None |
+ return self._received_metadata |
+ |
+ @property |
+ def received_status_code(self): |
+ if self.c_op.type != GRPC_OP_RECV_STATUS_ON_CLIENT: |
+ raise TypeError("self must be an operation receiving a status code") |
+ return self._received_status_code |
+ |
+ @property |
+ def received_status_code_or_none(self): |
+ if self.c_op.type != GRPC_OP_RECV_STATUS_ON_CLIENT: |
+ return None |
+ return self._received_status_code |
+ |
+ @property |
+ 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") |
+ 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 |
+ if self._received_status_details: |
+ return self._received_status_details |
+ else: |
+ return None |
+ |
+ @property |
+ def received_cancelled(self): |
+ if self.c_op.type != GRPC_OP_RECV_CLOSE_ON_SERVER: |
+ raise TypeError("self must be an operation receiving cancellation " |
+ "information") |
+ return False if self._received_cancelled == 0 else True |
+ |
+ @property |
+ def received_cancelled_or_none(self): |
+ if self.c_op.type != GRPC_OP_RECV_CLOSE_ON_SERVER: |
+ return None |
+ return False if self._received_cancelled == 0 else True |
+ |
+ def __dealloc__(self): |
+ # 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) |
+ |
+def operation_send_initial_metadata(Metadata metadata): |
+ cdef Operation op = Operation() |
+ op.c_op.type = GRPC_OP_SEND_INITIAL_METADATA |
+ op.c_op.data.send_initial_metadata.count = metadata.c_metadata_array.count |
+ op.c_op.data.send_initial_metadata.metadata = ( |
+ metadata.c_metadata_array.metadata) |
+ op.references.append(metadata) |
+ op.is_valid = True |
+ return op |
+ |
+def operation_send_message(data): |
+ cdef Operation op = Operation() |
+ op.c_op.type = GRPC_OP_SEND_MESSAGE |
+ byte_buffer = ByteBuffer(data) |
+ op.c_op.data.send_message = byte_buffer.c_byte_buffer |
+ op.references.append(byte_buffer) |
+ op.is_valid = True |
+ return op |
+ |
+def operation_send_close_from_client(): |
+ cdef Operation op = Operation() |
+ op.c_op.type = GRPC_OP_SEND_CLOSE_FROM_CLIENT |
+ op.is_valid = True |
+ return op |
+ |
+def operation_send_status_from_server( |
+ Metadata metadata, grpc_status_code code, details): |
+ if isinstance(details, bytes): |
+ pass |
+ elif isinstance(details, basestring): |
+ details = details.encode() |
+ else: |
+ raise TypeError("expected a str or bytes object for details") |
+ cdef Operation op = Operation() |
+ op.c_op.type = GRPC_OP_SEND_STATUS_FROM_SERVER |
+ op.c_op.data.send_status_from_server.trailing_metadata_count = ( |
+ metadata.c_metadata_array.count) |
+ 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 |
+ 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 |
+ |
+def operation_receive_initial_metadata(): |
+ cdef Operation op = Operation() |
+ op.c_op.type = GRPC_OP_RECV_INITIAL_METADATA |
+ op._received_metadata = Metadata([]) |
+ op.c_op.data.receive_initial_metadata = ( |
+ &op._received_metadata.c_metadata_array) |
+ op.is_valid = True |
+ return op |
+ |
+def operation_receive_message(): |
+ cdef Operation op = Operation() |
+ op.c_op.type = GRPC_OP_RECV_MESSAGE |
+ op._received_message = ByteBuffer(None) |
+ # 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.is_valid = True |
+ return op |
+ |
+def operation_receive_status_on_client(): |
+ cdef Operation op = Operation() |
+ op.c_op.type = GRPC_OP_RECV_STATUS_ON_CLIENT |
+ op._received_metadata = Metadata([]) |
+ op.c_op.data.receive_status_on_client.trailing_metadata = ( |
+ &op._received_metadata.c_metadata_array) |
+ op.c_op.data.receive_status_on_client.status = ( |
+ &op._received_status_code) |
+ op.c_op.data.receive_status_on_client.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 |
+ |
+def operation_receive_close_on_server(): |
+ cdef Operation op = Operation() |
+ op.c_op.type = GRPC_OP_RECV_CLOSE_ON_SERVER |
+ op.c_op.data.receive_close_on_server.cancelled = &op._received_cancelled |
+ op.is_valid = True |
+ return op |
+ |
+ |
+cdef class _OperationsIterator: |
+ |
+ cdef size_t i |
+ cdef Operations operations |
+ |
+ def __cinit__(self, Operations operations not None): |
+ self.i = 0 |
+ self.operations = operations |
+ |
+ def __iter__(self): |
+ return self |
+ |
+ def __next__(self): |
+ if self.i < len(self.operations): |
+ result = self.operations[self.i] |
+ self.i = self.i + 1 |
+ return result |
+ else: |
+ raise StopIteration |
+ |
+ |
+cdef class Operations: |
+ |
+ def __cinit__(self, operations): |
+ self.operations = list(operations) # normalize iterable |
+ self.c_ops = NULL |
+ self.c_nops = 0 |
+ for operation in self.operations: |
+ if not isinstance(operation, Operation): |
+ raise TypeError("expected operations to be iterable of Operation") |
+ self.c_nops = len(self.operations) |
+ self.c_ops = <grpc_op *>gpr_malloc( |
+ sizeof(grpc_op)*self.c_nops) |
+ for i in range(self.c_nops): |
+ self.c_ops[i] = (<Operation>(self.operations[i])).c_op |
+ |
+ def __len__(self): |
+ return self.c_nops |
+ |
+ def __getitem__(self, size_t i): |
+ # self.operations is never stale; it's only updated from this file |
+ return self.operations[i] |
+ |
+ def __dealloc__(self): |
+ gpr_free(self.c_ops) |
+ |
+ def __iter__(self): |
+ return _OperationsIterator(self) |
+ |