|  | @@ -448,13 +448,17 @@ class _SingleThreadedRendezvous(_Rendezvous, grpc.Call, grpc.Future):  # pylint:
 | 
	
		
			
				|  |  |      The __next__ method of _SingleThreadedRendezvous does not depend on the
 | 
	
		
			
				|  |  |      existence of any other thread, including the "channel spin thread".
 | 
	
		
			
				|  |  |      However, this means that its interface is entirely synchronous. So this
 | 
	
		
			
				|  |  | -    class cannot fulfill the grpc.Future interface.
 | 
	
		
			
				|  |  | +    class cannot completely fulfill the grpc.Future interface. The result,
 | 
	
		
			
				|  |  | +    exception, and traceback methods will never block and will instead raise
 | 
	
		
			
				|  |  | +    an exception if calling the method would result in blocking.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    This means that these methods are safe to call from add_done_callback
 | 
	
		
			
				|  |  | +    handlers.
 | 
	
		
			
				|  |  |      """
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      def _is_complete(self):
 | 
	
		
			
				|  |  |          return self._state.code is not None
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |      def cancelled(self):
 | 
	
		
			
				|  |  |          with self._state.condition:
 | 
	
		
			
				|  |  |              return self._state.cancelled
 | 
	
	
		
			
				|  | @@ -468,9 +472,17 @@ class _SingleThreadedRendezvous(_Rendezvous, grpc.Call, grpc.Future):  # pylint:
 | 
	
		
			
				|  |  |              return self._state.code is not None
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      def result(self, timeout=None):
 | 
	
		
			
				|  |  | +        """Returns the result of the computation or raises its exception.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        This method will never block. Instead, it will raise an exception
 | 
	
		
			
				|  |  | +        if calling this method would otherwise result in blocking.
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        del timeout
 | 
	
		
			
				|  |  |          with self._state.condition:
 | 
	
		
			
				|  |  |              if not self._is_complete():
 | 
	
		
			
				|  |  | -                raise Exception("_SingleThreadedRendezvous only supports result() when the RPC is complete.")
 | 
	
		
			
				|  |  | +                raise grpc.experimental.UsageError(
 | 
	
		
			
				|  |  | +                    "_SingleThreadedRendezvous only supports result() when the RPC is complete."
 | 
	
		
			
				|  |  | +                )
 | 
	
		
			
				|  |  |              if self._state.code is grpc.StatusCode.OK:
 | 
	
		
			
				|  |  |                  return self._state.response
 | 
	
		
			
				|  |  |              elif self._state.cancelled:
 | 
	
	
		
			
				|  | @@ -479,9 +491,17 @@ class _SingleThreadedRendezvous(_Rendezvous, grpc.Call, grpc.Future):  # pylint:
 | 
	
		
			
				|  |  |                  raise self
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      def exception(self, timeout=None):
 | 
	
		
			
				|  |  | +        """Return the exception raised by the computation.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        This method will never block. Instead, it will raise an exception
 | 
	
		
			
				|  |  | +        if calling this method would otherwise result in blocking.
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        del timeout
 | 
	
		
			
				|  |  |          with self._state.condition:
 | 
	
		
			
				|  |  |              if not self._is_complete():
 | 
	
		
			
				|  |  | -                raise Exception("_SingleThreadedRendezvous only supports exception() when the RPC is complete.")
 | 
	
		
			
				|  |  | +                raise grpc.experimental.UsageError(
 | 
	
		
			
				|  |  | +                    "_SingleThreadedRendezvous only supports exception() when the RPC is complete."
 | 
	
		
			
				|  |  | +                )
 | 
	
		
			
				|  |  |              if self._state.code is grpc.StatusCode.OK:
 | 
	
		
			
				|  |  |                  return None
 | 
	
		
			
				|  |  |              elif self._state.cancelled:
 | 
	
	
		
			
				|  | @@ -490,9 +510,17 @@ class _SingleThreadedRendezvous(_Rendezvous, grpc.Call, grpc.Future):  # pylint:
 | 
	
		
			
				|  |  |                  return self
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      def traceback(self, timeout=None):
 | 
	
		
			
				|  |  | +        """Access the traceback of the exception raised by the computation.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        This method will never block. Instead, it will raise an exception
 | 
	
		
			
				|  |  | +        if calling this method would otherwise result in blocking.
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        del timeout
 | 
	
		
			
				|  |  |          with self._state.condition:
 | 
	
		
			
				|  |  |              if not self._is_complete():
 | 
	
		
			
				|  |  | -                raise Exception("_SingleThreadedRendezvous only supports traceback() when the RPC is complete.")
 | 
	
		
			
				|  |  | +                raise grpc.experimental.UsageError(
 | 
	
		
			
				|  |  | +                    "_SingleThreadedRendezvous only supports traceback() when the RPC is complete."
 | 
	
		
			
				|  |  | +                )
 | 
	
		
			
				|  |  |              if self._state.code is grpc.StatusCode.OK:
 | 
	
		
			
				|  |  |                  return None
 | 
	
		
			
				|  |  |              elif self._state.cancelled:
 |