def timeout_after(delay, callable=None, *args): thr.enable_async() if callable: with curio.timeout_after(delay): return callable(*args) else: return curio.timeout_after(delay)
async def main(): t1 = await curio.spawn(curio.timeout_after(2, do_watch_m1())) t2 = await curio.spawn(curio.timeout_after(2, do_watch_m2(t1))) with link.open('a') as wr: wr.write("Hello") await t2.join() with pytest.raises(curio.TaskError): await t1.join()
async def http_serve(sock, addr): wrapper = CurioHTTPWrapper(sock) while True: assert wrapper.conn.states == { h11.CLIENT: h11.IDLE, h11.SERVER: h11.IDLE } try: async with curio.timeout_after(TIMEOUT): wrapper.info("Server main loop waiting for request") event = await wrapper.next_event() wrapper.info("Server main loop got event:", event) if type(event) is h11.Request: await send_echo_response(wrapper, event) except Exception as exc: wrapper.info("Error during response handler:", exc) await maybe_send_error_response(wrapper, exc) if wrapper.conn.our_state is h11.MUST_CLOSE: wrapper.info("connection is not reusable, so shutting down") await wrapper.shutdown_and_clean_up() return else: try: wrapper.info("trying to re-use connection") wrapper.conn.start_next_cycle() except h11.ProtocolError: states = wrapper.conn.states wrapper.info("unexpected state", states, "-- bailing out") await maybe_send_error_response( wrapper, RuntimeError("unexpected state {}".format(states))) await wrapper.shutdown_and_clean_up() return
async def http_serve(sock, addr): wrapper = CurioHTTPWrapper(sock) while True: assert wrapper.conn.states == { h11.CLIENT: h11.IDLE, h11.SERVER: h11.IDLE } try: async with curio.timeout_after(TIMEOUT): event = await wrapper.next_event() if type(event) is h11.Request: await send_echo_response(wrapper, event) except Exception as exc: await maybe_send_error_response(wrapper, exc) if wrapper.conn.our_state is h11.MUST_CLOSE: await wrapper.shutdown_and_clean_up() return else: try: wrapper.conn.start_next_cycle() except h11.ProtocolError: states = wrapper.conn.states await maybe_send_error_response( wrapper, RuntimeError("unexpected state {}".format(states))) await wrapper.shutdown_and_clean_up() return
async def make_request(bind_addr): async with curio.timeout_after(60): r = await subprocess.run([ "dig", "+short", f"@{bind_addr[0]}", "-p", f"{bind_addr[1]}", "baidu.com" ]) assert r.returncode == 0
async def http_serve(sock, addr): wrapper = CurioHTTPWrapper(sock) while True: assert wrapper.conn.states == { h11.CLIENT: h11.IDLE, h11.SERVER: h11.IDLE} try: async with curio.timeout_after(TIMEOUT): wrapper.info("Server main loop waiting for request") event = await wrapper.next_event() wrapper.info("Server main loop got event:", event) if type(event) is h11.Request: await send_echo_response(wrapper, event) except Exception as exc: wrapper.info("Error during response handler:", exc) await maybe_send_error_response(wrapper, exc) if wrapper.conn.our_state is h11.MUST_CLOSE: wrapper.info("connection is not reusable, so shutting down") await wrapper.shutdown_and_clean_up() return else: try: wrapper.info("trying to re-use connection") wrapper.conn.start_next_cycle() except h11.ProtocolError: states = wrapper.conn.states wrapper.info("unexpected state", states, "-- bailing out") await maybe_send_error_response( wrapper, RuntimeError("unexpected state {}".format(states))) await wrapper.shutdown_and_clean_up() return
def _heartbeat_loop(gw: 'VoiceGateway', heartbeat_interval: float): """ Heartbeat looper that loops and sends heartbeats to the gateway. :param gw: The gateway to handle. """ # async threads! logger.debug("Sending initial heartbeat.") AWAIT(gw.send_heartbeat()) while True: # this is similar to the normal threaded event waiter # it will time out after heartbeat_interval seconds. try: AWAIT( curio.timeout_after(heartbeat_interval, gw._stop_heartbeating.wait())) except curio.TaskTimeout: pass else: break try: AWAIT(gw.send_heartbeat()) except ReconnectWebsocket: break
async def cancel(self): await self.server_task.cancel() async with curio.timeout_after(10): while len(self.clients) > 0: await curio.sleep(0.5) await super().cancel()
async def make_request(client, url=None): if url is None: url = url_http headers = ["User-Agent: curl/7.54.0", "Accept: */*"] async with client: async with curio.timeout_after(40): response = await client.http_request(url, headers=headers) assert response.size > 0
async def make_request(client, url=None): if url is None: url = "https://cdn.jsdelivr.net/npm/jquery/dist/jquery.min.js" headers = ["User-Agent: curl/7.54.0", "Accept: */*"] async with client: async with curio.timeout_after(20): response = await client.http_request(url, headers=headers) assert response.size > 0
async def web_is_up(service): url = service and service.get("config", {}).get("url") if not url: return { "status": "unconfigured", "message": _('The service is not properly configured as it has not an URL.') } try: async with curio.timeout_after(10): urlp = urlparse(url) extra = {} if urlp.username: extra["auth"] = asks.BasicAuth((urlp.username, urlp.password)) if urlp.port: port = ":" + str(urlp.port) else: port = "" url = "%s://%s%s%s" % (urlp.scheme or "http", urlp.hostname, port, urlp.path) elif '://' not in url: url = "http://" + url res = await asks.get(url, **extra) code = res.status_code if code == 200: return "ok" if code == 401 or code == 403: return { "status": "unauthorized", "code": code, "message": _('Could connect to %s but the server answered not authorized.') % url } return { "status": "nok", "code": code, "message": _('Could connecto to %s, but the server answered with an error status code: %s.') % (url, code) } # except asks.exceptions.SSLError: # return "bad-ssl" # except asks.exceptions.ConnectionError: # return "down" except curio.TaskTimeout: return { "status": "timeout", "message": _('Timeout connecting to %s' % url) } except Exception as e: if '[Errno -2]' in str(e): return { "status": "error", "code": str(e), "message": _('Can not resolve domain name at %s' % (url)) } serverboards.log_traceback(e) return { "status": "error", "code": str(e), "message": _('There was an error connecting to %s: %s' % (url, str(e))) }
async def main(): t = await curio.spawn(curio.timeout_after(1,do_watch())) (p/"xyz").touch() (p/"abcXXd").touch() await t.join() (p/"xyz").touch() #Cover the case where all the first events are filtered out t = await curio.spawn(do_watch()) (p/'XXX').touch() await curio.sleep(0) (p/"abcXXd").touch() await t.join()
async def wait_for_timeout_with_channel(c, timeout_second): try: async with curio.timeout_after(timeout_second): print("start waiting") msg = await c.recv() if msg == "quit" or msg is None: return -1 else: return 1 except curio.TaskTimeout: print("timeout") return 0
async def main(): t = await curio.spawn(curio.timeout_after(1, do_watch())) (p / "xyz").touch() (p / "abcXXd").touch() await t.join() (p / "xyz").touch() #Cover the case where all the first events are filtered out t = await curio.spawn(do_watch()) (p / 'XXX').touch() await curio.sleep(0) (p / "abcXXd").touch() await t.join()
async def process_request(self, wrapper, event): route, params = self.router.match(event) if not route: return False req = Request(wrapper, event.method, params, event.target, event.headers, event.http_version) res = await route.call(req) if type(res) is not Response: raise Exception('expected handler return type to be Response') if wrapper.conn.their_state is h11.SEND_BODY: self.log.debug('handler didnt stream body') await req.body() async with curio.timeout_after(self.timeout): await res.send(wrapper) return True
async def open_connection(host, port, *, create_connection=None): """Return a :class:`Channel` connected to *addr*.""" if create_connection is None: create_connection = protocol.Connection.get_factory() async with curio.timeout_after(1): while True: try: socket = await curio.open_connection(host, port) break except ConnectionRefusedError: await curio.sleep(0.1) connection = create_connection() return await Channel.create(socket, connection)
async def _open_connection(self, resource, timeout=None, **kwargs): scheme, host, port = resource.key sock_co = curio.open_connection( host=host, port=port, **kwargs ) if timeout is not None: sock_co = curio.timeout_after(timeout, sock_co) try: sock = await sock_co except curio.TaskTimeout as ex: raise ConnectTimeout(str(ex)) from None conn = Connection(self._pool, resource, sock) resource.connection = conn # bind resource & connection return conn
async def run(self): """ print every 10 seconds for 5 minutes """ self.state = 'running' try: for iter_count in range(self.num_iterations): print("runner number {}, count {}: {}".format( self.runner_count, iter_count, self.xyz)) try: async with curio.timeout_after(self.sleep_time): await self.cancel_event.wait() print("I've been killed ({}).".format(self.xyz)) return except curio.TaskTimeout: pass finally: self.state = 'finished'
async def get_ip_info(source_ip="0.0.0.0", source_port=54320, stun_host=None, stun_port=3478) -> Tuple[str, str, int]: s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind((source_ip, source_port)) async with curio.timeout_after(2): nat_type, nat = await get_nat_type(s, source_ip, source_port, stun_host=stun_host, stun_port=stun_port) external_ip = nat['ExternalIP'] external_port = nat['ExternalPort'] await s.close() return (nat_type, external_ip, external_port)
async def http_serve(self, sock, addr): transport = CurioHTTPTransport(sock) _request_local.transport = transport _request_local.end_of_message = False while True: assert transport.conn.states == { h11.CLIENT: h11.IDLE, h11.SERVER: h11.IDLE} try: async with curio.timeout_after(TIMEOUT): log.info("Server main loop waiting for request") event = await transport.next_event() log.info(f"Server main loop got event: {event}") if type(event) is h11.Request: request = Request(event) handler = self.router.match(request) status, response = await handler(request) content_type, response = response_to_bytes(handler, response) await respond(status, content_type, response) except Exception as exc: log.info(f"Error during response handler: {exc}") handler = self.router.match_error(exc) status, response = await handler(exc) content_type, response = response_to_bytes(handler, response) await respond(status, content_type, response) if transport.conn.our_state is h11.MUST_CLOSE: log.info("connection is not reusable, so shutting down") await transport.shutdown_and_clean_up() return else: try: log.info("trying to re-use connection") transport.conn.start_next_cycle() except h11.ProtocolError: states = transport.conn.states log.info(f"unexpected state {states} -- bailing out") exc = RuntimeError("unexpected state {}".format(states)) handler = self.router.match_error(exc) status, response = await handler(exc) content_type, response = response_to_bytes(handler, response) await respond(status, content_type, response) await transport.shutdown_and_clean_up() return
def process(self, task_queue, ack_queue, task_module): while self.alive: task_result = None timeout = False self.done_ev.clear() tinfo = None try: try: msg = curio.thread.AWAIT(curio.timeout_after(self.timeout, task_queue.get)) except curio.TaskTimeout: continue if self.alive is False: self.logger.info('%s alive is False' % self.thread_ident) break try: channel, delivery_tag = msg['channel'], msg['delivery_tag'] j_data = json.loads(msg['data']) task, args = j_data['func'], j_data['args'] except Exception as e: self.logger.error('got error msg %s' % msg) else: func = getattr(task_module, task) tinfo = 'task: %s, args: %s' % (task, args) self.logger.info('got %s' % tinfo) # spawn超时 wrap_watch_task = curio.thread.AWAIT(curio.spawn(self.wrap_watch, daemon=True)) curio.thread.AWAIT(wrap_watch_task.join) # 执行 task_result = func(*args) except TimeoutException: timeout = True except WorkerExitException: self.logger.info('%s got WorkerExitException, break' % self.thread_ident) break except Exception as e: self.logger.error('%s catch exception %s' % (tinfo, e)) else: self.logger.info('%s got result: %s' % (tinfo, task_result)) curio.thread.AWAIT((ack_queue.put((channel, delivery_tag)))) if timeout is False: curio.thread.AWAIT(self.done_ev.set()) self.logger.info('worker %s return' % self.thread_ident) return
async def server_is_up(service): url = service and service.get("config", {}).get("url") if not url: return { "status": "unconfigured", "message": _('The service is not properly configured as it has not an URL.') } try: urlp = urlparse(url) except Exception: return { "status": "unconfigured", "message": _('The service is not properly configured as the URL is invalid.') } port = urlp.port or socket.getservbyname(urlp.scheme) ssl = (urlp.scheme or "").endswith("s") # Simple heristic for secure protocols try: ini_t = time.time() async with curio.timeout_after(10): _sock = await curio.open_connection(urlp.hostname, port, ssl=ssl) secs = time.time() - ini_t return { "status": "ok", "message": _("Connected after %.3fs" % secs), "seconds": secs, } await _sock.close() except curio.TaskTimeout: return { "status": "timeout", "message": _('Timeout connecting to %s' % url) } except Exception as e: serverboards.log_traceback(e, service_id=service["uuid"]) return { "status": "error", "message": _('Error connecting to %s: %s' % (url, e)) }
async def tcp_handle(self, sock, addr): wrapper = HTTPWrapper(self, sock, addr) while True: assert wrapper.conn.states == { h11.CLIENT: h11.IDLE, h11.SERVER: h11.IDLE } try: async with curio.timeout_after(self.timeout): event = await wrapper.next_event() self.log.debug('server main loop got event: {}', event) # NOTE: we dont want to timeout the handler if type(event) is h11.Request: if not await self.process_request(wrapper, event): # TODO: 404 handler await wrapper.send_simple_response(404, b'not found') except curio.TaskTimeout: # NOTE: Is it okay to ignore timeout on send async with curio.ignore_after(self.timeout): # TODO: timeout handler await wrapper.send_simple_response(408, None) except Exception as e: await wrapper.maybe_send_error_response(e) if wrapper.conn.our_state is h11.MUST_CLOSE: self.log.debug('must close connection: {}', wrapper.id) await wrapper.kill() return else: self.log.debug('our state is (supposedly) reusable: {}', wrapper.conn.our_state) try: wrapper.conn.start_next_cycle() except h11.ProtocolError as e: self.log.warn( 'couldnt start next cycle: protocolerror: {}', e) await wrapper.maybe_send_error_response(e) # self.log.warn('ProtocolError for connection: {}', wrapper.id) # self.log.warn(e) # await wrapper.kill() return
def wait(self): """Wait until command is done """ timeout = self.holding.timeout try: if timeout: self._rc = _curio.run( _curio.timeout_after(timeout, self.proc.wait)) else: self._rc = _curio.run(self.proc.wait()) except _curio.TaskTimeout: self.proc.kill() raise CmdyTimeoutError( f"Timeout after {self.holding.timeout} seconds.") from None else: if self._rc not in self.holding.okcode and self.holding.raise_: raise CmdyReturnCodeError(self) return self finally: self._close_fds()
async def close(self, warm=True): # close all watch tasks # empty amqp queue await self.spawn_task.cancel() self.alive = False if warm is True: self.logger.info('waiting for watch tasks join, timeout: %s(s)' % self.timeout) try: async with curio.timeout_after(self.timeout): async with curio.TaskGroup(self.watching.values()) as wtg: await wtg.join() except curio.TaskTimeout: # all task would be canceled if task group join timeout!!! self.logger.info('watch task group join timeout...') else: self.logger.info('cold shutdown, cancel all watching tasks') for t in list(self.watching.values()): await t.cancel() return
async def handleConnection(self, sock, addr): conn = self.SocketWrapper(self, sock, maxRecvSize=self.maxReceiveSize) while True: # Process all requests on this connection. try: async with curio.timeout_after(self.connectionTimeout): req = await conn.getNextEvent() if type(req) is h11.Request: # Collect POST data. # # TODO(grun): Re-implement handleRequest() to handle # streamed POST data, not buffer it. data = '' while True: event = await conn.getNextEvent() if type(event) is h11.Data: data += event.data.decode('ascii') elif type(event) is h11.EndOfMessage: break await conn.handleRequest(req, data) except Exception as exc: print(f'Unhandled exception during response handler:') print(traceback.format_exc()) await conn.sendExceptionResponse(exc) if conn.http.our_state is h11.MUST_CLOSE: await conn.closeConnection() break else: try: conn.http.start_next_cycle() except h11.ProtocolError: msg = f'Unexpected HTTP state {conn.http.states}.' exc = RuntimeError(msg) await conn.sendExceptionResponse(exc) await conn.closeConnection() break
async def close(self, warm=True): # do not get amqp msg self.alive = False self.getter_queue._queue = deque() await self.wait_amqp_msg_task.cancel() # wait for worker done if warm is True: try: self.logger.info('watching tasks join, wait %ss' % self.worker_timeout) async with curio.timeout_after(self.worker_timeout): async with curio.TaskGroup( self.watch_tasks.values()) as wtg: await wtg.join() except curio.TaskTimeout: # task_group will cancel all remaining tasks while catch TaskTimeout(CancelError), yes, that is true # so, we do not have to cancel all remaining tasks by ourself self.logger.info('watch_tasks join timeout...') else: # cold close, just cancel all watch tasks for watch_task_obj in list(self.watch_tasks.values()): await watch_task_obj.cancel() self.kill_all_workers() return
async def repl(self, ctx: Context): # `_` will be added in here later env = { 'ctx': ctx, 'bot': ctx.bot, 'client': ctx.bot, # lol 'guild': ctx.guild, 'message': ctx.message, 'channel': ctx.channel, 'author': ctx.author, 'manager': ctx.manager } env.update(sys.modules) dest = ctx.channel.messages if ctx.channel.id in self.sessions: return await dest.send( 'A REPL session is already running in this channel.') self.sessions.add(ctx.channel.id) # We can't not set a value, really await dest.send(f'```\n{sys.version} on {sys.platform}```') def predicate(message): return (message.author.id == ctx.author.id and message.channel.id == ctx.channel.id and message.content.startswith('`') and message.content.endswith('`')) while True: try: async with curio.timeout_after(60 * 15): response = await ctx.bot.wait_for('message_create', predicate=predicate) except curio.TaskTimeout: self.sessions.remove(ctx.channel.id) await dest.send('Timed out after 15 minutes.') return code = self.clean_code(response.content) if code in 'quit quit() exit exit()'.split(): # TODO maybe cool things here? self.sessions.remove(ctx.channel.id) await dest.send('Exiting.') return try: compiled = compile(code, f'<repl session in {ctx.channel.id}>', 'eval') except SyntaxError: # Not a simple eval statement try: compiled = compile(code, f'<repl session in {ctx.channel.id}>', 'exec') except SyntaxError as e: # We failed miserably # traceback.format_exc output was bad message = ( '```\n' 'Traceback (most recent call last):\n' ' File "{0.filename}, line {0.lineno}, in {3}\n' ' {0.text}\n' ' {1:>{0.offset}}\n' # Stupid '{2.__name__}: {0.msg}\n' '```') await dest.send(message.format(e, '^', type(e), __name__)) continue else: executor = exec else: executor = eval stdout = StringIO() # Don't forget to update env['message'] = response try: with contextlib.redirect_stdout(stdout): # Remember: # TypeError: <executor>() takes no keyword arguments result = executor(compiled, env) if inspect.isawaitable(result): result = await result except: output = stdout.getvalue() message = f'```\n{output}\n{traceback.format_exc()}```' else: output = stdout.getvalue() env['_'] = result indent = functools.partial(textwrap.indent, prefix=' ') message = '```\nstdout:\n{0}\nresult:\n{1}```'.format( indent(output or '(Empty)'), indent(str(result))) if len(message) > 2000: await dest.send('Output too long.') else: await dest.send(message)
async def send(self, *requests, timeout=None, full_res=False, raise_for_status=True, session_factory=None, backoff_decorator=lambda x: x): async def resolve_response(request, response): data = None json = None download_file = None upload_file = None # If downloading file: if request.media_download: raise NotImplementedError( "Downloading media isn't supported by this session") else: if response.status_code != 204: # If no (no content) try: json = response.json() except: # noqa: E722 bare-except try: data = response.text except: # noqa: E722 bare-except try: data = response.content except: # noqa: E722 bare-except try: data = response.body except: # noqa: E722 bare-except data = None if request.media_upload: upload_file = request.media_upload.file_path return Response( url=str(response.url), headers=response.headers, status_code=response.status_code, json=json, data=data, reason=response.reason_phrase if getattr( response, "reason_phrase") else None, req=request, download_file=download_file, upload_file=upload_file, session_factory=session_factory, ) @backoff_decorator async def fire_request(request): request.headers["Accept-Encoding"] = "gzip" request.headers["User-Agent"] = "Aiogoogle Asks Curio (gzip)" if request.media_upload: raise NotImplementedError( "Uploading media isn't supported by this session") else: return await self.request( method=request.method, url=request.url, headers=request.headers, data=request.data, json=request.json, # TODO: doesn't work with Asks # verify=request._verify_ssl, ) # ----------------- send sequence ------------------# async def get_response(request): response = await fire_request(request) response = await resolve_response(request, response) if raise_for_status is True: response.raise_for_status() return response async def get_content(request): response = await get_response(request) return response.content # ----------------- /send sequence ------------------# async def execute_tasks(): async with curio.TaskGroup() as g: if full_res is True: tasks = [ await g.spawn(get_response, request) for request in requests ] else: tasks = [ await g.spawn(get_content, request) for request in requests ] return await curio.gather(tasks) session_factory = self.__class__ if session_factory is None else session_factory if timeout is not None: async with curio.timeout_after(timeout): results = await execute_tasks() else: results = await execute_tasks() if isinstance(results, list) and len(results) == 1: return results[0] else: return results
async def main(): t = await curio.spawn(curio.timeout_after(2, do_watch())) delpath() await t.join()
async def web_is_up(service): url = service and service.get("config", {}).get("url") if not url: return { "status": "unconfigured", "message": _('The service is not properly configured as it has not an URL.') } try: async with curio.timeout_after(10): urlp = urlparse(url) extra = {} if urlp.username: extra["auth"] = asks.BasicAuth((urlp.username, urlp.password)) if urlp.port: port = ":" + str(urlp.port) else: port = "" url = "%s://%s%s%s" % (urlp.scheme or "http", urlp.hostname, port, urlp.path) elif '://' not in url: url = "http://" + url res = await asks.get(url, **extra) code = res.status_code if code == 200: return "ok" if code == 401 or code == 403: return { "status": "unauthorized", "code": code, "message": _('Could connect to %s but the server answered not authorized.' ) % url } return { "status": "nok", "code": code, "message": _('Could connecto to %s, but the server answered with an error status code: %s.' ) % (url, code) } # except asks.exceptions.SSLError: # return "bad-ssl" # except asks.exceptions.ConnectionError: # return "down" except curio.TaskTimeout: return { "status": "timeout", "message": _('Timeout connecting to %s' % url) } except Exception as e: if '[Errno -2]' in str(e): return { "status": "error", "code": str(e), "message": _('Can not resolve domain name at %s' % (url)) } serverboards.log_traceback(e) return { "status": "error", "code": str(e), "message": _('There was an error connecting to %s: %s' % (url, str(e))) }
async def send(self, *requests, timeout=None, full_res=False, raise_for_status=True, session_factory=None): async def resolve_response(request, response): data = None json = None download_file = None upload_file = None # If downloading file: if request.media_download: raise NotImplementedError( 'Downloading media isn\'t supported by this session') else: if response.status_code != 204: # If no (no content) try: json = response.json() except: try: data = response.text except: try: data = response.content except: try: data = response.body except: data = None if request.media_upload: upload_file = request.media_upload.file_path return Response(url=str(response.url), headers=response.headers, status_code=response.status_code, json=json, data=data, reason=response.reason_phrase if getattr( response, 'reason_phrase') else None, req=request, download_file=download_file, upload_file=upload_file, session_factory=session_factory) async def fire_request(request): request.headers['Accept-Encoding'] = 'gzip' request.headers['User-Agent'] = 'Aiogoogle Asks Curio (gzip)' if request.media_upload: raise NotImplementedError( 'Uploading media isn\'t supported by this session') else: return await self.request( method=request.method, url=request.url, headers=request.headers, data=request.data, json=request.json, ) #----------------- send sequence ------------------# async def get_response(request): response = await fire_request(request) response = await resolve_response(request, response) if raise_for_status is True: response.raise_for_status() response = _call_callback(request, response) return response async def get_content(request): response = await get_response(request) return response.content #----------------- /send sequence ------------------# async def execute_tasks(): async with curio.TaskGroup() as g: if full_res is True: tasks = [ await g.spawn(get_response, request) for request in requests ] else: tasks = [ await g.spawn(get_content, request) for request in requests ] return await curio.gather(tasks) if session_factory is None: session_factory = self.__class__ if timeout is not None: async with curio.timeout_after(timeout): results = await execute_tasks() else: results = await execute_tasks() if isinstance(results, list) and len(results) == 1: return results[0] else: return results
def wrapper(_self: Any, *args: Any, **kwargs: Any) -> Any: return curio.run( curio.timeout_after(10, fn(_self, *args, **kwargs)) )
async def test_arecv_curio_cancel(): with pynng.Pair0(listen=addr, recv_timeout=5000) as p0: with pytest.raises(curio.CancelledError): async with curio.timeout_after(0.5): await p0.arecv()