MCPcopy
hub / github.com/tornadoweb/tornado / wrapper

Function wrapper

tornado/gen.py:211–271  ·  view source on GitHub ↗
(*args, **kwargs)

Source from the content-addressed store, hash-verified

209
210 @functools.wraps(func)
211 def wrapper(*args, **kwargs):
212 # type: (*Any, **Any) -> Future[_T]
213 # This function is type-annotated with a comment to work around
214 # https://bitbucket.org/pypy/pypy/issues/2868/segfault-with-args-type-annotation-in
215 future = _create_future()
216 if contextvars is not None:
217 ctx_run = contextvars.copy_context().run # type: Callable
218 else:
219 ctx_run = _fake_ctx_run
220 try:
221 result = ctx_run(func, *args, **kwargs)
222 except (Return, StopIteration) as e:
223 result = _value_from_stopiteration(e)
224 except Exception:
225 future_set_exc_info(future, sys.exc_info())
226 try:
227 return future
228 finally:
229 # Avoid circular references
230 future = None # type: ignore
231 else:
232 if isinstance(result, Generator):
233 # Inline the first iteration of Runner.run. This lets us
234 # avoid the cost of creating a Runner when the coroutine
235 # never actually yields, which in turn allows us to
236 # use "optional" coroutines in critical path code without
237 # performance penalty for the synchronous case.
238 try:
239 yielded = ctx_run(next, result)
240 except (StopIteration, Return) as e:
241 future_set_result_unless_cancelled(
242 future, _value_from_stopiteration(e)
243 )
244 except Exception:
245 future_set_exc_info(future, sys.exc_info())
246 else:
247 # Provide strong references to Runner objects as long
248 # as their result future objects also have strong
249 # references (typically from the parent coroutine's
250 # Runner). This keeps the coroutine's Runner alive.
251 # We do this by exploiting the public API
252 # add_done_callback() instead of putting a private
253 # attribute on the Future.
254 # (GitHub issues #1769, #2229).
255 runner = Runner(ctx_run, result, future, yielded)
256 future.add_done_callback(lambda _: runner)
257 yielded = None
258 try:
259 return future
260 finally:
261 # Subtle memory optimization: if next() raised an exception,
262 # the future's exc_info contains a traceback which
263 # includes this stack frame. This creates a cycle,
264 # which will be collected at the next full GC but has
265 # been shown to greatly increase memory usage of
266 # benchmarks (relative to the refcount-based scheme
267 # used in the absence of cycles). We can avoid the
268 # cycle by clearing the local variable after we return it.

Callers 2

write_messageMethod · 0.70
install_hookMethod · 0.50

Calls 5

future_set_exc_infoFunction · 0.90
_create_futureFunction · 0.85
RunnerClass · 0.85

Tested by 1

install_hookMethod · 0.40