class Wait: """ Request-like object for sending a :class:`.Line` and waiting on a response. After sending, await an instance of this class to retrieve all collected lines after a success line is received. On failure, a :class:`ValueError` is raised. """ def __init__(self, lines, success, fail, collect): self.lines = lines self._success = tuple(success) self._fail = tuple(fail) self._collect = tuple(collect) self._data = [] self._result = Future() def wants(self, line): return (line.command == IRCTryAgain.COMMAND or line.command in self._success + self._fail + self._collect) @property def done(self): return self._result.done() def add(self, line): if line.command == IRCTryAgain.COMMAND: self._result.set_exception(IRCTryAgain(line)) if line.command in self._collect: self._data.append(line) if line.command in self._success: self._result.set_result(self._data) elif line.command in self._fail: self._result.set_exception(IRCError(line)) def cancel(self): self._result.set_exception(CancelledError("Wait was cancelled")) def __await__(self): return self._result.__await__() def __repr__(self): parts = [] for key in ("success", "fail", "collect"): value = getattr(self, "_{}".format(key)) if value: parts.append("{} {}".format(key, "/".join(value))) return "<{}: {}>".format(self.__class__.__name__, ", ".join(parts))
class BasePartialResult(BaseResultMixin): def __init__(self, result_id, *, fn_map=None): super(BasePartialResult, self).__init__(result_id, fn_map=fn_map) self._queue = Queue() self._fut = Future() async def _set_result(self, data): await self._queue.put(data) async def _set_exception(self, ex): await self._set_result(ex) async def set_partial_result(self, data): await self._set_result(self.map(data)) def __await__(self): return self._fut.__await__() def cancel(self): ensure_future(self._set_exception(StopAsyncIteration()))
def run_or_wait(future: asyncio.Future, loop: asyncio.AbstractEventLoop): if not loop.is_running(): loop.run_until_complete(future) else: list(future.__await__())
class Wait: """ Request-like object for sending a :class:`.Line` and waiting on a response. After sending, await an instance of this class to retrieve all collected lines after a success line is received. On failure, an :class:`IRCError` is raised. Attributes: done (bool): ``True`` once a success or fail line has been received. """ def __init__(self, success, fail, collect): self._success = tuple(success) self._fail = tuple(fail) self._collect = tuple(collect) self._data = [] self._result = Future() @property def done(self): return self._result.done() def add(self, line): """ Consume and handle a line, or raise :class:`TypeError` if it's not applicable to this wait. Args: line (.Line): Incoming line to be handled. """ if self.done: raise ValueError("Wait already resolved") if line.command == IRCTryAgain.COMMAND: self._result.set_exception(IRCTryAgain(line)) return if line.command in self._collect: self._data.append(line) if line.command in self._success: self._result.set_result(self._data) elif line.command in self._fail: self._result.set_exception(IRCError(line)) elif line.command not in self._collect: raise TypeError("Line not applicable") def cancel(self): """ Cancel any tasks waiting on this wait. """ self._result.set_exception(CancelledError("Wait was cancelled")) def __await__(self): return self._result.__await__() def __repr__(self): parts = [] for key in ("success", "fail", "collect"): value = getattr(self, "_{}".format(key)) if value: parts.append("{} {}".format(key, "/".join(value))) return "<{}: {}>".format(self.__class__.__name__, ", ".join(parts))
def __await__(self): return Future.__await__(self)