<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def revoke(self, token, pipe=None):
 """\ Revokes the key associated with the given revokation token. If the token does not exist, a :class:`KeyError <KeyError>` is thrown. Otherwise `None` is returned. If `pipe` is given, then a :class:`RevokeError <shorten.RevokeError>` will not be thrown if the key does not exist. The n-th from last result should be checked like so: :: pipe = redis.Pipeline() store.revoke(token, pipe=pipe) results = pipe.execute() if not results[-1]: raise RevokeError(token) :param pipe: a Redis pipeline. If `None`, the token will be revoked immediately. Otherwise they must be extracted from the pipeline results (see above). """

      
      p = self.redis.pipeline() if pipe is None else pipe    
      
      formatted_token = self.format_token(token)

      try:         
         p.watch(formatted_token)

         # Get the key immediately
         key = p.get(formatted_token)
         formatted_key = self.format_key(key)

         # Make this atomic
         p.multi()
         p.delete(formatted_key, formatted_token)
        
         if pipe is None:
            if not p.execute()[-1]:
               raise RevokeError(token, 'token not found')         

      except WatchError:
         raise

      finally:
         if pipe is None:
            p.reset()