| 
					
				 | 
			
			
				@@ -238,7 +238,7 @@ cdef class Event: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   def __cinit__(self, grpc_completion_type type, bint success, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 object tag, Call operation_call, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 CallDetails request_call_details, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                Metadata request_metadata, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                object request_metadata, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 bint is_new_request, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 Operations batch_operations): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     self.type = type 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -437,48 +437,79 @@ cdef class Metadatum: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 cdef class _MetadataIterator: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   cdef size_t i 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  cdef Metadata metadata 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cdef size_t _length 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cdef object _metadatum_indexable 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  def __cinit__(self, Metadata metadata not None): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  def __cinit__(self, length, metadatum_indexable): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    self._length = length 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    self._metadatum_indexable = metadatum_indexable 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     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] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if self.i < self._length: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      result = self._metadatum_indexable[self.i] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       self.i = self.i + 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       return result 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       raise StopIteration 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+# TODO(https://github.com/grpc/grpc/issues/7950): Eliminate this; just use an 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+# ordinary sequence of pairs of bytestrings all the way down to the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+# grpc_call_start_batch call. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 cdef class Metadata: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  """Metadata being passed from application to core.""" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   def __cinit__(self, metadata_iterable): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    metadata_sequence = tuple(metadata_iterable) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cdef size_t count = len(metadata_sequence) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     with nogil: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       grpc_init() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      grpc_metadata_array_init(&self.c_metadata_array) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    metadata = list(metadata_iterable) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    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) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      self.c_metadata = <grpc_metadata *>gpr_malloc( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          count * sizeof(grpc_metadata)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      self.c_count = count 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for index, metadatum in enumerate(metadata_sequence): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      self.c_metadata[index].key = grpc_slice_copy( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          (<Metadatum>metadatum).c_metadata.key) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      self.c_metadata[index].value = grpc_slice_copy( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          (<Metadatum>metadatum).c_metadata.value) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  def __dealloc__(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    with nogil: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for index in range(self.c_count): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        grpc_slice_unref(self.c_metadata[index].key) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        grpc_slice_unref(self.c_metadata[index].value) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      gpr_free(self.c_metadata) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      grpc_shutdown() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  def __len__(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return self.c_count 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  def __getitem__(self, size_t index): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if index < self.c_count: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      key = _slice_bytes(self.c_metadata[index].key) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      value = _slice_bytes(self.c_metadata[index].value) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return Metadatum(key, value) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      raise IndexError() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  def __iter__(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return _MetadataIterator(self.c_count, self) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+cdef class MetadataArray: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  """Metadata being passed from core to application.""" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  def __cinit__(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     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]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      grpc_init() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      grpc_metadata_array_init(&self.c_metadata_array) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   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() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -493,21 +524,7 @@ cdef class Metadata: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return Metadatum(key=key, value=value) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   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 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return _MetadataIterator(self.c_metadata_array.count, self) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 cdef class Operation: 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -547,14 +564,13 @@ cdef class Operation: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     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 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    # TODO(https://github.com/grpc/grpc/issues/7950): Drop the "all Cython 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    # objects must be legitimate for use from Python at any time" policy in 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    # place today, shift the policy toward "Operation objects are only usable 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    # while their calls are active", and move this making-a-copy-because-this- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    # data-needs-to-live-much-longer-than-the-call-from-which-it-arose to the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    # lowest Python layer. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return tuple(self._received_metadata) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   @property 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   def received_status_code(self): 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -601,9 +617,8 @@ def operation_send_initial_metadata(Metadata metadata, int flags): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   cdef Operation op = Operation() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   op.c_op.type = GRPC_OP_SEND_INITIAL_METADATA 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   op.c_op.flags = flags 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  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.c_op.data.send_initial_metadata.count = metadata.c_count 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op.c_op.data.send_initial_metadata.metadata = metadata.c_metadata 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   op.references.append(metadata) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   op.is_valid = True 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return op 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -631,9 +646,8 @@ def operation_send_status_from_server( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   op.c_op.type = GRPC_OP_SEND_STATUS_FROM_SERVER 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   op.c_op.flags = flags 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   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) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      metadata.c_count) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op.c_op.data.send_status_from_server.trailing_metadata = metadata.c_metadata 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   op.c_op.data.send_status_from_server.status = code 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_slice_unref(op._status_details) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   op._status_details = _slice_from_bytes(details) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -646,7 +660,7 @@ def operation_receive_initial_metadata(int flags): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   cdef Operation op = Operation() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   op.c_op.type = GRPC_OP_RECV_INITIAL_METADATA 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   op.c_op.flags = flags 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  op._received_metadata = Metadata([]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op._received_metadata = MetadataArray() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   op.c_op.data.receive_initial_metadata.receive_initial_metadata = ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       &op._received_metadata.c_metadata_array) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   op.is_valid = True 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -669,7 +683,7 @@ def operation_receive_status_on_client(int flags): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   cdef Operation op = Operation() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   op.c_op.type = GRPC_OP_RECV_STATUS_ON_CLIENT 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   op.c_op.flags = flags 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  op._received_metadata = Metadata([]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op._received_metadata = MetadataArray() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   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 = ( 
			 |