def _nested(*managers): """ 支持将多个contextmanager放到单个with语句中。 Copied from the python 2.6 standard library. It's no longer present in python 3 because the with statement natively supports multiple context managers, but that doesn't help if the list of context managers is not known until runtime. """ exits = [] vars = [] exc = (None, None, None) try: for mgr in managers: exit = mgr.__exit__ enter = mgr.__enter__ vars.append(enter()) # 依次对所有的manager调用__enter__并把结果放入vars中 exits.append(exit) yield vars # 一次性把所有enter()的结果以list的形式yield出去 except: exc = sys.exc_info() finally: while exits: exit = exits.pop() # 如果某个contextmanager(cm)镇压了异常,则在它之后的所有cm接收不到exc_info,否则之前的exc_info会被发送给所有的cm # 如果某个cm的__exit__产生了异常,则该异常会代替之前产生的异常 try: if exit(*exc): exc = (None, None, None) except: exc = sys.exc_info() if exc != (None, None, None): # 如果有任何异常产生则抛出 raise_exc_info(exc) # 不要信任sys.exc_info()依然包含正确的信息,其他的异常可能已经在某个exit方法中捕获了
def wrapper(*args, **kwargs): future = Future() callback, args, kwargs = replacer.replace(future.set_result, args, kwargs) if callback is not None: future.add_done_callback(callback) def handle_error(typ, value, tb): future.set_exception(value) return True exc_info = None with ExceptionStackContext(handle_error): try: result = f(*args, **kwargs) if result is not None: raise ReturnValueIgnoredError( "@return_future should not be used with functions " "that return values") except: exc_info = sys.exc_info() raise if exc_info is not None: # If the initial synchronous part of f() raised an exception, # go ahead and raise it to the caller directly without waiting # for them to inspect the Future. raise_exc_info(exc_info) return future
def wrapper(*args, **kwargs): future = Future() if callback_pos is not None and len(args) > callback_pos: # The callback argument is being passed positionally if args[callback_pos] is not None: future.add_done_callback(args[callback_pos]) args = list(args) # *args is normally a tuple args[callback_pos] = future.set_result else: # The callback argument is either omitted or passed by keyword. if kwargs.get('callback') is not None: future.add_done_callback(kwargs.pop('callback')) kwargs['callback'] = future.set_result def handle_error(typ, value, tb): future.set_exception(value) return True exc_info = None with ExceptionStackContext(handle_error): try: result = f(*args, **kwargs) except: exc_info = sys.exc_info() assert result is None, ("@return_future should not be used with " "functions that return values") if exc_info is not None: # If the initial synchronous part of f() raised an exception, # go ahead and raise it to the caller directly without waiting # for them to inspect the Future. raise_exc_info(exc_info) return future
def job_callback(future): if future.exception() is not None: self.log.error('failed applying template %s', self.template_filename) exception = future.exception() if isinstance(exception, jinja2.TemplateSyntaxError): self.log.error(u'%s in file "%s", line %d\n\t%s', exception.__class__.__name__, to_unicode(exception.filename), exception.lineno, to_unicode(exception.message)) elif isinstance(exception, jinja2.TemplateError): self.log.error(u'%s error\n\t%s', exception.__class__.__name__, to_unicode(exception.message)) if isinstance(future, TracebackFuture): raise_exc_info(future.exc_info()) else: raise exception start_time, result = future.result() self.log.stage_tag('tpl') self.log.info('applied template %s in %.2fms', self.template_filename, (time.time() - start_time) * 1000) callback(utf8(result))
def wrapper(*args, **kwargs): future = Future() callback, args, kwargs = replacer.replace(future.set_result, args, kwargs) def handle_error(typ, value, tb): future.set_exception(value) return True exc_info = None with ExceptionStackContext(handle_error): try: result = f(*args, **kwargs) if result is not None: raise ReturnValueIgnoredError( "@return_future should not be used with functions " "that return values") except: exc_info = sys.exc_info() raise if exc_info is not None: # If the initial synchronous part of f() raised an exception, # go ahead and raise it to the caller directly without waiting # for them to inspect the Future. raise_exc_info(exc_info) # If the caller passed in a callback, schedule it to be called # when the future resolves. It is important that this happens # just before we return the future, or else we risk confusing # stack contexts with multiple exceptions (one here with the # immediate exception, and again when the future resolves and # the callback triggers its exception by calling future.result()). if callback is not None: future.add_done_callback(wrap(callback)) return future
def job_callback(future): if future.exception() is not None: self.log.error('failed applying template %s', self.template_filename) exception = future.exception() if isinstance(exception, jinja2.TemplateSyntaxError): self.log.error( u'%s in file "%s", line %d\n\t%s', exception.__class__.__name__, to_unicode(exception.filename), exception.lineno, to_unicode(exception.message) ) elif isinstance(exception, jinja2.TemplateError): self.log.error(u'%s error\n\t%s', exception.__class__.__name__, to_unicode(exception.message)) if isinstance(future, TracebackFuture): raise_exc_info(future.exc_info()) else: raise exception start_time, result = future.result() self.log.stage_tag('tpl') self.log.info('applied template %s in %.2fms', self.template_filename, (time.time() - start_time) * 1000) callback(utf8(result))
def wrapper(*args, **kwargs): future = Future() callback, args, kwargs = replacer.replace(future.set_result, args, kwargs) if callback is not None: future.add_done_callback(callback) def handle_error(typ, value, tb): future.set_exception(value) return True exc_info = None with ExceptionStackContext(handle_error): result = None try: result = f(*args, **kwargs) except: exc_info = sys.exc_info() assert result is None, ("@return_future should not be used with " "functions that return values") if exc_info is not None: # If the initial synchronous part of f() raised an exception, # go ahead and raise it to the caller directly without waiting # for them to inspect the Future. raise_exc_info(exc_info) return future
def handle(request): # kwargs for this function's response_cls constructor response_kwargs = {} status = OK try: response = yield gen.maybe_future(handler(request)) except Exception as e: response = Response() for exc_spec in response_spec.exception_specs: # Each exc_spec is a thriftrw.spec.FieldSpec. The spec # attribute on that is the TypeSpec for the Exception class # and the surface on the TypeSpec is the exception class. exc_cls = exc_spec.spec.surface if isinstance(e, exc_cls): status = FAILED response_kwargs[exc_spec.name] = e break else: raise_exc_info(sys.exc_info()) else: response = response_from_mixed(response) if response_spec.return_spec is not None: assert response.body is not None, ( 'Expected a value to be returned for %s, ' 'but recieved None - only void procedures can ' 'return None.' % function.endpoint) response_kwargs['success'] = response.body response.status = status response.body = response_cls(**response_kwargs) raise gen.Return(response)
def _nested(*managers): """Support multiple context managers in a single with-statement. Copied from the python 2.6 standard library. It's no longer present in python 3 because the with statement natively supports multiple context managers, but that doesn't help if the list of context managers is not known until runtime. """ exits = [] vars = [] exc = (None, None, None) try: for mgr in managers: exit = mgr.__exit__ enter = mgr.__enter__ vars.append(enter()) exits.append(exit) yield vars except: exc = sys.exc_info() finally: while exits: exit = exits.pop() try: if exit(*exc): exc = (None, None, None) except: exc = sys.exc_info() if exc != (None, None, None): # Don't rely on sys.exc_info() still containing # the right information. Another exception may # have been raised and caught by an exit method raise_exc_info(exc)
def handle(request): # kwargs for this function's response_cls constructor response_kwargs = {} status = OK try: response = yield gen.maybe_future(handler(request)) except Exception as e: response = Response() for exc_spec in response_spec.exception_specs: # Each exc_spec is a thriftrw.spec.FieldSpec. The spec # attribute on that is the TypeSpec for the Exception class # and the surface on the TypeSpec is the exception class. exc_cls = exc_spec.spec.surface if isinstance(e, exc_cls): status = FAILED response_kwargs[exc_spec.name] = e break else: raise_exc_info(sys.exc_info()) else: response = response_from_mixed(response) if response_spec.return_spec is not None: assert response.body is not None, ( 'Expected a value to be returned for %s, ' 'but recieved None - only void procedures can ' 'return None.' % function.endpoint ) response_kwargs['success'] = response.body response.status = status response.body = response_cls(**response_kwargs) raise gen.Return(response)
def wrapped(*args, **kwargs): try: # Force local state - switch to new stack chain current_state = _state.contexts _state.contexts = contexts # Current exception exc = (None, None, None) top = None # Apply stack contexts last_ctx = 0 stack = contexts[0] # Apply state for n in stack: try: n.enter() last_ctx += 1 except: # Exception happened. Record exception info and store top-most handler exc = sys.exc_info() top = n.old_contexts[1] # Execute callback if no exception happened while restoring state if top is None: try: fn(*args, **kwargs) except: exc = sys.exc_info() top = contexts[1] # If there was exception, try to handle it by going through the exception chain if top is not None: exc = _handle_exception(top, exc) else: # Otherwise take shorter path and run stack contexts in reverse order while last_ctx > 0: last_ctx -= 1 c = stack[last_ctx] try: c.exit(*exc) except: exc = sys.exc_info() top = c.old_contexts[1] break else: top = None # If if exception happened while unrolling, take longer exception handler path if top is not None: exc = _handle_exception(top, exc) # If exception was not handled, raise it if exc != (None, None, None): raise_exc_info(exc) finally: _state.contexts = current_state
def result(self, timeout=None): self._clear_tb_log() if self._result is not None: return self._result if self._exc_info is not None: raise_exc_info(self._exc_info) self._check_done() return self._result
def raise_future_exception(future): exception = future.exception() if isinstance(future, TracebackFuture): raise_exc_info(future.exc_info()) elif hasattr(future, 'exception_info') and future.exception_info()[1] is not None: raise_exc_info((type(exception),) + future.exception_info()) else: raise exception
def result(self, timeout=None): if self._result is not None: return self._result if self._exc_info is not None: raise_exc_info(self._exc_info) elif self._exception is not None: raise self._exception self._check_done() return self._result
def begin(self): connection = yield self.Connection() try: yield connection.begin() except: exc_info = sys.exc_info() connection.close() raise_exc_info(exc_info) transaction = Transaction(self, connection) raise Return(transaction)
def begin(self): connection = yield self.Connection() try: yield connection.begin() except: exc_info = sys.exc_info() connection.close() raise_exc_info(exc_info) transaction = Transaction(self, connection) raise gen.Return(transaction)
def result(self, timeout=None): """If the operation succeeded, return its result. If it failed, re-raise its exception. """ self._clear_tb_log() if self._result is not None: return self._result if self._exc_info is not None: raise_exc_info(self._exc_info) self._check_done() return self._result
def wrapped(*args, **kwargs): ret = None try: current_state = _state.contexts cap_contexts[0] = contexts = _remove_deactivated(cap_contexts[0]) _state.contexts = contexts exc = (None, None, None) top = None last_ctx = 0 stack = contexts[0] for n in stack: try: n.enter() last_ctx += 1 except: exc = sys.exc_info() top = n.old_contexts[1] if top is None: try: ret = fn(*args, **kwargs) except: exc = sys.exc_info() top = contexts[1] if top is not None: exc = _handle_exception(top, exc) else: while last_ctx > 0: last_ctx -= 1 c = stack[last_ctx] try: c.exit(*exc) except: exc = sys.exc_info() top = c.old_contexts[1] break else: top = None if top is not None: exc = _handle_exception(top, exc) if exc != (None, None, None): raise_exc_info(exc) finally: _state.contexts = current_state return ret
def _stack_context_handle_exception(self, type, value, traceback): try: # For historical reasons _handle_request_exception only takes # the exception value instead of the full triple, # so re-raise the exception to ensure that it's in # sys.exc_info() raise_exc_info((type, value, traceback)) except Exception as e: print e.message return None return True
def _(*args, **kwargs): yield self.transaction.begin() try: kwargs[self.args_name] = self.transaction result = yield func(*args, **kwargs) except: exc_info = sys.exc_info() yield self.transaction.rollback() raise_exc_info(exc_info) else: yield self.transaction.commit() raise gen.Return(result)
def rollback(self): self._ensure_conn() try: yield self._connection.rollback() except: exc_info = sys.exc_info() self._connection.close(True) raise_exc_info(exc_info) else: self._connection.close() finally: self._connection = None
def __exit__(self, exc_type, exc_val, exc_tb): if self.connection is None: return if exc_type: self.rollback() else: try: self.commit() except: exc_info = sys.exc_info() self.rollback() raise_exc_info(exc_info)
def executemany(self, query, params=None, cursor_cls=None): with (yield self.Connection()) as connection: cursor = connection.cursor(cursor_cls) try: yield cursor.executemany(query, params) if not connection._connection.autocommit_mode: yield connection.commit() except: exc_info = sys.exc_info() if not connection._connection.autocommit_mode: yield connection.rollback() raise_exc_info(exc_info) finally: yield cursor.close() raise Return(cursor)
def result(self, timeout=None): """If the operation succeeded, return its result. If it failed, re-raise its exception. This method takes a ``timeout`` argument for compatibility with `concurrent.futures.Future` but it is an error to call it before the `Future` is done, so the ``timeout`` is never used. """ self._clear_tb_log() if self._result is not None: return self._result if self._exc_info is not None: raise_exc_info(self._exc_info) self._check_done() return self._result
def executemany(self, query, params=None, cursor_cls=None): with (yield self.Connection()) as connection: cursor = connection.cursor(cursor_cls) try: yield cursor.executemany(query, params) if not connection._connection.autocommit_mode: yield connection.commit() except: exc_info = sys.exc_info() if not connection._connection.autocommit_mode: yield connection.rollback() raise_exc_info(exc_info) finally: yield cursor.close() raise gen.Return(cursor)
def result(self, timeout=None): """If the operation succeeded, return its result. If it failed, re-raise its exception. """ self._log_traceback = False if self._tb_logger is not None: self._tb_logger.clear() self._tb_logger = None if self._result is not None: return self._result if self._exc_info is not None: raise_exc_info(self._exc_info) elif self._exception is not None: raise self._exception self._check_done() return self._result
def _call_function(self, handler_class, raise_exceptions=True): # Create application with the only route — handler_class application = application_mock([('', handler_class)], self._config)(**{ 'app': 'frontik.testing', }) for (key, value) in iteritems(self.application_kwargs): setattr(application, key, value) # Mock methods def fetch(request, callback, **kwargs): IOLoop.instance().add_callback( partial(self._fetch_mock, request, callback, **kwargs)) application.curl_http_client.fetch = fetch # raise_exceptions kwarg is deprecated if raise_exceptions: exceptions = [] old_handle_request_exception = handler_class._handle_request_exception def handle_request_exception(handler, e): old_handle_request_exception(handler, e) exceptions.append(sys.exc_info()) handler_class._handle_request_exception = handle_request_exception old_flush = handler_class.flush def flush(handler, *args, **kwargs): self._response_text = b''.join(handler._write_buffer) old_flush(handler, *args, **kwargs) IOLoop.instance().add_callback(IOLoop.instance().stop) handler_class.flush = flush self._handler = application(self._request) IOLoop.instance().start() if raise_exceptions and exceptions: raise_exc_info(exceptions[0]) return TestResult(self._config, self._request, self._handler, self._response_text)
def test_two_arg_exception(self): # This test would fail on python 3 if raise_exc_info were simply # a three-argument raise statement, because TwoArgException # doesn't have a "copy constructor" class TwoArgException(Exception): def __init__(self, a, b): super(TwoArgException, self).__init__() self.a, self.b = a, b try: raise TwoArgException(1, 2) except TwoArgException: exc_info = sys.exc_info() try: raise_exc_info(exc_info) self.fail("didn't get expected exception") except TwoArgException as e: self.assertIs(e, exc_info[1])
def get_result(self): result_list = [] exc_info = None for f in self.children: try: result_list.append(f.get_result()) except Exception as e: if exc_info is None: exc_info = sys.exc_info() else: if not isinstance(e, self.quiet_exceptions): app_log.error("Multiple exceptions in yield list", exc_info=True) if exc_info is not None: raise_exc_info(exc_info) if self.keys is not None: return dict(zip(self.keys, result_list)) else: return list(result_list)
def _call_function(self, handler_class, raise_exceptions=True): # Create application with the only route — handler_class application = application_mock([('', handler_class)], self._config)(**{ 'app': 'frontik.testing', 'app_root_url': '/', }) # Mock methods def fetch(request, callback, **kwargs): IOLoop.instance().add_callback(partial(self._fetch_mock, request, callback, **kwargs)) application.curl_http_client.fetch = fetch # raise_exceptions kwarg is deprecated if raise_exceptions: exceptions = [] old_handle_request_exception = handler_class._handle_request_exception def handle_request_exception(handler, e): old_handle_request_exception(handler, e) exceptions.append(sys.exc_info()) handler_class._handle_request_exception = handle_request_exception old_flush = handler_class.flush def flush(handler, *args, **kwargs): self._response_text = b''.join(handler._write_buffer) old_flush(handler, *args, **kwargs) IOLoop.instance().add_callback(IOLoop.instance().stop) handler_class.flush = flush self._handler = application(self._request) IOLoop.instance().start() if raise_exceptions and exceptions: raise_exc_info(exceptions[0]) return TestResult(self._config, self._request, self._handler, self._response_text)
def __rethrow(self): if self.__failure is not None: failure = self.__failure self.__failure = None raise_exc_info(failure)
def result(self, timeout=None): if self.__exc_info is not None: raise_exc_info(self.__exc_info) else: return super(TracebackFuture, self).result(timeout=timeout)
def _stack_context_handle_exception(self, type, value, traceback): try: raise_exc_info((type, value, traceback)) except Exception: self._handle_request_exception(value) return True
def wrapped(*args, **kwargs): ret = None try: # Capture old state current_state = _state.contexts # Remove deactivated items cap_contexts[0] = contexts = _remove_deactivated(cap_contexts[0]) # Force new state _state.contexts = contexts # Current exception exc = (None, None, None) top = None # Apply stack contexts last_ctx = 0 stack = contexts[0] # Apply state 对每个栈序列进行调用,恢复到在add_callback时候的状态 for n in stack: try: n.enter() last_ctx += 1 except: # Exception happened. Record exception info and store top-most handler exc = sys.exc_info() top = n.old_contexts[1] # 调用栈的上一帧异常处理 # Execute callback if no exception happened while restoring state if top is None: try: ret = fn(*args, **kwargs) except: exc = sys.exc_info() top = contexts[1] # 回调有异常,调用与自己栈相关的上下文异常处理,或者一直沿着栈往上传递这个异常 # If there was exception, try to handle it by going through the exception chain if top is not None: exc = _handle_exception(top, exc) else: # Otherwise take shorter path and run stack contexts in reverse order while last_ctx > 0: last_ctx -= 1 c = stack[last_ctx] try: c.exit(*exc) except: exc = sys.exc_info() top = c.old_contexts[1] break else: top = None # If if exception happened while unrolling, take longer exception handler path if top is not None: exc = _handle_exception(top, exc) # If exception was not handled, raise it if exc != (None, None, None): raise_exc_info(exc) finally: _state.contexts = current_state return ret
def wrapped(*args, **kwargs): ret = None try: # Capture old state current_state = _state.contexts # Remove deactivated items cap_contexts[0] = contexts = _remove_deactivated(cap_contexts[0]) # Force new state # 强制新的状态 _state.contexts = contexts # Current exception exc = (None, None, None) top = None # Apply stack contexts # 应用堆栈上下文 last_ctx = 0 stack = contexts[0] # Apply state # 应用状态 for n in stack: try: n.enter() last_ctx += 1 except: # Exception happened. Record exception info and store top-most handler exc = sys.exc_info() top = n.old_contexts[1] # Execute callback if no exception happened while restoring state if top is None: try: # 直接跳转到netutil.py中的: # def accept_handler(fd, events): # while True: # try: # connection, address = sock.accept() # except socket.error as e: # 此时的fn对象就是【accept_handler】 # 这个函数就是装饰器中要装饰的函数 ret = fn(*args, **kwargs) except: exc = sys.exc_info() top = contexts[1] # If there was exception, try to handle it by going through the exception chain if top is not None: exc = _handle_exception(top, exc) else: # Otherwise take shorter path and run stack contexts in reverse order while last_ctx > 0: last_ctx -= 1 c = stack[last_ctx] try: c.exit(*exc) except: exc = sys.exc_info() top = c.old_contexts[1] break else: top = None # If if exception happened while unrolling, take longer exception handler path if top is not None: exc = _handle_exception(top, exc) # If exception was not handled, raise it if exc != (None, None, None): raise_exc_info(exc) finally: _state.contexts = current_state return ret
def wrapped(*args, **kwargs): ret = None try: # Capture old state current_state = _state.contexts # Remove deactivated items cap_contexts[0] = contexts = _remove_deactivated(cap_contexts[0]) # Force new state _state.contexts = contexts # Current exception exc = (None, None, None) top = None # Apply stack contexts last_ctx = 0 stack = contexts[0] f = open("/home/guangtong/pgt_test/aaa.txt", "a") f.write("oooooooooooooooooooooooo \n") f.close() # Apply state for n in stack: f = open("/home/guangtong/pgt_test/aaa.txt", "a") f.write("oooooo111 %s\n" % str(dir(n))) f.write("oooooo111 %s\n" % str(type(n))) f.close() try: n.enter() last_ctx += 1 except: # Exception happened. Record exception info and store top-most handler exc = sys.exc_info() top = n.old_contexts[1] # Execute callback if no exception happened while restoring state if top is None: try: f = open("/home/guangtong/pgt_test/aaa.txt", "a") f.write("oooooo333 >>> %s\n" % fn.__name__) f.close() ret = fn(*args, **kwargs) f = open("/home/guangtong/pgt_test/aaa.txt", "a") f.write("oooooo333 %s\n" % fn.__name__) f.close() except Exception, e: f = open("/home/guangtong/pgt_test/aaa.txt", "a") f.write("oooooo444 %s\n" % str(e)) f.close() exc = sys.exc_info() top = contexts[1] # If there was exception, try to handle it by going through the exception chain if top is not None: exc = _handle_exception(top, exc) else: # Otherwise take shorter path and run stack contexts in reverse order while last_ctx > 0: last_ctx -= 1 c = stack[last_ctx] try: c.exit(*exc) except: exc = sys.exc_info() top = c.old_contexts[1] break else: top = None # If if exception happened while unrolling, take longer exception handler path if top is not None: exc = _handle_exception(top, exc) # If exception was not handled, raise it if exc != (None, None, None): raise_exc_info(exc)
def __rethrow(self): # pragma: no cover if self.__failure is not None: failure = self.__failure self.__failure = None raise_exc_info(failure)