def test_Militia(self): tu.print_test_header("test Militia") player2_discard_future = gen.Future() player3_discard_future = gen.Future() select_mock2 = unittest.mock.MagicMock(return_value=player2_discard_future) select_mock3 = unittest.mock.MagicMock(return_value=player3_discard_future) discard_mock2 =unittest.mock.Mock() discard_mock3 =unittest.mock.Mock() self.player2.select = select_mock2 self.player3.select = select_mock3 self.player2.discard = gen.coroutine(discard_mock2) self.player3.discard = gen.coroutine(discard_mock3) base.Militia(self.game, self.player1).play() self.assertTrue(select_mock2.called) self.assertTrue(select_mock3.called) select_mock2.assert_called_with(unittest.mock.ANY, unittest.mock.ANY, crd.card_list_to_titles(self.player2.hand.card_array()), unittest.mock.ANY) player2_selection = crd.card_list_to_titles(self.player2.hand.card_array())[:2] player2_discard_future.set_result(player2_selection) yield gen.moment discard_mock2.assert_called_once_with(player2_selection, self.player2.discard_pile) self.assertTrue(self.player1.last_mode["mode"] == "wait") player3_selection = ["Copper", "Copper"] player3_discard_future.set_result(player3_selection) yield gen.moment discard_mock3.assert_called_once_with(player3_selection, self.player3.discard_pile)
def coroutine(func, replace_callback=True): """Tornado-JSON compatible wrapper for ``tornado.gen.coroutine`` Annotates original argspec.args of ``func`` as attribute ``__argspec_args`` """ # gen.coroutine in tornado 3.x.x and 5.x.x have a different signature than 4.x.x if TORNADO_MAJOR != 4: wrapper = gen.coroutine(func) else: wrapper = gen.coroutine(func, replace_callback) wrapper.__argspec_args = inspect.getargspec(func).args return wrapper
def test_singleton(self): # Class "constructor" reuses objects on the same IOLoop self.assertTrue(SimpleAsyncHTTPClient() is SimpleAsyncHTTPClient()) # unless force_instance is used self.assertTrue(SimpleAsyncHTTPClient() is not SimpleAsyncHTTPClient(force_instance=True)) # different IOLoops use different objects with closing(IOLoop()) as io_loop2: client1 = self.io_loop.run_sync(gen.coroutine(SimpleAsyncHTTPClient)) client2 = io_loop2.run_sync(gen.coroutine(SimpleAsyncHTTPClient)) self.assertTrue(client1 is not client2)
def __init__(self, *args, **kwargs): super(Handler, self).__init__(*args, **kwargs) self.get_context = self.application.asynchronize(self.get_context) self.can_get = self.application.asynchronize(self.can_get) self.can_post = self.application.asynchronize(self.can_post) self.do_get = gen.coroutine(self.do_get) self.do_post = gen.coroutine(self.do_post) self.initkw = kwargs
def coroutine(f): """A coroutine that accepts an optional callback. Given a callback, the function returns None, and the callback is run with (result, error). Without a callback the function returns a Future. """ coro = gen.coroutine(f) @functools.wraps(f) def wrapper(*args, **kwargs): callback = kwargs.pop('callback', None) if callback and not callable(callback): raise CallbackTypeError() future = coro(*args, **kwargs) if callback: def _callback(_future): try: result = _future.result() callback(result, None) except Exception as e: callback(None, e) future.add_done_callback(_callback) else: return future return wrapper
def _parent_process(child_pipe): """ Simulate starting an AsyncProcess and then dying. The child_alive pipe is held open for as long as the child is alive, and can be used to determine if it exited correctly. """ def parent_process_coroutine(): worker_ready = mp_context.Event() worker = AsyncProcess(target=_worker_process, args=(worker_ready, child_pipe)) yield worker.start() # Wait for the child process to have started. worker_ready.wait() # Exit immediately, without doing any process teardown (including atexit # and 'finally:' blocks) as if by SIGKILL. This should cause # worker_process to also exit. os._exit(255) with pristine_loop() as loop: try: loop.run_sync(gen.coroutine(parent_process_coroutine), timeout=10) finally: loop.stop() raise RuntimeError("this should be unreachable due to os._exit")
def inner(): class Foo(object): pass local_var = Foo() self.local_ref = weakref.ref(local_var) yield gen.coroutine(lambda: None)() raise ValueError('Some error')
def _(func): cor = gen.coroutine(func) def test_func(): IOLoop.clear_instance() loop = IOLoop() loop.make_current() s, workers = loop.run_sync(lambda: start_cluster(ncores, Worker=Worker)) args = [s] + workers if executor: e = Executor((s.ip, s.port), loop=loop, start=False) loop.run_sync(e._start) args = [e] + args try: loop.run_sync(lambda: cor(*args), timeout=timeout) finally: if executor: loop.run_sync(e._shutdown) loop.run_sync(lambda: end_cluster(s, workers)) loop.stop() loop.close(all_fds=True) return test_func
def coroutine(f): """A coroutine that accepts an optional callback. Given a callback, the function returns None, and the callback is run with (result, error). Without a callback the function returns a Future. """ coro = gen.coroutine(f) @functools.wraps(f) def wrapper(*args, **kwargs): callback = kwargs.pop('callback', None) if callback and not callable(callback): raise callback_type_error future = coro(*args, **kwargs) if callback: def _callback(_future): try: result = _future.result() callback(result, None) except Exception as e: callback(None, e) future.add_done_callback(_callback) else: return future return wrapper
def _(func): cor = func if not iscoroutinefunction(func): cor = gen.coroutine(func) def test_func(): with pristine_loop() as loop: with check_active_rpc(loop, active_rpc_timeout): s, workers = loop.run_sync(lambda: start_cluster(ncores, scheduler, loop, security=security, Worker=Worker, scheduler_kwargs=scheduler_kwargs, worker_kwargs=worker_kwargs)) args = [s] + workers if client: c = [] @gen.coroutine def f(): c2 = yield Client(s.address, loop=loop, security=security, asynchronous=True) c.append(c2) loop.run_sync(f) args = c + args try: return loop.run_sync(lambda: cor(*args), timeout=timeout) finally: if client: loop.run_sync(c[0]._shutdown) loop.run_sync(lambda: end_cluster(s, workers)) for w in workers: assert not w._comms return test_func
def wdb_tornado(application, start_disabled=False): from tornado.web import RequestHandler, HTTPError from tornado import gen Wdb.enabled = not start_disabled class WdbOn(RequestHandler): def get(self): Wdb.enabled = True self.write('Wdb is now on') application.add_handlers(r'.*', ((r'/__wdb/on', WdbOn),)) old_execute = RequestHandler._execute under = getattr(RequestHandler._execute, '__wrapped__', None) below = 1 def _wdb_execute(*args, **kwargs): from wdb import trace, Wdb if Wdb.enabled: with trace(close_on_exit=True, below=below, under=under): old_execute(*args, **kwargs) else: old_execute(*args, **kwargs) # Close set_trace debuggers stop_trace(close_on_exit=True) RequestHandler._execute = gen.coroutine(_wdb_execute) def _wdb_error_writter(self, status_code, **kwargs): silent = False ex = kwargs.get('exc_info') if ex: silent = issubclass(ex[0], HTTPError) self.finish(_handle_off(silent=silent)) RequestHandler.write_error = _wdb_error_writter
def wrap(f): # Stack up several decorators to allow us to access the generator # object itself. In the innermost wrapper, we capture the generator # and save it in an attribute of self. Next, we run the wrapped # function through @gen.coroutine. Finally, the coroutine is # wrapped again to make it synchronous with run_sync. # # This is a good case study arguing for either some sort of # extensibility in the gen decorators or cancellation support. @functools.wraps(f) def pre_coroutine(self): result = f(self) if isinstance(result, types.GeneratorType): self._test_generator = result else: self._test_generator = None return result coro = gen.coroutine(pre_coroutine) @functools.wraps(coro) def post_coroutine(self): try: return self.io_loop.run_sync( functools.partial(coro, self), timeout=timeout) except TimeoutError as e: # run_sync raises an error with an unhelpful traceback. # If we throw it back into the generator the stack trace # will be replaced by the point where the test is stopped. self._test_generator.throw(e) # In case the test contains an overly broad except clause, # we may get back here. In this case re-raise the original # exception, which is better than nothing. raise return post_coroutine
def _execute_page(self, page_handler_method): self.stages_logger.commit_stage('prepare') preprocessors = _get_preprocessors(page_handler_method.__func__) def _prioritise_preprocessor_by_list(preprocessor): name = _get_preprocessor_name(preprocessor) if name in self._priority_preprocessor_names: return self._priority_preprocessor_names.index(name) else: return math.inf preprocessors.sort(key=_prioritise_preprocessor_by_list) preprocessors_to_run = _unwrap_preprocessors(self.preprocessors) + preprocessors preprocessors_completed = yield self._run_preprocessors(preprocessors_to_run) if not preprocessors_completed: self.log.info('page was already finished, skipping page method') return yield gen.coroutine(page_handler_method)() self._handler_finished_notification() yield self.finish_group.get_finish_future() render_result = yield self._postprocess() if render_result is not None: self.write(render_result)
def _(func): cor = gen.coroutine(func) def test_func(): IOLoop.clear_instance() loop = IOLoop() loop.make_current() s, workers = loop.run_sync( lambda: start_cluster(ncores, Worker=Worker)) args = [s] + workers if executor: e = Executor((s.ip, s.port), loop=loop, start=False) loop.run_sync(e._start) args = [e] + args try: loop.run_sync(lambda: cor(*args), timeout=timeout) finally: if executor: loop.run_sync(e._shutdown) loop.run_sync(lambda: end_cluster(s, workers)) loop.stop() loop.close(all_fds=True) return test_func
def tornado_motor_sock_method(method): """Decorator for socket-like methods on TornadoMotorSocket. The wrapper pauses the current greenlet while I/O is in progress, and uses the Tornado IOLoop to schedule the greenlet for resumption when I/O is ready. """ coro = gen.coroutine(method) @functools.wraps(method) def wrapped(self, *args, **kwargs): child_gr = greenlet.getcurrent() main = child_gr.parent assert main is not None, "Should be on child greenlet" def callback(future): if future.exc_info(): child_gr.throw(*future.exc_info()) elif future.exception(): child_gr.throw(future.exception()) else: child_gr.switch(future.result()) # Ensure the callback runs on the main greenlet. self.io_loop.add_future(coro(self, *args, **kwargs), callback) # Pause this greenlet until the coroutine finishes, # then return its result or raise its exception. return main.switch() return wrapped
def _(func): cor = gen.coroutine(func) def test_func(): with pristine_loop() as loop: with check_active_rpc(loop, active_rpc_timeout): s, workers = loop.run_sync(lambda: start_cluster(ncores, loop, Worker=Worker, scheduler_kwargs=scheduler_kwargs, worker_kwargs=worker_kwargs)) args = [s] + workers if client: e = Client((s.ip, s.port), loop=loop, start=False) loop.run_sync(e._start) args = [e] + args try: return loop.run_sync(lambda: cor(*args), timeout=timeout) finally: if client: loop.run_sync(e._shutdown) loop.run_sync(lambda: end_cluster(s, workers)) for w in workers: assert not w._listen_streams return test_func
def test_func(): with clean() as loop: if iscoroutinefunction(func): cor = func else: cor = gen.coroutine(func) loop.run_sync(cor, timeout=timeout)
def wdb_tornado(application, start_disabled=False): from tornado.web import RequestHandler, HTTPError from tornado import gen Wdb.enabled = not start_disabled class WdbOn(RequestHandler): def get(self): Wdb.enabled = True self.write('Wdb is now on') application.add_handlers(r'.*', ((r'/__wdb/on', WdbOn), )) old_execute = RequestHandler._execute under = getattr(RequestHandler._execute, '__wrapped__', None) below = 1 def _wdb_execute(*args, **kwargs): from wdb import trace, Wdb if Wdb.enabled: with trace(close_on_exit=True, below=below, under=under): old_execute(*args, **kwargs) else: old_execute(*args, **kwargs) # Close set_trace debuggers stop_trace(close_on_exit=True) RequestHandler._execute = gen.coroutine(_wdb_execute) def _wdb_error_writter(self, status_code, **kwargs): silent = False ex = kwargs.get('exc_info') if ex: silent = issubclass(ex[0], HTTPError) self.finish(_handle_off(silent=silent)) RequestHandler.write_error = _wdb_error_writter
def test_func(): with pristine_loop() as loop: cor = gen.coroutine(func) try: loop.run_sync(cor, timeout=timeout) finally: loop.stop()
def generate_async(self, **kwargs): namespace = self._get_namespace(**kwargs) exec_in(self.compiled, namespace) execute = gen.coroutine(namespace["_tt_execute"]) linecache.clearcache() result = yield execute() return result
def wrap(self, *args, **kwargs): query = kwargs.get('query') data = yield self._eval_db_find_one(query) if not data: raises.NotFound(message.not_found(self.table, query)) ret = yield gen.coroutine(xstep)(self, data, *args, **kwargs) raise gen.Return(ret)
def tracecoroutine(f): @wraps(f) def wrapper(*a,**kw): g = f(*a,**kw) thing = None try: if not(hasattr(g,'send')): note('nogen?',f) return while True: thing = g.send(thing) try: thing = yield thing except Exception as e: note('ex down',type(e)) thing = g.throw(e) except StopIteration: pass except gen.Return as e: # why this isn't default, no idea. value = e.value while gen.is_future(value): value = yield value raise gen.Return(value) except Exit: raise except: note.alarm('error in ',f) traceback.print_exc() return return gen.coroutine(wrapper)
def coroutine(func): """Tornado-JSON compatible wrapper for ``tornado.gen.coroutine`` Annotates original argspec.args of ``func`` as attribute ``__argspec_args`` """ wrapper = gen.coroutine(func) wrapper.__argspec_args = inspect.getfullargspec(func).args return wrapper
def coroutine(func, replace_callback=True): """Tornado-JSON compatible wrapper for ``tornado.gen.coroutine`` Annotates original argspec.args of ``func`` as attribute ``__argspec_args`` """ wrapper = gen.coroutine(func, replace_callback) wrapper.__argspec_args = inspect.getargspec(func).args return wrapper
def wrap(self, *args, **kwargs): checks = kwargs.pop('values_check', {}) if checks: for field, check, options in checks: if not check(field, options): raises.BadRequest(message.invalid_value(field, options)) ret = yield gen.coroutine(xstep)(self, *args, **kwargs) raise gen.Return(ret)
def wrap(self, *args, **kwargs): query = kwargs.get('query') if query: to_data = yield dbapi.db_find_one(self.table, query()) if to_data: raises.Forbidden(message.exist(self.table, query())) ret = yield gen.coroutine(xstep)(self, *args, **kwargs) raise gen.Return(ret)
def wrap(f): f = gen.coroutine(f) @functools.wraps(f) def wrapper(self): return self.io_loop.run_sync( functools.partial(f, self), timeout=timeout) return wrapper
def wrap(self, *args, **kwargs): fields = kwargs.pop('miss_fields', []) if fields: for miss in fields: miss_data = self.json_args.get(miss) if miss_data is None or miss_data == '': raises.BadRequest(message.missing(miss)) ret = yield gen.coroutine(xstep)(self, *args, **kwargs) raise gen.Return(ret)
def wrap(self, data, *args, **kwargs): db_keys = kwargs.pop('db_keys', []) query = self._update_query(db_keys, data) if query: to_data = yield dbapi.db_find_one(self.table, query) if to_data: raises.Forbidden(message.exist(self.table, query)) ret = yield gen.coroutine(xstep)(self, data, *args, **kwargs) raise gen.Return(ret)
def _(func): if not iscoroutinefunction(func): func = gen.coroutine(func) def test_func(): old_globals = _globals.copy() result = None workers = [] with pristine_loop() as loop: with check_active_rpc(loop, active_rpc_timeout): @gen.coroutine def coro(): s, ws = yield start_cluster( ncores, scheduler, loop, security=security, Worker=Worker, scheduler_kwargs=scheduler_kwargs, worker_kwargs=worker_kwargs) workers[:] = ws args = [s] + workers if client: c = yield Client(s.address, loop=loop, security=security, asynchronous=True) args = [c] + args try: result = yield func(*args) # for w in workers: # assert not w._comms finally: if client: yield c._close() yield end_cluster(s, workers) _globals.clear() _globals.update(old_globals) raise gen.Return(result) result = loop.run_sync(coro, timeout=timeout) for w in workers: if getattr(w, 'data', None): try: w.data.clear() except EnvironmentError: # zict backends can fail if their storage directory # was already removed pass del w.data return result return test_func
def _run_template_postprocessors(self, postprocessors, rendered_template): for p in postprocessors: rendered_template = yield gen.coroutine(p)(self, rendered_template) if self._finished: self.log.warning('page was already finished, breaking postprocessors chain') return None return rendered_template
def _run_template_postprocessors(self, postprocessors, rendered_template, meta_info): for p in postprocessors: rendered_template = yield gen.coroutine(p)(self, rendered_template, meta_info) if self._finished: self.log.warning('page was already finished, breaking postprocessors chain') return None return rendered_template
def _run_postprocessors(self, postprocessors): for p in postprocessors: yield gen.coroutine(p)(self) if self._finished: self.log.warning('page was already finished, breaking postprocessors chain') return False return True
def wrap(self, *args, **kwargs): carriers = kwargs.pop('carriers', {}) if carriers: for table, query in carriers: exist = yield dbapi.db_find_one(table, query()) if not exist: raises.Forbidden(message.not_found(table, query())) ret = yield gen.coroutine(xstep)(self, *args, **kwargs) raise gen.Return(ret)
def __init__(self, async_client_class=None, **kwargs): self._io_loop = IOLoop(make_current=False) if async_client_class is None: async_client_class = AsyncHTTPClient # Create the client while our IOLoop is "current", without # clobbering the thread's real current IOLoop (if any). self._async_client = self._io_loop.run_sync( gen.coroutine(lambda: async_client_class(**kwargs))) self._closed = False
def wrap(self, *args, **kwargs): carriers = kwargs.get('carriers') if carriers: for table, query in carriers: exist = yield self._eval_db_find_one(query(), table) if not exist: raises.Forbidden(message.not_found(table, query())) ret = yield gen.coroutine(xstep)(self, *args, **kwargs) raise gen.Return(ret)
def _msg_register(fn): if COROUTINE: fn = gen.coroutine(fn) msgTypeList = msgType if isinstance(msgType, list) else [msgType] for t in msgTypeList: if t in INCOME_MSG: self._replyFnDict[t] = fn else: raise ParameterError('Known type register "%s"' % t) return fn
def _(func): if not iscoroutinefunction(func): func = gen.coroutine(func) def test_func(): # Restore default logging levels # XXX use pytest hooks/fixtures instead? for name, level in logging_levels.items(): logging.getLogger(name).setLevel(level) old_globals = _globals.copy() result = None workers = [] with pristine_loop() as loop: with check_active_rpc(loop, active_rpc_timeout): @gen.coroutine def coro(): s, ws = yield start_cluster( ncores, scheduler, loop, security=security, Worker=Worker, scheduler_kwargs=scheduler_kwargs, worker_kwargs=worker_kwargs) workers[:] = ws args = [s] + workers if client: c = yield Client(s.address, loop=loop, security=security, asynchronous=True) args = [c] + args try: result = yield func(*args) if s.validate: s.validate_state() finally: if client: yield c._close() yield end_cluster(s, workers) _globals.clear() _globals.update(old_globals) raise gen.Return(result) result = loop.run_sync(coro, timeout=timeout) for w in workers: if getattr(w, 'data', None): try: w.data.clear() except EnvironmentError: # zict backends can fail if their storage directory # was already removed pass del w.data DequeHandler.clear_all_instances() return result return test_func
def test_attributes(self): self.finished = True def f(): yield gen.moment coro = gen.coroutine(f) self.assertEqual(coro.__name__, f.__name__) self.assertEqual(coro.__module__, f.__module__) self.assertIs(coro.__wrapped__, f) # type: ignore
def test_is_coroutine_function(self): self.finished = True def f(): yield gen.moment coro = gen.coroutine(f) self.assertFalse(gen.is_coroutine_function(f)) self.assertTrue(gen.is_coroutine_function(coro)) self.assertFalse(gen.is_coroutine_function(coro()))
def pub(func): func.public = True if coroutine == True: func.coroutine = True func = gen.coroutine(func) return func
def test_attributes(self): self.finished = True def f(): yield gen.moment coro = gen.coroutine(f) self.assertEqual(coro.__name__, f.__name__) self.assertEqual(coro.__module__, f.__module__) self.assertIs(coro.__wrapped__, f)
def inner(): class Foo(object): pass local_var = Foo() self.local_ref = weakref.ref(local_var) def dummy(): pass yield gen.coroutine(dummy)() raise ValueError('Some error')
def test_func(): with pristine_loop() as loop: if iscoroutinefunction(func): cor = func else: cor = gen.coroutine(func) try: loop.run_sync(cor, timeout=timeout) finally: loop.stop()
def __new__(cls, name, bases, attrs): klass = super(MetaAsyncShifter, cls).__new__(cls, name, bases, attrs) if attrs.get('async'): # ASYNC Wrapper for method_name in dir(bases[0]): method = getattr(bases[0], method_name) if getattr(method, 'ipptool_caller', False): # Patch Method with tornado.gen.coroutine setattr(klass, method_name, coroutine(method.original_method)) return klass
def _msg_register(fn): if COROUTINE: fn = gen.coroutine(fn) msgTypeList = msgType if isinstance(msgType, list) else [msgType] for t in msgTypeList: if t in INCOME_MSG: self._replyFnDict[t] = fn else: raise ParameterError( 'Known type register "%s"' % t) return fn
def wrapper(self, *args, **kwargs): # _Always_ compile the message we'd use in the event of a Dry run. # This ensures that our test cases catch any time invalid **kwargs # are passed in. msg = dry_message.format(*args, **kwargs) if self._dry: self.log.warning(msg) raise gen.Return() ret = yield gen.coroutine(f)(self, *args, **kwargs) raise gen.Return(ret)
def test_func(): IOLoop.clear_instance() loop = IOLoop() loop.make_current() cor = gen.coroutine(func) try: loop.run_sync(cor, timeout=timeout) finally: loop.stop() loop.close(all_fds=True)
def test_func(): before = process_state() with pristine_loop() as loop: cor = gen.coroutine(func) try: loop.run_sync(cor, timeout=timeout) finally: loop.stop() after = process_state() if should_check_state: check_state(before, after)
def wrapper(*args, **kwargs): cofunc = coroutine(func) io_loop = IOLoop.current() try: result = io_loop.run_sync(functools.partial(cofunc, *args, **kwargs)) return result finally: io_loop.clear_current() if not IOLoop.initialized() or io_loop is not IOLoop.instance(): io_loop.close(all_fds=True)