{
    "file_diffs": [
        {
            "old_file_content": "#!/usr/bin/env python\n#\n# Copyright 2010 Facebook\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may\n# not use this file except in compliance with the License. You may obtain\n# a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n# License for the specific language governing permissions and limitations\n# under the License.\n\n\"\"\"`StackContext` allows applications to maintain threadlocal-like state\nthat follows execution as it moves to other execution contexts.\n\nThe motivating examples are to eliminate the need for explicit\n``async_callback`` wrappers (as in `tornado.web.RequestHandler`), and to\nallow some additional context to be kept for logging.\n\nThis is slightly magic, but it's an extension of the idea that an\nexception handler is a kind of stack-local state and when that stack\nis suspended and resumed in a new context that state needs to be\npreserved.  `StackContext` shifts the burden of restoring that state\nfrom each call site (e.g.  wrapping each `.AsyncHTTPClient` callback\nin ``async_callback``) to the mechanisms that transfer control from\none context to another (e.g. `.AsyncHTTPClient` itself, `.IOLoop`,\nthread pools, etc).\n\nExample usage::\n\n    @contextlib.contextmanager\n    def die_on_error():\n        try:\n            yield\n        except Exception:\n            logging.error(\"exception in asynchronous operation\",exc_info=True)\n            sys.exit(1)\n\n    with StackContext(die_on_error):\n        # Any exception thrown here *or in callback and its desendents*\n        # will cause the process to exit instead of spinning endlessly\n        # in the ioloop.\n        http_client.fetch(url, callback)\n    ioloop.start()\n\nMost applications shouln't have to work with `StackContext` directly.\nHere are a few rules of thumb for when it's necessary:\n\n* If you're writing an asynchronous library that doesn't rely on a\n  stack_context-aware library like `tornado.ioloop` or `tornado.iostream`\n  (for example, if you're writing a thread pool), use\n  `.stack_context.wrap()` before any asynchronous operations to capture the\n  stack context from where the operation was started.\n\n* If you're writing an asynchronous library that has some shared\n  resources (such as a connection pool), create those shared resources\n  within a ``with stack_context.NullContext():`` block.  This will prevent\n  ``StackContexts`` from leaking from one request to another.\n\n* If you want to write something like an exception handler that will\n  persist across asynchronous calls, create a new `StackContext` (or\n  `ExceptionStackContext`), and make your asynchronous calls in a ``with``\n  block that references your `StackContext`.\n\"\"\"\n\nfrom __future__ import absolute_import, division, print_function, with_statement\n\nimport sys\nimport threading\nimport operator\n\nfrom tornado.util import raise_exc_info\n\n\nclass StackContextInconsistentError(Exception):\n    pass\n\n\nclass _State(threading.local):\n    def __init__(self):\n        self.contexts = (tuple(), None)\n_state = _State()\n\n\nclass StackContext(object):\n    \"\"\"Establishes the given context as a StackContext that will be transferred.\n\n    Note that the parameter is a callable that returns a context\n    manager, not the context itself.  That is, where for a\n    non-transferable context manager you would say::\n\n      with my_context():\n\n    StackContext takes the function itself rather than its result::\n\n      with StackContext(my_context):\n\n    The result of ``with StackContext() as cb:`` is a deactivation\n    callback.  Run this callback when the StackContext is no longer\n    needed to ensure that it is not propagated any further (note that\n    deactivating a context does not affect any instances of that\n    context that are currently pending).  This is an advanced feature\n    and not necessary in most applications.\n    \"\"\"\n    def __init__(self, context_factory):\n        self.context_factory = context_factory\n        self.contexts = []\n        self.active = True\n\n    def _deactivate(self):\n        self.active = False\n\n    # StackContext protocol\n    def enter(self):\n        context = self.context_factory()\n        self.contexts.append(context)\n        context.__enter__()\n\n    def exit(self, type, value, traceback):\n        context = self.contexts.pop()\n        context.__exit__(type, value, traceback)\n\n    # Note that some of this code is duplicated in ExceptionStackContext\n    # below.  ExceptionStackContext is more common and doesn't need\n    # the full generality of this class.\n    def __enter__(self):\n        self.old_contexts = _state.contexts\n        self.new_contexts = (self.old_contexts[0] + (self,), self)\n        _state.contexts = self.new_contexts\n\n        try:\n            self.enter()\n        except:\n            _state.contexts = self.old_contexts\n            raise\n\n        return self._deactivate\n\n    def __exit__(self, type, value, traceback):\n        try:\n            self.exit(type, value, traceback)\n        finally:\n            final_contexts = _state.contexts\n            _state.contexts = self.old_contexts\n\n            # Generator coroutines and with-statements with non-local\n            # effects interact badly.  Check here for signs of\n            # the stack getting out of sync.\n            # Note that this check comes after restoring _state.context\n            # so that if it fails things are left in a (relatively)\n            # consistent state.\n            if final_contexts is not self.new_contexts:\n                raise StackContextInconsistentError(\n                    'stack_context inconsistency (may be caused by yield '\n                    'within a \"with StackContext\" block)')\n\n            # Break up a reference to itself to allow for faster GC on CPython.\n            self.new_contexts = None\n\n\nclass ExceptionStackContext(object):\n    \"\"\"Specialization of StackContext for exception handling.\n\n    The supplied ``exception_handler`` function will be called in the\n    event of an uncaught exception in this context.  The semantics are\n    similar to a try/finally clause, and intended use cases are to log\n    an error, close a socket, or similar cleanup actions.  The\n    ``exc_info`` triple ``(type, value, traceback)`` will be passed to the\n    exception_handler function.\n\n    If the exception handler returns true, the exception will be\n    consumed and will not be propagated to other exception handlers.\n    \"\"\"\n    def __init__(self, exception_handler):\n        self.exception_handler = exception_handler\n        self.active = True\n\n    def _deactivate(self):\n        self.active = False\n\n    def exit(self, type, value, traceback):\n        if type is not None:\n            return self.exception_handler(type, value, traceback)\n\n    def __enter__(self):\n        self.old_contexts = _state.contexts\n        self.new_contexts = (self.old_contexts[0], self)\n        _state.contexts = self.new_contexts\n\n        return self._deactivate\n\n    def __exit__(self, type, value, traceback):\n        try:\n            if type is not None:\n                return self.exception_handler(type, value, traceback)\n        finally:\n            final_contexts = _state.contexts\n            _state.contexts = self.old_contexts\n\n            if final_contexts is not self.new_contexts:\n                raise StackContextInconsistentError(\n                    'stack_context inconsistency (may be caused by yield '\n                    'within a \"with StackContext\" block)')\n\n            # Break up a reference to itself to allow for faster GC on CPython.\n            self.new_contexts = None\n\n\nclass NullContext(object):\n    \"\"\"Resets the `StackContext`.\n\n    Useful when creating a shared resource on demand (e.g. an\n    `.AsyncHTTPClient`) where the stack that caused the creating is\n    not relevant to future operations.\n    \"\"\"\n    def __enter__(self):\n        self.old_contexts = _state.contexts\n        _state.contexts = (tuple(), None)\n\n    def __exit__(self, type, value, traceback):\n        _state.contexts = self.old_contexts\n\n\ndef _remove_deactivated(contexts):\n    \"\"\"Remove deactivated handlers from the chain\"\"\"\n    # Clean ctx handlers\n    stack_contexts = tuple([h for h in contexts[0] if h.active])\n\n    # Find new head\n    head = contexts[1]\n    while head is not None and not head.active:\n        head = head.old_contexts[1]\n\n    # Process chain\n    ctx = head\n    while ctx is not None:\n        parent = ctx.old_contexts[1]\n\n        while parent is not None and not parent.active:\n            parent = parent.old_contexts[1]\n\n            ctx.old_contexts = parent.old_contexts\n\n        ctx = parent\n\n    return (stack_contexts, head)\n\n\ndef wrap(fn):\n    \"\"\"Returns a callable object that will restore the current `StackContext`\n    when executed.\n\n    Use this whenever saving a callback to be executed later in a\n    different execution context (either in a different thread or\n    asynchronously in the same thread).\n    \"\"\"\n    # Check if function is already wrapped\n    if fn is None or hasattr(fn, '_wrapped'):\n        return fn\n\n    # Capture current stack head\n    # TODO: Any other better way to store contexts and update them in wrapped function?\n    cap_contexts = [_state.contexts]\n\n    def wrapped(*args, **kwargs):\n        try:\n            # Capture old state\n            current_state = _state.contexts\n\n            # Remove deactivated items\n            cap_contexts[0] = contexts = _remove_deactivated(cap_contexts[0])\n\n            # Force new state\n            _state.contexts = contexts\n\n            # Current exception\n            exc = (None, None, None)\n            top = None\n\n            # Apply stack contexts\n            last_ctx = 0\n            stack = contexts[0]\n\n            # Apply state\n            for n in stack:\n                try:\n                    n.enter()\n                    last_ctx += 1\n                except:\n                    # Exception happened. Record exception info and store top-most handler\n                    exc = sys.exc_info()\n                    top = n.old_contexts[1]\n\n            # Execute callback if no exception happened while restoring state\n            if top is None:\n                try:\n                    fn(*args, **kwargs)\n                except:\n                    exc = sys.exc_info()\n                    top = contexts[1]\n\n            # If there was exception, try to handle it by going through the exception chain\n            if top is not None:\n                exc = _handle_exception(top, exc)\n            else:\n                # Otherwise take shorter path and run stack contexts in reverse order\n                while last_ctx > 0:\n                    last_ctx -= 1\n                    c = stack[last_ctx]\n\n                    try:\n                        c.exit(*exc)\n                    except:\n                        exc = sys.exc_info()\n                        top = c.old_contexts[1]\n                        break\n                else:\n                    top = None\n\n                # If if exception happened while unrolling, take longer exception handler path\n                if top is not None:\n                    exc = _handle_exception(top, exc)\n\n            # If exception was not handled, raise it\n            if exc != (None, None, None):\n                raise_exc_info(exc)\n        finally:\n            _state.contexts = current_state\n\n    wrapped._wrapped = True\n    return wrapped\n\n\ndef _handle_exception(tail, exc):\n    while tail is not None:\n        try:\n            if tail.exit(*exc):\n                exc = (None, None, None)\n        except:\n            exc = sys.exc_info()\n\n        tail = tail.old_contexts[1]\n\n    return exc\n\n\ndef run_with_stack_context(context, func):\n    \"\"\"Run a coroutine ``func`` in the given `StackContext`.\n\n    It is not safe to have a ``yield`` statement within a ``with StackContext``\n    block, so it is difficult to use stack context with `.gen.coroutine`.\n    This helper function runs the function in the correct context while\n    keeping the ``yield`` and ``with`` statements syntactically separate.\n\n    Example::\n\n        @gen.coroutine\n        def incorrect():\n            with StackContext(ctx):\n                # ERROR: this will raise StackContextInconsistentError\n                yield other_coroutine()\n\n        @gen.coroutine\n        def correct():\n            yield run_with_stack_context(StackContext(ctx), other_coroutine)\n    \"\"\"\n    with context:\n        return func()\n",
            "new_file_content": "#!/usr/bin/env python\n#\n# Copyright 2010 Facebook\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may\n# not use this file except in compliance with the License. You may obtain\n# a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n# License for the specific language governing permissions and limitations\n# under the License.\n\n\"\"\"`StackContext` allows applications to maintain threadlocal-like state\nthat follows execution as it moves to other execution contexts.\n\nThe motivating examples are to eliminate the need for explicit\n``async_callback`` wrappers (as in `tornado.web.RequestHandler`), and to\nallow some additional context to be kept for logging.\n\nThis is slightly magic, but it's an extension of the idea that an\nexception handler is a kind of stack-local state and when that stack\nis suspended and resumed in a new context that state needs to be\npreserved.  `StackContext` shifts the burden of restoring that state\nfrom each call site (e.g.  wrapping each `.AsyncHTTPClient` callback\nin ``async_callback``) to the mechanisms that transfer control from\none context to another (e.g. `.AsyncHTTPClient` itself, `.IOLoop`,\nthread pools, etc).\n\nExample usage::\n\n    @contextlib.contextmanager\n    def die_on_error():\n        try:\n            yield\n        except Exception:\n            logging.error(\"exception in asynchronous operation\",exc_info=True)\n            sys.exit(1)\n\n    with StackContext(die_on_error):\n        # Any exception thrown here *or in callback and its desendents*\n        # will cause the process to exit instead of spinning endlessly\n        # in the ioloop.\n        http_client.fetch(url, callback)\n    ioloop.start()\n\nMost applications shouln't have to work with `StackContext` directly.\nHere are a few rules of thumb for when it's necessary:\n\n* If you're writing an asynchronous library that doesn't rely on a\n  stack_context-aware library like `tornado.ioloop` or `tornado.iostream`\n  (for example, if you're writing a thread pool), use\n  `.stack_context.wrap()` before any asynchronous operations to capture the\n  stack context from where the operation was started.\n\n* If you're writing an asynchronous library that has some shared\n  resources (such as a connection pool), create those shared resources\n  within a ``with stack_context.NullContext():`` block.  This will prevent\n  ``StackContexts`` from leaking from one request to another.\n\n* If you want to write something like an exception handler that will\n  persist across asynchronous calls, create a new `StackContext` (or\n  `ExceptionStackContext`), and make your asynchronous calls in a ``with``\n  block that references your `StackContext`.\n\"\"\"\n\nfrom __future__ import absolute_import, division, print_function, with_statement\n\nimport sys\nimport threading\nimport operator\n\nfrom tornado.util import raise_exc_info\n\n\nclass StackContextInconsistentError(Exception):\n    pass\n\n\nclass _State(threading.local):\n    def __init__(self):\n        self.contexts = (tuple(), None)\n_state = _State()\n\n\nclass StackContext(object):\n    \"\"\"Establishes the given context as a StackContext that will be transferred.\n\n    Note that the parameter is a callable that returns a context\n    manager, not the context itself.  That is, where for a\n    non-transferable context manager you would say::\n\n      with my_context():\n\n    StackContext takes the function itself rather than its result::\n\n      with StackContext(my_context):\n\n    The result of ``with StackContext() as cb:`` is a deactivation\n    callback.  Run this callback when the StackContext is no longer\n    needed to ensure that it is not propagated any further (note that\n    deactivating a context does not affect any instances of that\n    context that are currently pending).  This is an advanced feature\n    and not necessary in most applications.\n    \"\"\"\n    def __init__(self, context_factory):\n        self.context_factory = context_factory\n        self.contexts = []\n        self.active = True\n\n    def _deactivate(self):\n        self.active = False\n\n    # StackContext protocol\n    def enter(self):\n        context = self.context_factory()\n        self.contexts.append(context)\n        context.__enter__()\n\n    def exit(self, type, value, traceback):\n        context = self.contexts.pop()\n        context.__exit__(type, value, traceback)\n\n    # Note that some of this code is duplicated in ExceptionStackContext\n    # below.  ExceptionStackContext is more common and doesn't need\n    # the full generality of this class.\n    def __enter__(self):\n        self.old_contexts = _state.contexts\n        self.new_contexts = (self.old_contexts[0] + (self,), self)\n        _state.contexts = self.new_contexts\n\n        try:\n            self.enter()\n        except:\n            _state.contexts = self.old_contexts\n            raise\n\n        return self._deactivate\n\n    def __exit__(self, type, value, traceback):\n        try:\n            self.exit(type, value, traceback)\n        finally:\n            final_contexts = _state.contexts\n            _state.contexts = self.old_contexts\n\n            # Generator coroutines and with-statements with non-local\n            # effects interact badly.  Check here for signs of\n            # the stack getting out of sync.\n            # Note that this check comes after restoring _state.context\n            # so that if it fails things are left in a (relatively)\n            # consistent state.\n            if final_contexts is not self.new_contexts:\n                raise StackContextInconsistentError(\n                    'stack_context inconsistency (may be caused by yield '\n                    'within a \"with StackContext\" block)')\n\n            # Break up a reference to itself to allow for faster GC on CPython.\n            self.new_contexts = None\n\n\nclass ExceptionStackContext(object):\n    \"\"\"Specialization of StackContext for exception handling.\n\n    The supplied ``exception_handler`` function will be called in the\n    event of an uncaught exception in this context.  The semantics are\n    similar to a try/finally clause, and intended use cases are to log\n    an error, close a socket, or similar cleanup actions.  The\n    ``exc_info`` triple ``(type, value, traceback)`` will be passed to the\n    exception_handler function.\n\n    If the exception handler returns true, the exception will be\n    consumed and will not be propagated to other exception handlers.\n    \"\"\"\n    def __init__(self, exception_handler):\n        self.exception_handler = exception_handler\n        self.active = True\n\n    def _deactivate(self):\n        self.active = False\n\n    def exit(self, type, value, traceback):\n        if type is not None:\n            return self.exception_handler(type, value, traceback)\n\n    def __enter__(self):\n        self.old_contexts = _state.contexts\n        self.new_contexts = (self.old_contexts[0], self)\n        _state.contexts = self.new_contexts\n\n        return self._deactivate\n\n    def __exit__(self, type, value, traceback):\n        try:\n            if type is not None:\n                return self.exception_handler(type, value, traceback)\n        finally:\n            final_contexts = _state.contexts\n            _state.contexts = self.old_contexts\n\n            if final_contexts is not self.new_contexts:\n                raise StackContextInconsistentError(\n                    'stack_context inconsistency (may be caused by yield '\n                    'within a \"with StackContext\" block)')\n\n            # Break up a reference to itself to allow for faster GC on CPython.\n            self.new_contexts = None\n\n\nclass NullContext(object):\n    \"\"\"Resets the `StackContext`.\n\n    Useful when creating a shared resource on demand (e.g. an\n    `.AsyncHTTPClient`) where the stack that caused the creating is\n    not relevant to future operations.\n    \"\"\"\n    def __enter__(self):\n        self.old_contexts = _state.contexts\n        _state.contexts = (tuple(), None)\n\n    def __exit__(self, type, value, traceback):\n        _state.contexts = self.old_contexts\n\n\ndef _remove_deactivated(contexts):\n    \"\"\"Remove deactivated handlers from the chain\"\"\"\n    # Clean ctx handlers\n    stack_contexts = tuple([h for h in contexts[0] if h.active])\n\n    # Find new head\n    head = contexts[1]\n    while head is not None and not head.active:\n        head = head.old_contexts[1]\n\n    # Process chain\n    ctx = head\n    while ctx is not None:\n        parent = ctx.old_contexts[1]\n\n        while parent is not None:\n            if parent.active:\n                break\n            ctx.old_contexts = parent.old_contexts\n            parent = parent.old_contexts[1]\n\n        ctx = parent\n\n    return (stack_contexts, head)\n\n\ndef wrap(fn):\n    \"\"\"Returns a callable object that will restore the current `StackContext`\n    when executed.\n\n    Use this whenever saving a callback to be executed later in a\n    different execution context (either in a different thread or\n    asynchronously in the same thread).\n    \"\"\"\n    # Check if function is already wrapped\n    if fn is None or hasattr(fn, '_wrapped'):\n        return fn\n\n    # Capture current stack head\n    # TODO: Any other better way to store contexts and update them in wrapped function?\n    cap_contexts = [_state.contexts]\n\n    def wrapped(*args, **kwargs):\n        ret = None\n        try:\n            # Capture old state\n            current_state = _state.contexts\n\n            # Remove deactivated items\n            cap_contexts[0] = contexts = _remove_deactivated(cap_contexts[0])\n\n            # Force new state\n            _state.contexts = contexts\n\n            # Current exception\n            exc = (None, None, None)\n            top = None\n\n            # Apply stack contexts\n            last_ctx = 0\n            stack = contexts[0]\n\n            # Apply state\n            for n in stack:\n                try:\n                    n.enter()\n                    last_ctx += 1\n                except:\n                    # Exception happened. Record exception info and store top-most handler\n                    exc = sys.exc_info()\n                    top = n.old_contexts[1]\n\n            # Execute callback if no exception happened while restoring state\n            if top is None:\n                try:\n                    ret = fn(*args, **kwargs)\n                except:\n                    exc = sys.exc_info()\n                    top = contexts[1]\n\n            # If there was exception, try to handle it by going through the exception chain\n            if top is not None:\n                exc = _handle_exception(top, exc)\n            else:\n                # Otherwise take shorter path and run stack contexts in reverse order\n                while last_ctx > 0:\n                    last_ctx -= 1\n                    c = stack[last_ctx]\n\n                    try:\n                        c.exit(*exc)\n                    except:\n                        exc = sys.exc_info()\n                        top = c.old_contexts[1]\n                        break\n                else:\n                    top = None\n\n                # If if exception happened while unrolling, take longer exception handler path\n                if top is not None:\n                    exc = _handle_exception(top, exc)\n\n            # If exception was not handled, raise it\n            if exc != (None, None, None):\n                raise_exc_info(exc)\n        finally:\n            _state.contexts = current_state\n        return ret\n\n    wrapped._wrapped = True\n    return wrapped\n\n\ndef _handle_exception(tail, exc):\n    while tail is not None:\n        try:\n            if tail.exit(*exc):\n                exc = (None, None, None)\n        except:\n            exc = sys.exc_info()\n\n        tail = tail.old_contexts[1]\n\n    return exc\n\n\ndef run_with_stack_context(context, func):\n    \"\"\"Run a coroutine ``func`` in the given `StackContext`.\n\n    It is not safe to have a ``yield`` statement within a ``with StackContext``\n    block, so it is difficult to use stack context with `.gen.coroutine`.\n    This helper function runs the function in the correct context while\n    keeping the ``yield`` and ``with`` statements syntactically separate.\n\n    Example::\n\n        @gen.coroutine\n        def incorrect():\n            with StackContext(ctx):\n                # ERROR: this will raise StackContextInconsistentError\n                yield other_coroutine()\n\n        @gen.coroutine\n        def correct():\n            yield run_with_stack_context(StackContext(ctx), other_coroutine)\n    \"\"\"\n    with context:\n        return func()\n",
            "header": {
                "file": {
                    "path": "tornado/stack_context.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "7e44beda",
                "new_commit_hash": "9ad31476",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/tornado/stack_context.py"
            },
            "plus_file": {
                "path": "b/tornado/stack_context.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 240,
                            "length": 10
                        },
                        "new_range": {
                            "start": 240,
                            "length": 11
                        },
                        "section": "def _remove_deactivated(contexts):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "    while ctx is not None:",
                                "type": "context"
                            },
                            {
                                "content": "        parent = ctx.old_contexts[1]",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "        while parent is not None and not parent.active:",
                                "type": "deleted"
                            },
                            {
                                "content": "            parent = parent.old_contexts[1]",
                                "type": "deleted"
                            },
                            {
                                "content": "",
                                "type": "deleted"
                            },
                            {
                                "content": "        while parent is not None:",
                                "type": "added"
                            },
                            {
                                "content": "            if parent.active:",
                                "type": "added"
                            },
                            {
                                "content": "                break",
                                "type": "added"
                            },
                            {
                                "content": "            ctx.old_contexts = parent.old_contexts",
                                "type": "context"
                            },
                            {
                                "content": "            parent = parent.old_contexts[1]",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "        ctx = parent",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/stack_context.py",
                            "type": "function",
                            "name": "_remove_deactivated",
                            "content": "def _remove_deactivated(contexts):\n    \"\"\"Remove deactivated handlers from the chain\"\"\"\n    # Clean ctx handlers\n    stack_contexts = tuple([h for h in contexts[0] if h.active])\n\n    # Find new head\n    head = contexts[1]\n    while head is not None and not head.active:\n        head = head.old_contexts[1]\n\n    # Process chain\n    ctx = head\n    while ctx is not None:\n        parent = ctx.old_contexts[1]\n\n        while parent is not None and not parent.active:\n            parent = parent.old_contexts[1]\n\n            ctx.old_contexts = parent.old_contexts\n\n        ctx = parent\n\n    return (stack_contexts, head)",
                            "ast_type_str": "FunctionDef",
                            "start_lineno": 228,
                            "end_lineno": 250,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 267,
                            "length": 6
                        },
                        "new_range": {
                            "start": 268,
                            "length": 7
                        },
                        "section": "def wrap(fn):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "    cap_contexts = [_state.contexts]",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def wrapped(*args, **kwargs):",
                                "type": "context"
                            },
                            {
                                "content": "        ret = None",
                                "type": "added"
                            },
                            {
                                "content": "        try:",
                                "type": "context"
                            },
                            {
                                "content": "            # Capture old state",
                                "type": "context"
                            },
                            {
                                "content": "            current_state = _state.contexts",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/stack_context.py",
                            "type": "function",
                            "name": "wrap",
                            "content": "def wrap(fn):\n    \"\"\"Returns a callable object that will restore the current `StackContext`\n    when executed.\n\n    Use this whenever saving a callback to be executed later in a\n    different execution context (either in a different thread or\n    asynchronously in the same thread).\n    \"\"\"\n    # Check if function is already wrapped\n    if fn is None or hasattr(fn, '_wrapped'):\n        return fn\n\n    # Capture current stack head\n    # TODO: Any other better way to store contexts and update them in wrapped function?\n    cap_contexts = [_state.contexts]\n\n    def wrapped(*args, **kwargs):\n        ret = None\n        try:\n            # Capture old state\n            current_state = _state.contexts\n\n            # Remove deactivated items\n            cap_contexts[0] = contexts = _remove_deactivated(cap_contexts[0])\n\n            # Force new state\n            _state.contexts = contexts\n\n            # Current exception\n            exc = (None, None, None)\n            top = None\n\n            # Apply stack contexts\n            last_ctx = 0\n            stack = contexts[0]\n\n            # Apply state\n            for n in stack:\n                try:\n                    n.enter()\n                    last_ctx += 1\n                except:\n                    # Exception happened. Record exception info and store top-most handler\n                    exc = sys.exc_info()\n                    top = n.old_contexts[1]\n\n            # Execute callback if no exception happened while restoring state\n            if top is None:\n                try:\n                    ret = fn(*args, **kwargs)\n                except:\n                    exc = sys.exc_info()\n                    top = contexts[1]\n\n            # If there was exception, try to handle it by going through the exception chain\n            if top is not None:\n                exc = _handle_exception(top, exc)\n            else:\n                # Otherwise take shorter path and run stack contexts in reverse order\n                while last_ctx > 0:\n                    last_ctx -= 1\n                    c = stack[last_ctx]\n\n                    try:\n                        c.exit(*exc)\n                    except:\n                        exc = sys.exc_info()\n                        top = c.old_contexts[1]\n                        break\n                else:\n                    top = None\n\n                # If if exception happened while unrolling, take longer exception handler path\n                if top is not None:\n                    exc = _handle_exception(top, exc)\n\n            # If exception was not handled, raise it\n            if exc != (None, None, None):\n                raise_exc_info(exc)\n        finally:\n            _state.contexts = current_state\n        return ret\n\n    wrapped._wrapped = True\n    return wrapped",
                            "ast_type_str": "FunctionDef",
                            "start_lineno": 254,
                            "end_lineno": 338,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 298,
                            "length": 7
                        },
                        "new_range": {
                            "start": 300,
                            "length": 7
                        },
                        "section": "def wrap(fn):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "            # Execute callback if no exception happened while restoring state",
                                "type": "context"
                            },
                            {
                                "content": "            if top is None:",
                                "type": "context"
                            },
                            {
                                "content": "                try:",
                                "type": "context"
                            },
                            {
                                "content": "                    fn(*args, **kwargs)",
                                "type": "deleted"
                            },
                            {
                                "content": "                    ret = fn(*args, **kwargs)",
                                "type": "added"
                            },
                            {
                                "content": "                except:",
                                "type": "context"
                            },
                            {
                                "content": "                    exc = sys.exc_info()",
                                "type": "context"
                            },
                            {
                                "content": "                    top = contexts[1]",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/stack_context.py",
                            "type": "function",
                            "name": "wrap",
                            "content": "def wrap(fn):\n    \"\"\"Returns a callable object that will restore the current `StackContext`\n    when executed.\n\n    Use this whenever saving a callback to be executed later in a\n    different execution context (either in a different thread or\n    asynchronously in the same thread).\n    \"\"\"\n    # Check if function is already wrapped\n    if fn is None or hasattr(fn, '_wrapped'):\n        return fn\n\n    # Capture current stack head\n    # TODO: Any other better way to store contexts and update them in wrapped function?\n    cap_contexts = [_state.contexts]\n\n    def wrapped(*args, **kwargs):\n        try:\n            # Capture old state\n            current_state = _state.contexts\n\n            # Remove deactivated items\n            cap_contexts[0] = contexts = _remove_deactivated(cap_contexts[0])\n\n            # Force new state\n            _state.contexts = contexts\n\n            # Current exception\n            exc = (None, None, None)\n            top = None\n\n            # Apply stack contexts\n            last_ctx = 0\n            stack = contexts[0]\n\n            # Apply state\n            for n in stack:\n                try:\n                    n.enter()\n                    last_ctx += 1\n                except:\n                    # Exception happened. Record exception info and store top-most handler\n                    exc = sys.exc_info()\n                    top = n.old_contexts[1]\n\n            # Execute callback if no exception happened while restoring state\n            if top is None:\n                try:\n                    fn(*args, **kwargs)\n                except:\n                    exc = sys.exc_info()\n                    top = contexts[1]\n\n            # If there was exception, try to handle it by going through the exception chain\n            if top is not None:\n                exc = _handle_exception(top, exc)\n            else:\n                # Otherwise take shorter path and run stack contexts in reverse order\n                while last_ctx > 0:\n                    last_ctx -= 1\n                    c = stack[last_ctx]\n\n                    try:\n                        c.exit(*exc)\n                    except:\n                        exc = sys.exc_info()\n                        top = c.old_contexts[1]\n                        break\n                else:\n                    top = None\n\n                # If if exception happened while unrolling, take longer exception handler path\n                if top is not None:\n                    exc = _handle_exception(top, exc)\n\n            # If exception was not handled, raise it\n            if exc != (None, None, None):\n                raise_exc_info(exc)\n        finally:\n            _state.contexts = current_state\n\n    wrapped._wrapped = True\n    return wrapped",
                            "ast_type_str": "FunctionDef",
                            "start_lineno": 253,
                            "end_lineno": 335,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 330,
                            "length": 6
                        },
                        "new_range": {
                            "start": 332,
                            "length": 7
                        },
                        "section": "def wrap(fn):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "                raise_exc_info(exc)",
                                "type": "context"
                            },
                            {
                                "content": "        finally:",
                                "type": "context"
                            },
                            {
                                "content": "            _state.contexts = current_state",
                                "type": "context"
                            },
                            {
                                "content": "        return ret",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    wrapped._wrapped = True",
                                "type": "context"
                            },
                            {
                                "content": "    return wrapped",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/stack_context.py",
                            "type": "function",
                            "name": "wrap",
                            "content": "def wrap(fn):\n    \"\"\"Returns a callable object that will restore the current `StackContext`\n    when executed.\n\n    Use this whenever saving a callback to be executed later in a\n    different execution context (either in a different thread or\n    asynchronously in the same thread).\n    \"\"\"\n    # Check if function is already wrapped\n    if fn is None or hasattr(fn, '_wrapped'):\n        return fn\n\n    # Capture current stack head\n    # TODO: Any other better way to store contexts and update them in wrapped function?\n    cap_contexts = [_state.contexts]\n\n    def wrapped(*args, **kwargs):\n        ret = None\n        try:\n            # Capture old state\n            current_state = _state.contexts\n\n            # Remove deactivated items\n            cap_contexts[0] = contexts = _remove_deactivated(cap_contexts[0])\n\n            # Force new state\n            _state.contexts = contexts\n\n            # Current exception\n            exc = (None, None, None)\n            top = None\n\n            # Apply stack contexts\n            last_ctx = 0\n            stack = contexts[0]\n\n            # Apply state\n            for n in stack:\n                try:\n                    n.enter()\n                    last_ctx += 1\n                except:\n                    # Exception happened. Record exception info and store top-most handler\n                    exc = sys.exc_info()\n                    top = n.old_contexts[1]\n\n            # Execute callback if no exception happened while restoring state\n            if top is None:\n                try:\n                    ret = fn(*args, **kwargs)\n                except:\n                    exc = sys.exc_info()\n                    top = contexts[1]\n\n            # If there was exception, try to handle it by going through the exception chain\n            if top is not None:\n                exc = _handle_exception(top, exc)\n            else:\n                # Otherwise take shorter path and run stack contexts in reverse order\n                while last_ctx > 0:\n                    last_ctx -= 1\n                    c = stack[last_ctx]\n\n                    try:\n                        c.exit(*exc)\n                    except:\n                        exc = sys.exc_info()\n                        top = c.old_contexts[1]\n                        break\n                else:\n                    top = None\n\n                # If if exception happened while unrolling, take longer exception handler path\n                if top is not None:\n                    exc = _handle_exception(top, exc)\n\n            # If exception was not handled, raise it\n            if exc != (None, None, None):\n                raise_exc_info(exc)\n        finally:\n            _state.contexts = current_state\n        return ret\n\n    wrapped._wrapped = True\n    return wrapped",
                            "ast_type_str": "FunctionDef",
                            "start_lineno": 254,
                            "end_lineno": 338,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        },
        {
            "old_file_content": "#!/usr/bin/env python\nfrom __future__ import absolute_import, division, print_function, with_statement\n\nfrom tornado import gen\nfrom tornado.log import app_log\nfrom tornado.stack_context import (StackContext, wrap, NullContext, StackContextInconsistentError,\n                                   ExceptionStackContext, run_with_stack_context, _state)\nfrom tornado.testing import AsyncHTTPTestCase, AsyncTestCase, ExpectLog, gen_test\nfrom tornado.test.util import unittest\nfrom tornado.web import asynchronous, Application, RequestHandler\nimport contextlib\nimport functools\nimport logging\n\n\nclass TestRequestHandler(RequestHandler):\n    def __init__(self, app, request, io_loop):\n        super(TestRequestHandler, self).__init__(app, request)\n        self.io_loop = io_loop\n\n    @asynchronous\n    def get(self):\n        logging.debug('in get()')\n        # call self.part2 without a self.async_callback wrapper.  Its\n        # exception should still get thrown\n        self.io_loop.add_callback(self.part2)\n\n    def part2(self):\n        logging.debug('in part2()')\n        # Go through a third layer to make sure that contexts once restored\n        # are again passed on to future callbacks\n        self.io_loop.add_callback(self.part3)\n\n    def part3(self):\n        logging.debug('in part3()')\n        raise Exception('test exception')\n\n    def get_error_html(self, status_code, **kwargs):\n        if 'exception' in kwargs and str(kwargs['exception']) == 'test exception':\n            return 'got expected exception'\n        else:\n            return 'unexpected failure'\n\n\nclass HTTPStackContextTest(AsyncHTTPTestCase):\n    def get_app(self):\n        return Application([('/', TestRequestHandler,\n                             dict(io_loop=self.io_loop))])\n\n    def test_stack_context(self):\n        with ExpectLog(app_log, \"Uncaught exception GET /\"):\n            self.http_client.fetch(self.get_url('/'), self.handle_response)\n            self.wait()\n        self.assertEqual(self.response.code, 500)\n        self.assertTrue(b'got expected exception' in self.response.body)\n\n    def handle_response(self, response):\n        self.response = response\n        self.stop()\n\n\nclass StackContextTest(AsyncTestCase):\n    def setUp(self):\n        super(StackContextTest, self).setUp()\n        self.active_contexts = []\n\n    @contextlib.contextmanager\n    def context(self, name):\n        self.active_contexts.append(name)\n        yield\n        self.assertEqual(self.active_contexts.pop(), name)\n\n    # Simulates the effect of an asynchronous library that uses its own\n    # StackContext internally and then returns control to the application.\n    def test_exit_library_context(self):\n        def library_function(callback):\n            # capture the caller's context before introducing our own\n            callback = wrap(callback)\n            with StackContext(functools.partial(self.context, 'library')):\n                self.io_loop.add_callback(\n                    functools.partial(library_inner_callback, callback))\n\n        def library_inner_callback(callback):\n            self.assertEqual(self.active_contexts[-2:],\n                             ['application', 'library'])\n            callback()\n\n        def final_callback():\n            # implementation detail:  the full context stack at this point\n            # is ['application', 'library', 'application'].  The 'library'\n            # context was not removed, but is no longer innermost so\n            # the application context takes precedence.\n            self.assertEqual(self.active_contexts[-1], 'application')\n            self.stop()\n        with StackContext(functools.partial(self.context, 'application')):\n            library_function(final_callback)\n        self.wait()\n\n    def test_deactivate(self):\n        deactivate_callbacks = []\n\n        def f1():\n            with StackContext(functools.partial(self.context, 'c1')) as c1:\n                deactivate_callbacks.append(c1)\n                self.io_loop.add_callback(f2)\n\n        def f2():\n            with StackContext(functools.partial(self.context, 'c2')) as c2:\n                deactivate_callbacks.append(c2)\n                self.io_loop.add_callback(f3)\n\n        def f3():\n            with StackContext(functools.partial(self.context, 'c3')) as c3:\n                deactivate_callbacks.append(c3)\n                self.io_loop.add_callback(f4)\n\n        def f4():\n            self.assertEqual(self.active_contexts, ['c1', 'c2', 'c3'])\n            deactivate_callbacks[1]()\n            # deactivating a context doesn't remove it immediately,\n            # but it will be missing from the next iteration\n            self.assertEqual(self.active_contexts, ['c1', 'c2', 'c3'])\n            self.io_loop.add_callback(f5)\n\n        def f5():\n            self.assertEqual(self.active_contexts, ['c1', 'c3'])\n            self.stop()\n        self.io_loop.add_callback(f1)\n        self.wait()\n\n    def test_isolation_nonempty(self):\n        # f2 and f3 are a chain of operations started in context c1.\n        # f2 is incidentally run under context c2, but that context should\n        # not be passed along to f3.\n        def f1():\n            with StackContext(functools.partial(self.context, 'c1')):\n                wrapped = wrap(f2)\n            with StackContext(functools.partial(self.context, 'c2')):\n                wrapped()\n\n        def f2():\n            self.assertIn('c1', self.active_contexts)\n            self.io_loop.add_callback(f3)\n\n        def f3():\n            self.assertIn('c1', self.active_contexts)\n            self.assertNotIn('c2', self.active_contexts)\n            self.stop()\n\n        self.io_loop.add_callback(f1)\n        self.wait()\n\n    def test_isolation_empty(self):\n        # Similar to test_isolation_nonempty, but here the f2/f3 chain\n        # is started without any context.  Behavior should be equivalent\n        # to the nonempty case (although historically it was not)\n        def f1():\n            with NullContext():\n                wrapped = wrap(f2)\n            with StackContext(functools.partial(self.context, 'c2')):\n                wrapped()\n\n        def f2():\n            self.io_loop.add_callback(f3)\n\n        def f3():\n            self.assertNotIn('c2', self.active_contexts)\n            self.stop()\n\n        self.io_loop.add_callback(f1)\n        self.wait()\n\n    def test_yield_in_with(self):\n        @gen.engine\n        def f():\n            with StackContext(functools.partial(self.context, 'c1')):\n                # This yield is a problem: the generator will be suspended\n                # and the StackContext's __exit__ is not called yet, so\n                # the context will be left on _state.contexts for anything\n                # that runs before the yield resolves.\n                yield gen.Task(self.io_loop.add_callback)\n\n        with self.assertRaises(StackContextInconsistentError):\n            f()\n            self.wait()\n\n    @gen_test\n    def test_yield_outside_with(self):\n        # This pattern avoids the problem in the previous test.\n        cb = yield gen.Callback('k1')\n        with StackContext(functools.partial(self.context, 'c1')):\n            self.io_loop.add_callback(cb)\n        yield gen.Wait('k1')\n\n    def test_yield_in_with_exception_stack_context(self):\n        # As above, but with ExceptionStackContext instead of StackContext.\n        @gen.engine\n        def f():\n            with ExceptionStackContext(lambda t, v, tb: False):\n                yield gen.Task(self.io_loop.add_callback)\n\n        with self.assertRaises(StackContextInconsistentError):\n            f()\n            self.wait()\n\n    @gen_test\n    def test_yield_outside_with_exception_stack_context(self):\n        cb = yield gen.Callback('k1')\n        with ExceptionStackContext(lambda t, v, tb: False):\n            self.io_loop.add_callback(cb)\n        yield gen.Wait('k1')\n\n    def test_run_with_stack_context(self):\n        @gen.coroutine\n        def f1():\n            self.assertEqual(self.active_contexts, ['c1'])\n            yield run_with_stack_context(\n                StackContext(functools.partial(self.context, 'c1')),\n                f2)\n            self.assertEqual(self.active_contexts, ['c1'])\n\n        @gen.coroutine\n        def f2():\n            self.assertEqual(self.active_contexts, ['c1', 'c2'])\n            yield gen.Task(self.io_loop.add_callback)\n            self.assertEqual(self.active_contexts, ['c1', 'c2'])\n\n        self.assertEqual(self.active_contexts, [])\n        run_with_stack_context(\n            StackContext(functools.partial(self.context, 'c1')),\n            f1)\n        self.assertEqual(self.active_contexts, [])\n\nif __name__ == '__main__':\n    unittest.main()\n",
            "new_file_content": "#!/usr/bin/env python\nfrom __future__ import absolute_import, division, print_function, with_statement\n\nfrom tornado import gen\nfrom tornado.log import app_log\nfrom tornado.stack_context import (StackContext, wrap, NullContext, StackContextInconsistentError,\n                                   ExceptionStackContext, run_with_stack_context, _state)\nfrom tornado.testing import AsyncHTTPTestCase, AsyncTestCase, ExpectLog, gen_test\nfrom tornado.test.util import unittest\nfrom tornado.web import asynchronous, Application, RequestHandler\nimport contextlib\nimport functools\nimport logging\n\n\nclass TestRequestHandler(RequestHandler):\n    def __init__(self, app, request, io_loop):\n        super(TestRequestHandler, self).__init__(app, request)\n        self.io_loop = io_loop\n\n    @asynchronous\n    def get(self):\n        logging.debug('in get()')\n        # call self.part2 without a self.async_callback wrapper.  Its\n        # exception should still get thrown\n        self.io_loop.add_callback(self.part2)\n\n    def part2(self):\n        logging.debug('in part2()')\n        # Go through a third layer to make sure that contexts once restored\n        # are again passed on to future callbacks\n        self.io_loop.add_callback(self.part3)\n\n    def part3(self):\n        logging.debug('in part3()')\n        raise Exception('test exception')\n\n    def get_error_html(self, status_code, **kwargs):\n        if 'exception' in kwargs and str(kwargs['exception']) == 'test exception':\n            return 'got expected exception'\n        else:\n            return 'unexpected failure'\n\n\nclass HTTPStackContextTest(AsyncHTTPTestCase):\n    def get_app(self):\n        return Application([('/', TestRequestHandler,\n                             dict(io_loop=self.io_loop))])\n\n    def test_stack_context(self):\n        with ExpectLog(app_log, \"Uncaught exception GET /\"):\n            self.http_client.fetch(self.get_url('/'), self.handle_response)\n            self.wait()\n        self.assertEqual(self.response.code, 500)\n        self.assertTrue(b'got expected exception' in self.response.body)\n\n    def handle_response(self, response):\n        self.response = response\n        self.stop()\n\n\nclass StackContextTest(AsyncTestCase):\n    def setUp(self):\n        super(StackContextTest, self).setUp()\n        self.active_contexts = []\n\n    @contextlib.contextmanager\n    def context(self, name):\n        self.active_contexts.append(name)\n        yield\n        self.assertEqual(self.active_contexts.pop(), name)\n\n    # Simulates the effect of an asynchronous library that uses its own\n    # StackContext internally and then returns control to the application.\n    def test_exit_library_context(self):\n        def library_function(callback):\n            # capture the caller's context before introducing our own\n            callback = wrap(callback)\n            with StackContext(functools.partial(self.context, 'library')):\n                self.io_loop.add_callback(\n                    functools.partial(library_inner_callback, callback))\n\n        def library_inner_callback(callback):\n            self.assertEqual(self.active_contexts[-2:],\n                             ['application', 'library'])\n            callback()\n\n        def final_callback():\n            # implementation detail:  the full context stack at this point\n            # is ['application', 'library', 'application'].  The 'library'\n            # context was not removed, but is no longer innermost so\n            # the application context takes precedence.\n            self.assertEqual(self.active_contexts[-1], 'application')\n            self.stop()\n        with StackContext(functools.partial(self.context, 'application')):\n            library_function(final_callback)\n        self.wait()\n\n    def test_deactivate(self):\n        deactivate_callbacks = []\n\n        def f1():\n            with StackContext(functools.partial(self.context, 'c1')) as c1:\n                deactivate_callbacks.append(c1)\n                self.io_loop.add_callback(f2)\n\n        def f2():\n            with StackContext(functools.partial(self.context, 'c2')) as c2:\n                deactivate_callbacks.append(c2)\n                self.io_loop.add_callback(f3)\n\n        def f3():\n            with StackContext(functools.partial(self.context, 'c3')) as c3:\n                deactivate_callbacks.append(c3)\n                self.io_loop.add_callback(f4)\n\n        def f4():\n            self.assertEqual(self.active_contexts, ['c1', 'c2', 'c3'])\n            deactivate_callbacks[1]()\n            # deactivating a context doesn't remove it immediately,\n            # but it will be missing from the next iteration\n            self.assertEqual(self.active_contexts, ['c1', 'c2', 'c3'])\n            self.io_loop.add_callback(f5)\n\n        def f5():\n            self.assertEqual(self.active_contexts, ['c1', 'c3'])\n            self.stop()\n        self.io_loop.add_callback(f1)\n        self.wait()\n\n    def test_deactivate_order(self):\n        # Stack context deactivation has separate logic for deactivation at\n        # the head and tail of the stack, so make sure it works in any order.\n        def check_contexts():\n            # Make sure that the full-context array and the exception-context\n            # linked lists are consistent with each other.\n            full_contexts, chain = _state.contexts\n            exception_contexts = []\n            while chain is not None:\n                exception_contexts.append(chain)\n                chain = chain.old_contexts[1]\n            self.assertEqual(list(reversed(full_contexts)), exception_contexts)\n            return list(self.active_contexts)\n\n        def make_wrapped_function():\n            \"\"\"Wraps a function in three stack contexts, and returns\n            the function along with the deactivation functions.\n            \"\"\"\n            # Remove the test's stack context to make sure we can cover\n            # the case where the last context is deactivated.\n            with NullContext():\n                with StackContext(functools.partial(self.context, 'c0')) as c0,\\\n                     StackContext(functools.partial(self.context, 'c1')) as c1,\\\n                     StackContext(functools.partial(self.context, 'c2')) as c2:\n                    return (wrap(check_contexts), [c0, c1, c2])\n\n        # First make sure the test mechanism works without any deactivations\n        func, deactivate_callbacks = make_wrapped_function()\n        self.assertEqual(func(), ['c0', 'c1', 'c2'])\n\n        # Deactivate the tail\n        func, deactivate_callbacks = make_wrapped_function()\n        deactivate_callbacks[0]()\n        self.assertEqual(func(), ['c1', 'c2'])\n\n        # Deactivate the middle\n        func, deactivate_callbacks = make_wrapped_function()\n        deactivate_callbacks[1]()\n        self.assertEqual(func(), ['c0', 'c2'])\n\n        # Deactivate the head\n        func, deactivate_callbacks = make_wrapped_function()\n        deactivate_callbacks[2]()\n        self.assertEqual(func(), ['c0', 'c1'])\n\n\n    def test_isolation_nonempty(self):\n        # f2 and f3 are a chain of operations started in context c1.\n        # f2 is incidentally run under context c2, but that context should\n        # not be passed along to f3.\n        def f1():\n            with StackContext(functools.partial(self.context, 'c1')):\n                wrapped = wrap(f2)\n            with StackContext(functools.partial(self.context, 'c2')):\n                wrapped()\n\n        def f2():\n            self.assertIn('c1', self.active_contexts)\n            self.io_loop.add_callback(f3)\n\n        def f3():\n            self.assertIn('c1', self.active_contexts)\n            self.assertNotIn('c2', self.active_contexts)\n            self.stop()\n\n        self.io_loop.add_callback(f1)\n        self.wait()\n\n    def test_isolation_empty(self):\n        # Similar to test_isolation_nonempty, but here the f2/f3 chain\n        # is started without any context.  Behavior should be equivalent\n        # to the nonempty case (although historically it was not)\n        def f1():\n            with NullContext():\n                wrapped = wrap(f2)\n            with StackContext(functools.partial(self.context, 'c2')):\n                wrapped()\n\n        def f2():\n            self.io_loop.add_callback(f3)\n\n        def f3():\n            self.assertNotIn('c2', self.active_contexts)\n            self.stop()\n\n        self.io_loop.add_callback(f1)\n        self.wait()\n\n    def test_yield_in_with(self):\n        @gen.engine\n        def f():\n            with StackContext(functools.partial(self.context, 'c1')):\n                # This yield is a problem: the generator will be suspended\n                # and the StackContext's __exit__ is not called yet, so\n                # the context will be left on _state.contexts for anything\n                # that runs before the yield resolves.\n                yield gen.Task(self.io_loop.add_callback)\n\n        with self.assertRaises(StackContextInconsistentError):\n            f()\n            self.wait()\n\n    @gen_test\n    def test_yield_outside_with(self):\n        # This pattern avoids the problem in the previous test.\n        cb = yield gen.Callback('k1')\n        with StackContext(functools.partial(self.context, 'c1')):\n            self.io_loop.add_callback(cb)\n        yield gen.Wait('k1')\n\n    def test_yield_in_with_exception_stack_context(self):\n        # As above, but with ExceptionStackContext instead of StackContext.\n        @gen.engine\n        def f():\n            with ExceptionStackContext(lambda t, v, tb: False):\n                yield gen.Task(self.io_loop.add_callback)\n\n        with self.assertRaises(StackContextInconsistentError):\n            f()\n            self.wait()\n\n    @gen_test\n    def test_yield_outside_with_exception_stack_context(self):\n        cb = yield gen.Callback('k1')\n        with ExceptionStackContext(lambda t, v, tb: False):\n            self.io_loop.add_callback(cb)\n        yield gen.Wait('k1')\n\n    def test_run_with_stack_context(self):\n        @gen.coroutine\n        def f1():\n            self.assertEqual(self.active_contexts, ['c1'])\n            yield run_with_stack_context(\n                StackContext(functools.partial(self.context, 'c1')),\n                f2)\n            self.assertEqual(self.active_contexts, ['c1'])\n\n        @gen.coroutine\n        def f2():\n            self.assertEqual(self.active_contexts, ['c1', 'c2'])\n            yield gen.Task(self.io_loop.add_callback)\n            self.assertEqual(self.active_contexts, ['c1', 'c2'])\n\n        self.assertEqual(self.active_contexts, [])\n        run_with_stack_context(\n            StackContext(functools.partial(self.context, 'c1')),\n            f1)\n        self.assertEqual(self.active_contexts, [])\n\nif __name__ == '__main__':\n    unittest.main()\n",
            "header": {
                "file": {
                    "path": "tornado/test/stack_context_test.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "976ef400",
                "new_commit_hash": "192bf891",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/tornado/test/stack_context_test.py"
            },
            "plus_file": {
                "path": "b/tornado/test/stack_context_test.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 128,
                            "length": 6
                        },
                        "new_range": {
                            "start": 128,
                            "length": 52
                        },
                        "section": "class StackContextTest(AsyncTestCase):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        self.io_loop.add_callback(f1)",
                                "type": "context"
                            },
                            {
                                "content": "        self.wait()",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def test_deactivate_order(self):",
                                "type": "added"
                            },
                            {
                                "content": "        # Stack context deactivation has separate logic for deactivation at",
                                "type": "added"
                            },
                            {
                                "content": "        # the head and tail of the stack, so make sure it works in any order.",
                                "type": "added"
                            },
                            {
                                "content": "        def check_contexts():",
                                "type": "added"
                            },
                            {
                                "content": "            # Make sure that the full-context array and the exception-context",
                                "type": "added"
                            },
                            {
                                "content": "            # linked lists are consistent with each other.",
                                "type": "added"
                            },
                            {
                                "content": "            full_contexts, chain = _state.contexts",
                                "type": "added"
                            },
                            {
                                "content": "            exception_contexts = []",
                                "type": "added"
                            },
                            {
                                "content": "            while chain is not None:",
                                "type": "added"
                            },
                            {
                                "content": "                exception_contexts.append(chain)",
                                "type": "added"
                            },
                            {
                                "content": "                chain = chain.old_contexts[1]",
                                "type": "added"
                            },
                            {
                                "content": "            self.assertEqual(list(reversed(full_contexts)), exception_contexts)",
                                "type": "added"
                            },
                            {
                                "content": "            return list(self.active_contexts)",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        def make_wrapped_function():",
                                "type": "added"
                            },
                            {
                                "content": "            \"\"\"Wraps a function in three stack contexts, and returns",
                                "type": "added"
                            },
                            {
                                "content": "            the function along with the deactivation functions.",
                                "type": "added"
                            },
                            {
                                "content": "            \"\"\"",
                                "type": "added"
                            },
                            {
                                "content": "            # Remove the test's stack context to make sure we can cover",
                                "type": "added"
                            },
                            {
                                "content": "            # the case where the last context is deactivated.",
                                "type": "added"
                            },
                            {
                                "content": "            with NullContext():",
                                "type": "added"
                            },
                            {
                                "content": "                with StackContext(functools.partial(self.context, 'c0')) as c0,\\",
                                "type": "added"
                            },
                            {
                                "content": "                     StackContext(functools.partial(self.context, 'c1')) as c1,\\",
                                "type": "added"
                            },
                            {
                                "content": "                     StackContext(functools.partial(self.context, 'c2')) as c2:",
                                "type": "added"
                            },
                            {
                                "content": "                    return (wrap(check_contexts), [c0, c1, c2])",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        # First make sure the test mechanism works without any deactivations",
                                "type": "added"
                            },
                            {
                                "content": "        func, deactivate_callbacks = make_wrapped_function()",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertEqual(func(), ['c0', 'c1', 'c2'])",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        # Deactivate the tail",
                                "type": "added"
                            },
                            {
                                "content": "        func, deactivate_callbacks = make_wrapped_function()",
                                "type": "added"
                            },
                            {
                                "content": "        deactivate_callbacks[0]()",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertEqual(func(), ['c1', 'c2'])",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        # Deactivate the middle",
                                "type": "added"
                            },
                            {
                                "content": "        func, deactivate_callbacks = make_wrapped_function()",
                                "type": "added"
                            },
                            {
                                "content": "        deactivate_callbacks[1]()",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertEqual(func(), ['c0', 'c2'])",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        # Deactivate the head",
                                "type": "added"
                            },
                            {
                                "content": "        func, deactivate_callbacks = make_wrapped_function()",
                                "type": "added"
                            },
                            {
                                "content": "        deactivate_callbacks[2]()",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertEqual(func(), ['c0', 'c1'])",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    def test_isolation_nonempty(self):",
                                "type": "context"
                            },
                            {
                                "content": "        # f2 and f3 are a chain of operations started in context c1.",
                                "type": "context"
                            },
                            {
                                "content": "        # f2 is incidentally run under context c2, but that context should",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/test/stack_context_test.py",
                            "type": "class",
                            "name": "StackContextTest",
                            "content": "class StackContextTest(AsyncTestCase):\n    def setUp(self):\n        super(StackContextTest, self).setUp()\n        self.active_contexts = []\n\n    @contextlib.contextmanager\n    def context(self, name):\n        self.active_contexts.append(name)\n        yield\n        self.assertEqual(self.active_contexts.pop(), name)\n\n    # Simulates the effect of an asynchronous library that uses its own\n    # StackContext internally and then returns control to the application.\n    def test_exit_library_context(self):\n        def library_function(callback):\n            # capture the caller's context before introducing our own\n            callback = wrap(callback)\n            with StackContext(functools.partial(self.context, 'library')):\n                self.io_loop.add_callback(\n                    functools.partial(library_inner_callback, callback))\n\n        def library_inner_callback(callback):\n            self.assertEqual(self.active_contexts[-2:],\n                             ['application', 'library'])\n            callback()\n\n        def final_callback():\n            # implementation detail:  the full context stack at this point\n            # is ['application', 'library', 'application'].  The 'library'\n            # context was not removed, but is no longer innermost so\n            # the application context takes precedence.\n            self.assertEqual(self.active_contexts[-1], 'application')\n            self.stop()\n        with StackContext(functools.partial(self.context, 'application')):\n            library_function(final_callback)\n        self.wait()\n\n    def test_deactivate(self):\n        deactivate_callbacks = []\n\n        def f1():\n            with StackContext(functools.partial(self.context, 'c1')) as c1:\n                deactivate_callbacks.append(c1)\n                self.io_loop.add_callback(f2)\n\n        def f2():\n            with StackContext(functools.partial(self.context, 'c2')) as c2:\n                deactivate_callbacks.append(c2)\n                self.io_loop.add_callback(f3)\n\n        def f3():\n            with StackContext(functools.partial(self.context, 'c3')) as c3:\n                deactivate_callbacks.append(c3)\n                self.io_loop.add_callback(f4)\n\n        def f4():\n            self.assertEqual(self.active_contexts, ['c1', 'c2', 'c3'])\n            deactivate_callbacks[1]()\n            # deactivating a context doesn't remove it immediately,\n            # but it will be missing from the next iteration\n            self.assertEqual(self.active_contexts, ['c1', 'c2', 'c3'])\n            self.io_loop.add_callback(f5)\n\n        def f5():\n            self.assertEqual(self.active_contexts, ['c1', 'c3'])\n            self.stop()\n        self.io_loop.add_callback(f1)\n        self.wait()\n\n    def test_deactivate_order(self):\n        # Stack context deactivation has separate logic for deactivation at\n        # the head and tail of the stack, so make sure it works in any order.\n        def check_contexts():\n            # Make sure that the full-context array and the exception-context\n            # linked lists are consistent with each other.\n            full_contexts, chain = _state.contexts\n            exception_contexts = []\n            while chain is not None:\n                exception_contexts.append(chain)\n                chain = chain.old_contexts[1]\n            self.assertEqual(list(reversed(full_contexts)), exception_contexts)\n            return list(self.active_contexts)\n\n        def make_wrapped_function():\n            \"\"\"Wraps a function in three stack contexts, and returns\n            the function along with the deactivation functions.\n            \"\"\"\n            # Remove the test's stack context to make sure we can cover\n            # the case where the last context is deactivated.\n            with NullContext():\n                with StackContext(functools.partial(self.context, 'c0')) as c0,\\\n                     StackContext(functools.partial(self.context, 'c1')) as c1,\\\n                     StackContext(functools.partial(self.context, 'c2')) as c2:\n                    return (wrap(check_contexts), [c0, c1, c2])\n\n        # First make sure the test mechanism works without any deactivations\n        func, deactivate_callbacks = make_wrapped_function()\n        self.assertEqual(func(), ['c0', 'c1', 'c2'])\n\n        # Deactivate the tail\n        func, deactivate_callbacks = make_wrapped_function()\n        deactivate_callbacks[0]()\n        self.assertEqual(func(), ['c1', 'c2'])\n\n        # Deactivate the middle\n        func, deactivate_callbacks = make_wrapped_function()\n        deactivate_callbacks[1]()\n        self.assertEqual(func(), ['c0', 'c2'])\n\n        # Deactivate the head\n        func, deactivate_callbacks = make_wrapped_function()\n        deactivate_callbacks[2]()\n        self.assertEqual(func(), ['c0', 'c1'])\n\n\n    def test_isolation_nonempty(self):\n        # f2 and f3 are a chain of operations started in context c1.\n        # f2 is incidentally run under context c2, but that context should\n        # not be passed along to f3.\n        def f1():\n            with StackContext(functools.partial(self.context, 'c1')):\n                wrapped = wrap(f2)\n            with StackContext(functools.partial(self.context, 'c2')):\n                wrapped()\n\n        def f2():\n            self.assertIn('c1', self.active_contexts)\n            self.io_loop.add_callback(f3)\n\n        def f3():\n            self.assertIn('c1', self.active_contexts)\n            self.assertNotIn('c2', self.active_contexts)\n            self.stop()\n\n        self.io_loop.add_callback(f1)\n        self.wait()\n\n    def test_isolation_empty(self):\n        # Similar to test_isolation_nonempty, but here the f2/f3 chain\n        # is started without any context.  Behavior should be equivalent\n        # to the nonempty case (although historically it was not)\n        def f1():\n            with NullContext():\n                wrapped = wrap(f2)\n            with StackContext(functools.partial(self.context, 'c2')):\n                wrapped()\n\n        def f2():\n            self.io_loop.add_callback(f3)\n\n        def f3():\n            self.assertNotIn('c2', self.active_contexts)\n            self.stop()\n\n        self.io_loop.add_callback(f1)\n        self.wait()\n\n    def test_yield_in_with(self):\n        @gen.engine\n        def f():\n            with StackContext(functools.partial(self.context, 'c1')):\n                # This yield is a problem: the generator will be suspended\n                # and the StackContext's __exit__ is not called yet, so\n                # the context will be left on _state.contexts for anything\n                # that runs before the yield resolves.\n                yield gen.Task(self.io_loop.add_callback)\n\n        with self.assertRaises(StackContextInconsistentError):\n            f()\n            self.wait()\n\n    @gen_test\n    def test_yield_outside_with(self):\n        # This pattern avoids the problem in the previous test.\n        cb = yield gen.Callback('k1')\n        with StackContext(functools.partial(self.context, 'c1')):\n            self.io_loop.add_callback(cb)\n        yield gen.Wait('k1')\n\n    def test_yield_in_with_exception_stack_context(self):\n        # As above, but with ExceptionStackContext instead of StackContext.\n        @gen.engine\n        def f():\n            with ExceptionStackContext(lambda t, v, tb: False):\n                yield gen.Task(self.io_loop.add_callback)\n\n        with self.assertRaises(StackContextInconsistentError):\n            f()\n            self.wait()\n\n    @gen_test\n    def test_yield_outside_with_exception_stack_context(self):\n        cb = yield gen.Callback('k1')\n        with ExceptionStackContext(lambda t, v, tb: False):\n            self.io_loop.add_callback(cb)\n        yield gen.Wait('k1')\n\n    def test_run_with_stack_context(self):\n        @gen.coroutine\n        def f1():\n            self.assertEqual(self.active_contexts, ['c1'])\n            yield run_with_stack_context(\n                StackContext(functools.partial(self.context, 'c1')),\n                f2)\n            self.assertEqual(self.active_contexts, ['c1'])\n\n        @gen.coroutine\n        def f2():\n            self.assertEqual(self.active_contexts, ['c1', 'c2'])\n            yield gen.Task(self.io_loop.add_callback)\n            self.assertEqual(self.active_contexts, ['c1', 'c2'])\n\n        self.assertEqual(self.active_contexts, [])\n        run_with_stack_context(\n            StackContext(functools.partial(self.context, 'c1')),\n            f1)\n        self.assertEqual(self.active_contexts, [])",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 62,
                            "end_lineno": 278,
                            "parent": null
                        }
                    ],
                    "added_entities": [
                        {
                            "file_name": "tornado/test/stack_context_test.py",
                            "type": "method",
                            "name": "StackContextTest.test_deactivate_order",
                            "content": "class StackContextTest(AsyncTestCase):\n    def setUp(self):\n        super(StackContextTest, self).setUp()\n        self.active_contexts = []\n\n    @contextlib.contextmanager\n    def context(self, name):\n        self.active_contexts.append(name)\n        yield\n        self.assertEqual(self.active_contexts.pop(), name)\n\n    # Simulates the effect of an asynchronous library that uses its own\n    # StackContext internally and then returns control to the application.\n    def test_exit_library_context(self):\n        def library_function(callback):\n            # capture the caller's context before introducing our own\n            callback = wrap(callback)\n            with StackContext(functools.partial(self.context, 'library')):\n                self.io_loop.add_callback(\n                    functools.partial(library_inner_callback, callback))\n\n        def library_inner_callback(callback):\n            self.assertEqual(self.active_contexts[-2:],\n                             ['application', 'library'])\n            callback()\n\n        def final_callback():\n            # implementation detail:  the full context stack at this point\n            # is ['application', 'library', 'application'].  The 'library'\n            # context was not removed, but is no longer innermost so\n            # the application context takes precedence.\n            self.assertEqual(self.active_contexts[-1], 'application')\n            self.stop()\n        with StackContext(functools.partial(self.context, 'application')):\n            library_function(final_callback)\n        self.wait()\n\n    def test_deactivate(self):\n        deactivate_callbacks = []\n\n        def f1():\n            with StackContext(functools.partial(self.context, 'c1')) as c1:\n                deactivate_callbacks.append(c1)\n                self.io_loop.add_callback(f2)\n\n        def f2():\n            with StackContext(functools.partial(self.context, 'c2')) as c2:\n                deactivate_callbacks.append(c2)\n                self.io_loop.add_callback(f3)\n\n        def f3():\n            with StackContext(functools.partial(self.context, 'c3')) as c3:\n                deactivate_callbacks.append(c3)\n                self.io_loop.add_callback(f4)\n\n        def f4():\n            self.assertEqual(self.active_contexts, ['c1', 'c2', 'c3'])\n            deactivate_callbacks[1]()\n            # deactivating a context doesn't remove it immediately,\n            # but it will be missing from the next iteration\n            self.assertEqual(self.active_contexts, ['c1', 'c2', 'c3'])\n            self.io_loop.add_callback(f5)\n\n        def f5():\n            self.assertEqual(self.active_contexts, ['c1', 'c3'])\n            self.stop()\n        self.io_loop.add_callback(f1)\n        self.wait()\n\n    def test_deactivate_order(self):\n        # Stack context deactivation has separate logic for deactivation at\n        # the head and tail of the stack, so make sure it works in any order.\n        def check_contexts():\n            # Make sure that the full-context array and the exception-context\n            # linked lists are consistent with each other.\n            full_contexts, chain = _state.contexts\n            exception_contexts = []\n            while chain is not None:\n                exception_contexts.append(chain)\n                chain = chain.old_contexts[1]\n            self.assertEqual(list(reversed(full_contexts)), exception_contexts)\n            return list(self.active_contexts)\n\n        def make_wrapped_function():\n            \"\"\"Wraps a function in three stack contexts, and returns\n            the function along with the deactivation functions.\n            \"\"\"\n            # Remove the test's stack context to make sure we can cover\n            # the case where the last context is deactivated.\n            with NullContext():\n                with StackContext(functools.partial(self.context, 'c0')) as c0,\\\n                     StackContext(functools.partial(self.context, 'c1')) as c1,\\\n                     StackContext(functools.partial(self.context, 'c2')) as c2:\n                    return (wrap(check_contexts), [c0, c1, c2])\n\n        # First make sure the test mechanism works without any deactivations\n        func, deactivate_callbacks = make_wrapped_function()\n        self.assertEqual(func(), ['c0', 'c1', 'c2'])\n\n        # Deactivate the tail\n        func, deactivate_callbacks = make_wrapped_function()\n        deactivate_callbacks[0]()\n        self.assertEqual(func(), ['c1', 'c2'])\n\n        # Deactivate the middle\n        func, deactivate_callbacks = make_wrapped_function()\n        deactivate_callbacks[1]()\n        self.assertEqual(func(), ['c0', 'c2'])\n\n        # Deactivate the head\n        func, deactivate_callbacks = make_wrapped_function()\n        deactivate_callbacks[2]()\n        self.assertEqual(func(), ['c0', 'c1'])\n\n\n    def test_isolation_nonempty(self):\n        # f2 and f3 are a chain of operations started in context c1.\n        # f2 is incidentally run under context c2, but that context should\n        # not be passed along to f3.\n        def f1():\n            with StackContext(functools.partial(self.context, 'c1')):\n                wrapped = wrap(f2)\n            with StackContext(functools.partial(self.context, 'c2')):\n                wrapped()\n\n        def f2():\n            self.assertIn('c1', self.active_contexts)\n            self.io_loop.add_callback(f3)\n\n        def f3():\n            self.assertIn('c1', self.active_contexts)\n            self.assertNotIn('c2', self.active_contexts)\n            self.stop()\n\n        self.io_loop.add_callback(f1)\n        self.wait()\n\n    def test_isolation_empty(self):\n        # Similar to test_isolation_nonempty, but here the f2/f3 chain\n        # is started without any context.  Behavior should be equivalent\n        # to the nonempty case (although historically it was not)\n        def f1():\n            with NullContext():\n                wrapped = wrap(f2)\n            with StackContext(functools.partial(self.context, 'c2')):\n                wrapped()\n\n        def f2():\n            self.io_loop.add_callback(f3)\n\n        def f3():\n            self.assertNotIn('c2', self.active_contexts)\n            self.stop()\n\n        self.io_loop.add_callback(f1)\n        self.wait()\n\n    def test_yield_in_with(self):\n        @gen.engine\n        def f():\n            with StackContext(functools.partial(self.context, 'c1')):\n                # This yield is a problem: the generator will be suspended\n                # and the StackContext's __exit__ is not called yet, so\n                # the context will be left on _state.contexts for anything\n                # that runs before the yield resolves.\n                yield gen.Task(self.io_loop.add_callback)\n\n        with self.assertRaises(StackContextInconsistentError):\n            f()\n            self.wait()\n\n    @gen_test\n    def test_yield_outside_with(self):\n        # This pattern avoids the problem in the previous test.\n        cb = yield gen.Callback('k1')\n        with StackContext(functools.partial(self.context, 'c1')):\n            self.io_loop.add_callback(cb)\n        yield gen.Wait('k1')\n\n    def test_yield_in_with_exception_stack_context(self):\n        # As above, but with ExceptionStackContext instead of StackContext.\n        @gen.engine\n        def f():\n            with ExceptionStackContext(lambda t, v, tb: False):\n                yield gen.Task(self.io_loop.add_callback)\n\n        with self.assertRaises(StackContextInconsistentError):\n            f()\n            self.wait()\n\n    @gen_test\n    def test_yield_outside_with_exception_stack_context(self):\n        cb = yield gen.Callback('k1')\n        with ExceptionStackContext(lambda t, v, tb: False):\n            self.io_loop.add_callback(cb)\n        yield gen.Wait('k1')\n\n    def test_run_with_stack_context(self):\n        @gen.coroutine\n        def f1():\n            self.assertEqual(self.active_contexts, ['c1'])\n            yield run_with_stack_context(\n                StackContext(functools.partial(self.context, 'c1')),\n                f2)\n            self.assertEqual(self.active_contexts, ['c1'])\n\n        @gen.coroutine\n        def f2():\n            self.assertEqual(self.active_contexts, ['c1', 'c2'])\n            yield gen.Task(self.io_loop.add_callback)\n            self.assertEqual(self.active_contexts, ['c1', 'c2'])\n\n        self.assertEqual(self.active_contexts, [])\n        run_with_stack_context(\n            StackContext(functools.partial(self.context, 'c1')),\n            f1)\n        self.assertEqual(self.active_contexts, [])",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 131,
                            "end_lineno": 174,
                            "parent": {
                                "file_name": "tornado/test/stack_context_test.py",
                                "type": "class",
                                "name": "StackContextTest",
                                "content": "class StackContextTest(AsyncTestCase):\n    def setUp(self):\n        super(StackContextTest, self).setUp()\n        self.active_contexts = []\n\n    @contextlib.contextmanager\n    def context(self, name):\n        self.active_contexts.append(name)\n        yield\n        self.assertEqual(self.active_contexts.pop(), name)\n\n    # Simulates the effect of an asynchronous library that uses its own\n    # StackContext internally and then returns control to the application.\n    def test_exit_library_context(self):\n        def library_function(callback):\n            # capture the caller's context before introducing our own\n            callback = wrap(callback)\n            with StackContext(functools.partial(self.context, 'library')):\n                self.io_loop.add_callback(\n                    functools.partial(library_inner_callback, callback))\n\n        def library_inner_callback(callback):\n            self.assertEqual(self.active_contexts[-2:],\n                             ['application', 'library'])\n            callback()\n\n        def final_callback():\n            # implementation detail:  the full context stack at this point\n            # is ['application', 'library', 'application'].  The 'library'\n            # context was not removed, but is no longer innermost so\n            # the application context takes precedence.\n            self.assertEqual(self.active_contexts[-1], 'application')\n            self.stop()\n        with StackContext(functools.partial(self.context, 'application')):\n            library_function(final_callback)\n        self.wait()\n\n    def test_deactivate(self):\n        deactivate_callbacks = []\n\n        def f1():\n            with StackContext(functools.partial(self.context, 'c1')) as c1:\n                deactivate_callbacks.append(c1)\n                self.io_loop.add_callback(f2)\n\n        def f2():\n            with StackContext(functools.partial(self.context, 'c2')) as c2:\n                deactivate_callbacks.append(c2)\n                self.io_loop.add_callback(f3)\n\n        def f3():\n            with StackContext(functools.partial(self.context, 'c3')) as c3:\n                deactivate_callbacks.append(c3)\n                self.io_loop.add_callback(f4)\n\n        def f4():\n            self.assertEqual(self.active_contexts, ['c1', 'c2', 'c3'])\n            deactivate_callbacks[1]()\n            # deactivating a context doesn't remove it immediately,\n            # but it will be missing from the next iteration\n            self.assertEqual(self.active_contexts, ['c1', 'c2', 'c3'])\n            self.io_loop.add_callback(f5)\n\n        def f5():\n            self.assertEqual(self.active_contexts, ['c1', 'c3'])\n            self.stop()\n        self.io_loop.add_callback(f1)\n        self.wait()\n\n    def test_deactivate_order(self):\n        # Stack context deactivation has separate logic for deactivation at\n        # the head and tail of the stack, so make sure it works in any order.\n        def check_contexts():\n            # Make sure that the full-context array and the exception-context\n            # linked lists are consistent with each other.\n            full_contexts, chain = _state.contexts\n            exception_contexts = []\n            while chain is not None:\n                exception_contexts.append(chain)\n                chain = chain.old_contexts[1]\n            self.assertEqual(list(reversed(full_contexts)), exception_contexts)\n            return list(self.active_contexts)\n\n        def make_wrapped_function():\n            \"\"\"Wraps a function in three stack contexts, and returns\n            the function along with the deactivation functions.\n            \"\"\"\n            # Remove the test's stack context to make sure we can cover\n            # the case where the last context is deactivated.\n            with NullContext():\n                with StackContext(functools.partial(self.context, 'c0')) as c0,\\\n                     StackContext(functools.partial(self.context, 'c1')) as c1,\\\n                     StackContext(functools.partial(self.context, 'c2')) as c2:\n                    return (wrap(check_contexts), [c0, c1, c2])\n\n        # First make sure the test mechanism works without any deactivations\n        func, deactivate_callbacks = make_wrapped_function()\n        self.assertEqual(func(), ['c0', 'c1', 'c2'])\n\n        # Deactivate the tail\n        func, deactivate_callbacks = make_wrapped_function()\n        deactivate_callbacks[0]()\n        self.assertEqual(func(), ['c1', 'c2'])\n\n        # Deactivate the middle\n        func, deactivate_callbacks = make_wrapped_function()\n        deactivate_callbacks[1]()\n        self.assertEqual(func(), ['c0', 'c2'])\n\n        # Deactivate the head\n        func, deactivate_callbacks = make_wrapped_function()\n        deactivate_callbacks[2]()\n        self.assertEqual(func(), ['c0', 'c1'])\n\n\n    def test_isolation_nonempty(self):\n        # f2 and f3 are a chain of operations started in context c1.\n        # f2 is incidentally run under context c2, but that context should\n        # not be passed along to f3.\n        def f1():\n            with StackContext(functools.partial(self.context, 'c1')):\n                wrapped = wrap(f2)\n            with StackContext(functools.partial(self.context, 'c2')):\n                wrapped()\n\n        def f2():\n            self.assertIn('c1', self.active_contexts)\n            self.io_loop.add_callback(f3)\n\n        def f3():\n            self.assertIn('c1', self.active_contexts)\n            self.assertNotIn('c2', self.active_contexts)\n            self.stop()\n\n        self.io_loop.add_callback(f1)\n        self.wait()\n\n    def test_isolation_empty(self):\n        # Similar to test_isolation_nonempty, but here the f2/f3 chain\n        # is started without any context.  Behavior should be equivalent\n        # to the nonempty case (although historically it was not)\n        def f1():\n            with NullContext():\n                wrapped = wrap(f2)\n            with StackContext(functools.partial(self.context, 'c2')):\n                wrapped()\n\n        def f2():\n            self.io_loop.add_callback(f3)\n\n        def f3():\n            self.assertNotIn('c2', self.active_contexts)\n            self.stop()\n\n        self.io_loop.add_callback(f1)\n        self.wait()\n\n    def test_yield_in_with(self):\n        @gen.engine\n        def f():\n            with StackContext(functools.partial(self.context, 'c1')):\n                # This yield is a problem: the generator will be suspended\n                # and the StackContext's __exit__ is not called yet, so\n                # the context will be left on _state.contexts for anything\n                # that runs before the yield resolves.\n                yield gen.Task(self.io_loop.add_callback)\n\n        with self.assertRaises(StackContextInconsistentError):\n            f()\n            self.wait()\n\n    @gen_test\n    def test_yield_outside_with(self):\n        # This pattern avoids the problem in the previous test.\n        cb = yield gen.Callback('k1')\n        with StackContext(functools.partial(self.context, 'c1')):\n            self.io_loop.add_callback(cb)\n        yield gen.Wait('k1')\n\n    def test_yield_in_with_exception_stack_context(self):\n        # As above, but with ExceptionStackContext instead of StackContext.\n        @gen.engine\n        def f():\n            with ExceptionStackContext(lambda t, v, tb: False):\n                yield gen.Task(self.io_loop.add_callback)\n\n        with self.assertRaises(StackContextInconsistentError):\n            f()\n            self.wait()\n\n    @gen_test\n    def test_yield_outside_with_exception_stack_context(self):\n        cb = yield gen.Callback('k1')\n        with ExceptionStackContext(lambda t, v, tb: False):\n            self.io_loop.add_callback(cb)\n        yield gen.Wait('k1')\n\n    def test_run_with_stack_context(self):\n        @gen.coroutine\n        def f1():\n            self.assertEqual(self.active_contexts, ['c1'])\n            yield run_with_stack_context(\n                StackContext(functools.partial(self.context, 'c1')),\n                f2)\n            self.assertEqual(self.active_contexts, ['c1'])\n\n        @gen.coroutine\n        def f2():\n            self.assertEqual(self.active_contexts, ['c1', 'c2'])\n            yield gen.Task(self.io_loop.add_callback)\n            self.assertEqual(self.active_contexts, ['c1', 'c2'])\n\n        self.assertEqual(self.active_contexts, [])\n        run_with_stack_context(\n            StackContext(functools.partial(self.context, 'c1')),\n            f1)\n        self.assertEqual(self.active_contexts, [])",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 62,
                                "end_lineno": 278,
                                "parent": null
                            }
                        }
                    ],
                    "deleted_entities": []
                }
            ]
        }
    ],
    "old_commit_hash": "46850a7b3cee73c068b03690f1f97e8fda1326d3^",
    "new_commit_hash": "46850a7b3cee73c068b03690f1f97e8fda1326d3",
    "commit_message": "Fix an exception when the outermost stack_context is deactivated.\n\nAdd more tests for deactivation in various scenarios.",
    "commit_date": "2013-05-26T17:50:09-04:00",
    "metadata": {}
}
{
    "repo_name": "tornado",
    "new_commit_hash": "46850a7b3cee73c068b03690f1f97e8fda1326d3",
    "test_file_codes": [
        "#!/usr/bin/env python\nfrom __future__ import absolute_import, division, print_function, with_statement\n\nfrom tornado import gen\nfrom tornado.log import app_log\nfrom tornado.stack_context import (StackContext, wrap, NullContext, StackContextInconsistentError,\n                                   ExceptionStackContext, run_with_stack_context, _state)\nfrom tornado.testing import AsyncHTTPTestCase, AsyncTestCase, ExpectLog, gen_test\nfrom tornado.test.util import unittest\nfrom tornado.web import asynchronous, Application, RequestHandler\nimport contextlib\nimport functools\nimport logging\n\n\nclass TestRequestHandler(RequestHandler):\n    def __init__(self, app, request, io_loop):\n        super(TestRequestHandler, self).__init__(app, request)\n        self.io_loop = io_loop\n\n    @asynchronous\n    def get(self):\n        logging.debug('in get()')\n        # call self.part2 without a self.async_callback wrapper.  Its\n        # exception should still get thrown\n        self.io_loop.add_callback(self.part2)\n\n    def part2(self):\n        logging.debug('in part2()')\n        # Go through a third layer to make sure that contexts once restored\n        # are again passed on to future callbacks\n        self.io_loop.add_callback(self.part3)\n\n    def part3(self):\n        logging.debug('in part3()')\n        raise Exception('test exception')\n\n    def get_error_html(self, status_code, **kwargs):\n        if 'exception' in kwargs and str(kwargs['exception']) == 'test exception':\n            return 'got expected exception'\n        else:\n            return 'unexpected failure'\n\n\nclass HTTPStackContextTest(AsyncHTTPTestCase):\n    def get_app(self):\n        return Application([('/', TestRequestHandler,\n                             dict(io_loop=self.io_loop))])\n\n    def test_stack_context(self):\n        with ExpectLog(app_log, \"Uncaught exception GET /\"):\n            self.http_client.fetch(self.get_url('/'), self.handle_response)\n            self.wait()\n        self.assertEqual(self.response.code, 500)\n        self.assertTrue(b'got expected exception' in self.response.body)\n\n    def handle_response(self, response):\n        self.response = response\n        self.stop()\n\n\nclass StackContextTest(AsyncTestCase):\n    def setUp(self):\n        super(StackContextTest, self).setUp()\n        self.active_contexts = []\n\n    @contextlib.contextmanager\n    def context(self, name):\n        self.active_contexts.append(name)\n        yield\n        self.assertEqual(self.active_contexts.pop(), name)\n\n    # Simulates the effect of an asynchronous library that uses its own\n    # StackContext internally and then returns control to the application.\n    def test_exit_library_context(self):\n        def library_function(callback):\n            # capture the caller's context before introducing our own\n            callback = wrap(callback)\n            with StackContext(functools.partial(self.context, 'library')):\n                self.io_loop.add_callback(\n                    functools.partial(library_inner_callback, callback))\n\n        def library_inner_callback(callback):\n            self.assertEqual(self.active_contexts[-2:],\n                             ['application', 'library'])\n            callback()\n\n        def final_callback():\n            # implementation detail:  the full context stack at this point\n            # is ['application', 'library', 'application'].  The 'library'\n            # context was not removed, but is no longer innermost so\n            # the application context takes precedence.\n            self.assertEqual(self.active_contexts[-1], 'application')\n            self.stop()\n        with StackContext(functools.partial(self.context, 'application')):\n            library_function(final_callback)\n        self.wait()\n\n    def test_deactivate(self):\n        deactivate_callbacks = []\n\n        def f1():\n            with StackContext(functools.partial(self.context, 'c1')) as c1:\n                deactivate_callbacks.append(c1)\n                self.io_loop.add_callback(f2)\n\n        def f2():\n            with StackContext(functools.partial(self.context, 'c2')) as c2:\n                deactivate_callbacks.append(c2)\n                self.io_loop.add_callback(f3)\n\n        def f3():\n            with StackContext(functools.partial(self.context, 'c3')) as c3:\n                deactivate_callbacks.append(c3)\n                self.io_loop.add_callback(f4)\n\n        def f4():\n            self.assertEqual(self.active_contexts, ['c1', 'c2', 'c3'])\n            deactivate_callbacks[1]()\n            # deactivating a context doesn't remove it immediately,\n            # but it will be missing from the next iteration\n            self.assertEqual(self.active_contexts, ['c1', 'c2', 'c3'])\n            self.io_loop.add_callback(f5)\n\n        def f5():\n            self.assertEqual(self.active_contexts, ['c1', 'c3'])\n            self.stop()\n        self.io_loop.add_callback(f1)\n        self.wait()\n\n    def test_deactivate_order(self):\n        # Stack context deactivation has separate logic for deactivation at\n        # the head and tail of the stack, so make sure it works in any order.\n        def check_contexts():\n            # Make sure that the full-context array and the exception-context\n            # linked lists are consistent with each other.\n            full_contexts, chain = _state.contexts\n            exception_contexts = []\n            while chain is not None:\n                exception_contexts.append(chain)\n                chain = chain.old_contexts[1]\n            self.assertEqual(list(reversed(full_contexts)), exception_contexts)\n            return list(self.active_contexts)\n\n        def make_wrapped_function():\n            \"\"\"Wraps a function in three stack contexts, and returns\n            the function along with the deactivation functions.\n            \"\"\"\n            # Remove the test's stack context to make sure we can cover\n            # the case where the last context is deactivated.\n            with NullContext():\n                with StackContext(functools.partial(self.context, 'c0')) as c0,\\\n                     StackContext(functools.partial(self.context, 'c1')) as c1,\\\n                     StackContext(functools.partial(self.context, 'c2')) as c2:\n                    return (wrap(check_contexts), [c0, c1, c2])\n\n        # First make sure the test mechanism works without any deactivations\n        func, deactivate_callbacks = make_wrapped_function()\n        self.assertEqual(func(), ['c0', 'c1', 'c2'])\n\n        # Deactivate the tail\n        func, deactivate_callbacks = make_wrapped_function()\n        deactivate_callbacks[0]()\n        self.assertEqual(func(), ['c1', 'c2'])\n\n        # Deactivate the middle\n        func, deactivate_callbacks = make_wrapped_function()\n        deactivate_callbacks[1]()\n        self.assertEqual(func(), ['c0', 'c2'])\n\n        # Deactivate the head\n        func, deactivate_callbacks = make_wrapped_function()\n        deactivate_callbacks[2]()\n        self.assertEqual(func(), ['c0', 'c1'])\n\n\n    def test_isolation_nonempty(self):\n        # f2 and f3 are a chain of operations started in context c1.\n        # f2 is incidentally run under context c2, but that context should\n        # not be passed along to f3.\n        def f1():\n            with StackContext(functools.partial(self.context, 'c1')):\n                wrapped = wrap(f2)\n            with StackContext(functools.partial(self.context, 'c2')):\n                wrapped()\n\n        def f2():\n            self.assertIn('c1', self.active_contexts)\n            self.io_loop.add_callback(f3)\n\n        def f3():\n            self.assertIn('c1', self.active_contexts)\n            self.assertNotIn('c2', self.active_contexts)\n            self.stop()\n\n        self.io_loop.add_callback(f1)\n        self.wait()\n\n    def test_isolation_empty(self):\n        # Similar to test_isolation_nonempty, but here the f2/f3 chain\n        # is started without any context.  Behavior should be equivalent\n        # to the nonempty case (although historically it was not)\n        def f1():\n            with NullContext():\n                wrapped = wrap(f2)\n            with StackContext(functools.partial(self.context, 'c2')):\n                wrapped()\n\n        def f2():\n            self.io_loop.add_callback(f3)\n\n        def f3():\n            self.assertNotIn('c2', self.active_contexts)\n            self.stop()\n\n        self.io_loop.add_callback(f1)\n        self.wait()\n\n    def test_yield_in_with(self):\n        @gen.engine\n        def f():\n            with StackContext(functools.partial(self.context, 'c1')):\n                # This yield is a problem: the generator will be suspended\n                # and the StackContext's __exit__ is not called yet, so\n                # the context will be left on _state.contexts for anything\n                # that runs before the yield resolves.\n                yield gen.Task(self.io_loop.add_callback)\n\n        with self.assertRaises(StackContextInconsistentError):\n            f()\n            self.wait()\n\n    @gen_test\n    def test_yield_outside_with(self):\n        # This pattern avoids the problem in the previous test.\n        cb = yield gen.Callback('k1')\n        with StackContext(functools.partial(self.context, 'c1')):\n            self.io_loop.add_callback(cb)\n        yield gen.Wait('k1')\n\n    def test_yield_in_with_exception_stack_context(self):\n        # As above, but with ExceptionStackContext instead of StackContext.\n        @gen.engine\n        def f():\n            with ExceptionStackContext(lambda t, v, tb: False):\n                yield gen.Task(self.io_loop.add_callback)\n\n        with self.assertRaises(StackContextInconsistentError):\n            f()\n            self.wait()\n\n    @gen_test\n    def test_yield_outside_with_exception_stack_context(self):\n        cb = yield gen.Callback('k1')\n        with ExceptionStackContext(lambda t, v, tb: False):\n            self.io_loop.add_callback(cb)\n        yield gen.Wait('k1')\n\n    def test_run_with_stack_context(self):\n        @gen.coroutine\n        def f1():\n            self.assertEqual(self.active_contexts, ['c1'])\n            yield run_with_stack_context(\n                StackContext(functools.partial(self.context, 'c1')),\n                f2)\n            self.assertEqual(self.active_contexts, ['c1'])\n\n        @gen.coroutine\n        def f2():\n            self.assertEqual(self.active_contexts, ['c1', 'c2'])\n            yield gen.Task(self.io_loop.add_callback)\n            self.assertEqual(self.active_contexts, ['c1', 'c2'])\n\n        self.assertEqual(self.active_contexts, [])\n        run_with_stack_context(\n            StackContext(functools.partial(self.context, 'c1')),\n            f1)\n        self.assertEqual(self.active_contexts, [])\n\nif __name__ == '__main__':\n    unittest.main()\n",
        "#!/usr/bin/env python\nimport unittest\nimport sys\nimport time\nimport traceback\nimport platform\nimport os\n\n\nclass PytestLikeResult(unittest.TestResult):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self.start_time = None\n        # Store (test, outcome, info) for each test:\n        #   outcome ∈ { \"passed\", \"failed\", \"error\", \"skipped\" }\n        #   info can hold the exception or skip reason, etc.\n        self.results = []\n\n    def startTestRun(self):\n        \"\"\"Called once before all tests.\"\"\"\n        self.start_time = time.time()\n        # Print a header similar to pytest\n        print(\"=\" * 29 + \" test session starts \" + \"=\" * 29)\n        # You can customize the platform/versions/paths as you like:\n        print(\n            f\"platform {platform.system().lower()} -- Python {platform.python_version()}\"\n        )\n        print(f\"rootdir: {os.path.abspath(os.curdir)}\")\n\n    def stopTestRun(self):\n        \"\"\"Called once after all tests are done.\"\"\"\n        elapsed = time.time() - self.start_time\n        print()  # blank line after final dot\n\n        # Summarize\n        ntests = len(self.results)\n        print(f\"collected {ntests} items\")\n\n        # Show details of failures/errors\n        failures = [r for r in self.results if r[1] == \"failed\"]\n        errors = [r for r in self.results if r[1] == \"error\"]\n\n        if failures:\n            print(\"\\n\" + \"=\" * 35 + \" FAILURES \" + \"=\" * 35)\n            for test, outcome, err_info in failures:\n                test = test.split(\"::\")\n                if len(test) == 3:\n                    test = f\"{test[1]}.{test[2]}\"\n                else:\n                    test = f\"{test[1]}\"\n                print(f\"__________ {test} __________\")\n                self._print_traceback(err_info)\n        if errors:\n            print(\"\\n\" + \"=\" * 35 + \" ERRORS \" + \"=\" * 37)\n            for test, outcome, err_info in errors:\n                test = test.split(\"::\")\n                if len(test) == 3:\n                    test = f\"{test[1]}.{test[2]}\"\n                else:\n                    test = f\"{test[1]}\"\n                print(f\"__________ {test} __________\")\n                self._print_traceback(err_info)\n\n        # Optional short summary lines for passes/fails/skips\n        print(\"\\n==================== short test summary info ====================\")\n        for test, outcome, info in self.results:\n            if outcome in (\"passed\", \"failed\", \"error\", \"skipped\"):\n                print(f\"{outcome.upper()} {test}\")\n\n        # Final one-line summary: “1 failed, 1 errors, 10 passed in 2.04s”\n        passed_count = sum(1 for r in self.results if r[1] == \"passed\")\n        failed_count = len(failures)\n        error_count = len(errors)\n        skipped_count = sum(1 for r in self.results if r[1] == \"skipped\")\n\n        summary_bits = []\n        if failed_count:\n            summary_bits.append(f\"{failed_count} failed\")\n        if error_count:\n            summary_bits.append(f\"{error_count} error{'s' if error_count != 1 else ''}\")\n        if passed_count:\n            summary_bits.append(f\"{passed_count} passed\")\n        if skipped_count:\n            summary_bits.append(f\"{skipped_count} skipped\")\n\n        summary_str = \", \".join(summary_bits) if summary_bits else \"no tests run\"\n        print(\n            f\"=================== {summary_str} in {elapsed:.2f}s ===================\"\n        )\n\n    def startTest(self, test):\n        \"\"\"Called right before each test method.\"\"\"\n        super().startTest(test)\n        # Print a dot or some indicator\n        print(\".\", end=\"\", flush=True)\n\n    def addSuccess(self, test):\n        super().addSuccess(test)\n        self.results.append((self._test_id(test), \"passed\", None))\n\n    def addFailure(self, test, err):\n        super().addFailure(test, err)\n        self.results.append((self._test_id(test), \"failed\", err))\n\n    def addError(self, test, err):\n        super().addError(test, err)\n        self.results.append((self._test_id(test), \"error\", err))\n\n    def addSkip(self, test, reason):\n        super().addSkip(test, reason)\n        self.results.append((self._test_id(test), \"skipped\", reason))\n\n    def _print_traceback(self, err_info):\n        \"\"\"Helper to print the traceback like pytest does.\"\"\"\n        if isinstance(err_info, tuple) and len(err_info) == 3:\n            exc_type, exc_value, tb = err_info\n            traceback.print_exception(exc_type, exc_value, tb, file=sys.stdout)\n        else:\n            print(str(err_info))\n\n    def _test_id(self, test):\n        try:\n            return f\"{test.__class__.__module__}::{test.__class__.__name__}::{test._testMethodName}\"\n        except AttributeError:\n            # Fallback for _ErrorHolder objects\n            return f\"{test.__class__.__module__}::{test.__class__.__name__}\"\n\n\nclass PytestLikeRunner(unittest.TextTestRunner):\n    \"\"\"A custom TextTestRunner that uses the PytestLikeResult.\"\"\"\n\n    resultclass = PytestLikeResult\n\n    def run(self, test):\n        result = self._makeResult()\n        # Overriding run to ensure we call startTestRun/stopTestRun\n        result.startTestRun()\n        test(result)\n        result.stopTestRun()\n        return result\n\n    def tearDown(self):\n        # Reset signal handlers\n        from twisted.internet import reactor\n\n        reactor.removeAll()\n        reactor.stop()\n        super().tearDown()\n\n\ndef main():\n    loader = unittest.TestLoader()\n    suite = loader.discover(\".\", pattern=\"test_*.py\")  # discover tests in r2e_tests/\n    runner = PytestLikeRunner(verbosity=0)\n    result = runner.run(suite)\n    # Exit with code 0 if all tests passed/skipped, 1 if there were fails/errors\n    sys.exit(not result.wasSuccessful())\n\n\nif __name__ == \"__main__\":\n    main()\n"
    ],
    "test_file_names": [
        "test_1.py",
        "tornado_unittest_runner.py"
    ],
    "setup_res_code": 0,
    "setup_res_stdout": "",
    "setup_res_stderr": "Using CPython 3.9.21\nCreating virtual environment at: .venv\nActivate with: source .venv/bin/activate\nResolved 1 package in 795ms\nPrepared 1 package in 816ms\nInstalled 1 package in 0.99ms\n + tornado==3.1.dev2 (from file:///home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_46850a7b3cee73c068b03690f1f97e8fda1326d3)\nResolved 29 packages in 19ms\nInstalled 29 packages in 109ms\n + attrs==24.3.0\n + automat==24.8.1\n + cachetools==5.5.0\n + cffi==1.17.1\n + chardet==5.2.0\n + colorama==0.4.6\n + constantly==23.10.4\n + distlib==0.3.9\n + exceptiongroup==1.2.2\n + filelock==3.16.1\n + hyperlink==21.0.0\n + idna==3.10\n + incremental==24.7.2\n + iniconfig==2.0.0\n + packaging==24.2\n + platformdirs==4.3.6\n + pluggy==1.5.0\n + pycares==4.5.0\n + pycparser==2.22\n + pycurl==7.45.4\n + pyproject-api==1.8.0\n + pytest==8.3.4\n + setuptools==75.6.0\n + tomli==2.2.1\n + tox==4.23.2\n + twisted==24.11.0\n + typing-extensions==4.12.2\n + virtualenv==20.28.0\n + zope-interface==7.2\n",
    "new_commit_res_code": 0,
    "new_commit_res_stdout": "============================= test session starts =============================\nplatform linux -- Python 3.9.21\nrootdir: /home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_46850a7b3cee73c068b03690f1f97e8fda1326d3\n...........\ncollected 11 items\n\n==================== short test summary info ====================\nPASSED r2e_tests.test_1::HTTPStackContextTest::test_stack_context\nPASSED r2e_tests.test_1::StackContextTest::test_deactivate\nPASSED r2e_tests.test_1::StackContextTest::test_deactivate_order\nPASSED r2e_tests.test_1::StackContextTest::test_exit_library_context\nPASSED r2e_tests.test_1::StackContextTest::test_isolation_empty\nPASSED r2e_tests.test_1::StackContextTest::test_isolation_nonempty\nPASSED r2e_tests.test_1::StackContextTest::test_run_with_stack_context\nPASSED r2e_tests.test_1::StackContextTest::test_yield_in_with\nPASSED r2e_tests.test_1::StackContextTest::test_yield_in_with_exception_stack_context\nPASSED r2e_tests.test_1::StackContextTest::test_yield_outside_with\nPASSED r2e_tests.test_1::StackContextTest::test_yield_outside_with_exception_stack_context\n=================== 11 passed in 0.01s ===================\n",
    "new_commit_res_stderr": "ERROR:tornado.access:500 GET / (127.0.0.1) 0.48ms\nException ignored in: <generator object StackContextTest.test_yield_in_with.<locals>.f at 0x757bbb6b0580>\nTraceback (most recent call last):\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_46850a7b3cee73c068b03690f1f97e8fda1326d3/r2e_tests/test_1.py\", line 227, in f\n    yield gen.Task(self.io_loop.add_callback)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_46850a7b3cee73c068b03690f1f97e8fda1326d3/tornado/stack_context.py\", line 157, in __exit__\n    raise StackContextInconsistentError(\ntornado.stack_context.StackContextInconsistentError: stack_context inconsistency (may be caused by yield within a \"with StackContext\" block)\nException ignored in: <generator object StackContextTest.test_yield_in_with_exception_stack_context.<locals>.f at 0x757bbb6b0350>\nTraceback (most recent call last):\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_46850a7b3cee73c068b03690f1f97e8fda1326d3/r2e_tests/test_1.py\", line 246, in f\n    yield gen.Task(self.io_loop.add_callback)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_46850a7b3cee73c068b03690f1f97e8fda1326d3/tornado/stack_context.py\", line 205, in __exit__\n    raise StackContextInconsistentError(\ntornado.stack_context.StackContextInconsistentError: stack_context inconsistency (may be caused by yield within a \"with StackContext\" block)\n",
    "old_commit_res_code": 1,
    "old_commit_res_stdout": "============================= test session starts =============================\nplatform linux -- Python 3.9.21\nrootdir: /home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_46850a7b3cee73c068b03690f1f97e8fda1326d3\n...........\ncollected 11 items\n\n=================================== FAILURES ===================================\n__________ StackContextTest.test_deactivate_order __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_46850a7b3cee73c068b03690f1f97e8fda1326d3/r2e_tests/test_1.py\", line 159, in test_deactivate_order\n    self.assertEqual(func(), ['c0', 'c1', 'c2'])\nAssertionError: None != ['c0', 'c1', 'c2']\n\n==================== short test summary info ====================\nPASSED r2e_tests.test_1::HTTPStackContextTest::test_stack_context\nPASSED r2e_tests.test_1::StackContextTest::test_deactivate\nFAILED r2e_tests.test_1::StackContextTest::test_deactivate_order\nPASSED r2e_tests.test_1::StackContextTest::test_exit_library_context\nPASSED r2e_tests.test_1::StackContextTest::test_isolation_empty\nPASSED r2e_tests.test_1::StackContextTest::test_isolation_nonempty\nPASSED r2e_tests.test_1::StackContextTest::test_run_with_stack_context\nPASSED r2e_tests.test_1::StackContextTest::test_yield_in_with\nPASSED r2e_tests.test_1::StackContextTest::test_yield_in_with_exception_stack_context\nPASSED r2e_tests.test_1::StackContextTest::test_yield_outside_with\nPASSED r2e_tests.test_1::StackContextTest::test_yield_outside_with_exception_stack_context\n=================== 1 failed, 10 passed in 0.01s ===================\n",
    "old_commit_res_stderr": "ERROR:tornado.access:500 GET / (127.0.0.1) 0.55ms\nException ignored in: <generator object StackContextTest.test_yield_in_with.<locals>.f at 0x78765b495890>\nTraceback (most recent call last):\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_46850a7b3cee73c068b03690f1f97e8fda1326d3/r2e_tests/test_1.py\", line 227, in f\n    yield gen.Task(self.io_loop.add_callback)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_46850a7b3cee73c068b03690f1f97e8fda1326d3/tornado/stack_context.py\", line 157, in __exit__\n    raise StackContextInconsistentError(\ntornado.stack_context.StackContextInconsistentError: stack_context inconsistency (may be caused by yield within a \"with StackContext\" block)\nException ignored in: <generator object StackContextTest.test_yield_in_with_exception_stack_context.<locals>.f at 0x78765b495ac0>\nTraceback (most recent call last):\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_46850a7b3cee73c068b03690f1f97e8fda1326d3/r2e_tests/test_1.py\", line 246, in f\n    yield gen.Task(self.io_loop.add_callback)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_46850a7b3cee73c068b03690f1f97e8fda1326d3/tornado/stack_context.py\", line 205, in __exit__\n    raise StackContextInconsistentError(\ntornado.stack_context.StackContextInconsistentError: stack_context inconsistency (may be caused by yield within a \"with StackContext\" block)\n"
}
tornado/stack_context.py tornado/test/stack_context_test.py
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ISSUE]

**Title:** Wrapped functions return `None` when the outermost `stack_context` is deactivated

**Description:**
When the outermost `stack_context` is deactivated, functions wrapped by `StackContext` unexpectedly return `None` instead of their intended results. This behavior leads to loss of context information, causing parts of the application to malfunction when they rely on the returned context data.

**Example Code:**
```python
def check_contexts():
    # Intended to return the list of active contexts
    return list(self.active_contexts)

def make_wrapped_function():
    with NullContext():
        with StackContext(functools.partial(self.context, 'c0')) as c0, \
             StackContext(functools.partial(self.context, 'c1')) as c1, \
             StackContext(functools.partial(self.context, 'c2')) as c2:
            return wrap(check_contexts), [c0, c1, c2]

func, deactivate_callbacks = make_wrapped_function()
result = func()  # Expected: ['c0', 'c1', 'c2'], Actual: None
```

**Expected Behavior:**
Functions wrapped by `StackContext` should return their expected results (e.g., the list of active contexts) even after the outermost `stack_context` is deactivated.

**Actual Behavior:**
Wrapped functions return `None` instead of the expected list of active contexts when the outermost `stack_context` is deactivated.

[/ISSUE]
--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.

--- BEGIN FILE ---
```
### tornado/stack_context.py
#!/usr/bin/env python
#
# Copyright 2010 Facebook
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

"""`StackContext` allows applications to maintain threadlocal-like state
that follows execution as it moves to other execution contexts.

The motivating examples are to eliminate the need for explicit
``async_callback`` wrappers (as in `tornado.web.RequestHandler`), and to
allow some additional context to be kept for logging.

This is slightly magic, but it's an extension of the idea that an
exception handler is a kind of stack-local state and when that stack
is suspended and resumed in a new context that state needs to be
preserved.  `StackContext` shifts the burden of restoring that state
from each call site (e.g.  wrapping each `.AsyncHTTPClient` callback
in ``async_callback``) to the mechanisms that transfer control from
one context to another (e.g. `.AsyncHTTPClient` itself, `.IOLoop`,
thread pools, etc).

Example usage::

    @contextlib.contextmanager
    def die_on_error():
        try:
            yield
        except Exception:
            logging.error("exception in asynchronous operation",exc_info=True)
            sys.exit(1)

    with StackContext(die_on_error):
        # Any exception thrown here *or in callback and its desendents*
        # will cause the process to exit instead of spinning endlessly
        # in the ioloop.
        http_client.fetch(url, callback)
    ioloop.start()

Most applications shouln't have to work with `StackContext` directly.
Here are a few rules of thumb for when it's necessary:

* If you're writing an asynchronous library that doesn't rely on a
  stack_context-aware library like `tornado.ioloop` or `tornado.iostream`
  (for example, if you're writing a thread pool), use
  `.stack_context.wrap()` before any asynchronous operations to capture the
  stack context from where the operation was started.

* If you're writing an asynchronous library that has some shared
  resources (such as a connection pool), create those shared resources
  within a ``with stack_context.NullContext():`` block.  This will prevent
  ``StackContexts`` from leaking from one request to another.

* If you want to write something like an exception handler that will
  persist across asynchronous calls, create a new `StackContext` (or
  `ExceptionStackContext`), and make your asynchronous calls in a ``with``
  block that references your `StackContext`.
"""

from __future__ import absolute_import, division, print_function, with_statement

import sys
import threading
import operator

from tornado.util import raise_exc_info


class StackContextInconsistentError(Exception):
    pass


class _State(threading.local):
    def __init__(self):
        self.contexts = (tuple(), None)
_state = _State()


class StackContext(object):
    """Establishes the given context as a StackContext that will be transferred.

    Note that the parameter is a callable that returns a context
    manager, not the context itself.  That is, where for a
    non-transferable context manager you would say::

      with my_context():

    StackContext takes the function itself rather than its result::

      with StackContext(my_context):

    The result of ``with StackContext() as cb:`` is a deactivation
    callback.  Run this callback when the StackContext is no longer
    needed to ensure that it is not propagated any further (note that
    deactivating a context does not affect any instances of that
    context that are currently pending).  This is an advanced feature
    and not necessary in most applications.
    """
    def __init__(self, context_factory):
        self.context_factory = context_factory
        self.contexts = []
        self.active = True

    def _deactivate(self):
        self.active = False

    # StackContext protocol
    def enter(self):
        context = self.context_factory()
        self.contexts.append(context)
        context.__enter__()

    def exit(self, type, value, traceback):
        context = self.contexts.pop()
        context.__exit__(type, value, traceback)

    # Note that some of this code is duplicated in ExceptionStackContext
    # below.  ExceptionStackContext is more common and doesn't need
    # the full generality of this class.
    def __enter__(self):
        self.old_contexts = _state.contexts
        self.new_contexts = (self.old_contexts[0] + (self,), self)
        _state.contexts = self.new_contexts

        try:
            self.enter()
        except:
            _state.contexts = self.old_contexts
            raise

        return self._deactivate

    def __exit__(self, type, value, traceback):
        try:
            self.exit(type, value, traceback)
        finally:
            final_contexts = _state.contexts
            _state.contexts = self.old_contexts

            # Generator coroutines and with-statements with non-local
            # effects interact badly.  Check here for signs of
            # the stack getting out of sync.
            # Note that this check comes after restoring _state.context
            # so that if it fails things are left in a (relatively)
            # consistent state.
            if final_contexts is not self.new_contexts:
                raise StackContextInconsistentError(
                    'stack_context inconsistency (may be caused by yield '
                    'within a "with StackContext" block)')

            # Break up a reference to itself to allow for faster GC on CPython.
            self.new_contexts = None


class ExceptionStackContext(object):
    """Specialization of StackContext for exception handling.

    The supplied ``exception_handler`` function will be called in the
    event of an uncaught exception in this context.  The semantics are
    similar to a try/finally clause, and intended use cases are to log
    an error, close a socket, or similar cleanup actions.  The
    ``exc_info`` triple ``(type, value, traceback)`` will be passed to the
    exception_handler function.

    If the exception handler returns true, the exception will be
    consumed and will not be propagated to other exception handlers.
    """
    def __init__(self, exception_handler):
        self.exception_handler = exception_handler
        self.active = True

    def _deactivate(self):
        self.active = False

    def exit(self, type, value, traceback):
        if type is not None:
            return self.exception_handler(type, value, traceback)

    def __enter__(self):
        self.old_contexts = _state.contexts
        self.new_contexts = (self.old_contexts[0], self)
        _state.contexts = self.new_contexts

        return self._deactivate

    def __exit__(self, type, value, traceback):
        try:
            if type is not None:
                return self.exception_handler(type, value, traceback)
        finally:
            final_contexts = _state.contexts
            _state.contexts = self.old_contexts

            if final_contexts is not self.new_contexts:
                raise StackContextInconsistentError(
                    'stack_context inconsistency (may be caused by yield '
                    'within a "with StackContext" block)')

            # Break up a reference to itself to allow for faster GC on CPython.
            self.new_contexts = None


class NullContext(object):
    """Resets the `StackContext`.

    Useful when creating a shared resource on demand (e.g. an
    `.AsyncHTTPClient`) where the stack that caused the creating is
    not relevant to future operations.
    """
    def __enter__(self):
        self.old_contexts = _state.contexts
        _state.contexts = (tuple(), None)

    def __exit__(self, type, value, traceback):
        _state.contexts = self.old_contexts


def _remove_deactivated(contexts):
    """Remove deactivated handlers from the chain"""
    # Clean ctx handlers
    stack_contexts = tuple([h for h in contexts[0] if h.active])

    # Find new head
    head = contexts[1]
    while head is not None and not head.active:
        head = head.old_contexts[1]

    # Process chain
    ctx = head
    while ctx is not None:
        parent = ctx.old_contexts[1]

        while parent is not None and not parent.active:
            parent = parent.old_contexts[1]

            ctx.old_contexts = parent.old_contexts

        ctx = parent

    return (stack_contexts, head)


def wrap(fn):
    """Returns a callable object that will restore the current `StackContext`
    when executed.

    Use this whenever saving a callback to be executed later in a
    different execution context (either in a different thread or
    asynchronously in the same thread).
    """
    # Check if function is already wrapped
    if fn is None or hasattr(fn, '_wrapped'):
        return fn

    # Capture current stack head
    # TODO: Any other better way to store contexts and update them in wrapped function?
    cap_contexts = [_state.contexts]

    def wrapped(*args, **kwargs):
        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:
                    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

    wrapped._wrapped = True
    return wrapped


def _handle_exception(tail, exc):
    while tail is not None:
        try:
            if tail.exit(*exc):
                exc = (None, None, None)
        except:
            exc = sys.exc_info()

        tail = tail.old_contexts[1]

    return exc


def run_with_stack_context(context, func):
    """Run a coroutine ``func`` in the given `StackContext`.

    It is not safe to have a ``yield`` statement within a ``with StackContext``
    block, so it is difficult to use stack context with `.gen.coroutine`.
    This helper function runs the function in the correct context while
    keeping the ``yield`` and ``with`` statements syntactically separate.

    Example::

        @gen.coroutine
        def incorrect():
            with StackContext(ctx):
                # ERROR: this will raise StackContextInconsistentError
                yield other_coroutine()

        @gen.coroutine
        def correct():
            yield run_with_stack_context(StackContext(ctx), other_coroutine)
    """
    with context:
        return func()

```
--- END FILE ---

Please first localize the bug based on the issue statement, and then generate *SEARCH/REPLACE* edits to fix the issue.

Every *SEARCH/REPLACE* edit must use this format:
1. The file path
2. The start of search block: <<<<<<< SEARCH
3. A contiguous chunk of lines to search for in the existing source code
4. The dividing line: =======
5. The lines to replace into the source code
6. The end of the replace block: >>>>>>> REPLACE

Here is an example:

```python
### mathweb/flask/app.py
<<<<<<< SEARCH
from flask import Flask
=======
import math
from flask import Flask
>>>>>>> REPLACE
```
</solution>

Please note that the *SEARCH/REPLACE* edit REQUIRES PROPER INDENTATION. If you would like to add the line '        print(x)', you must fully write that out, with all those spaces before the code!
Wrap each *SEARCH/REPLACE* edit in a code block as shown in the example above. If you have multiple *SEARCH/REPLACE* edits, use a separate code block for each one.
[ISSUE]

**Title:** Wrapped functions return `None` when the outermost `stack_context` is deactivated

**Description:**
When the outermost `stack_context` is deactivated, functions wrapped by `StackContext` unexpectedly return `None` instead of their intended results. This behavior leads to loss of context information, causing parts of the application to malfunction when they rely on the returned context data.

**Example Code:**
```python
def check_contexts():
    # Intended to return the list of active contexts
    return list(self.active_contexts)

def make_wrapped_function():
    with NullContext():
        with StackContext(functools.partial(self.context, 'c0')) as c0, \
             StackContext(functools.partial(self.context, 'c1')) as c1, \
             StackContext(functools.partial(self.context, 'c2')) as c2:
            return wrap(check_contexts), [c0, c1, c2]

func, deactivate_callbacks = make_wrapped_function()
result = func()  # Expected: ['c0', 'c1', 'c2'], Actual: None
```

**Expected Behavior:**
Functions wrapped by `StackContext` should return their expected results (e.g., the list of active contexts) even after the outermost `stack_context` is deactivated.

**Actual Behavior:**
Wrapped functions return `None` instead of the expected list of active contexts when the outermost `stack_context` is deactivated.

[/ISSUE]
{
    "HTTPStackContextTest.test_stack_context": "PASSED",
    "StackContextTest.test_deactivate": "PASSED",
    "StackContextTest.test_deactivate_order": "PASSED",
    "StackContextTest.test_exit_library_context": "PASSED",
    "StackContextTest.test_isolation_empty": "PASSED",
    "StackContextTest.test_isolation_nonempty": "PASSED",
    "StackContextTest.test_run_with_stack_context": "PASSED",
    "StackContextTest.test_yield_in_with": "PASSED",
    "StackContextTest.test_yield_in_with_exception_stack_context": "PASSED",
    "StackContextTest.test_yield_outside_with": "PASSED",
    "StackContextTest.test_yield_outside_with_exception_stack_context": "PASSED"
}
diff --git a/tornado/stack_context.py b/tornado/stack_context.py
index 7e44beda..9ad31476 100644
--- a/tornado/stack_context.py
+++ b/tornado/stack_context.py
@@ -240,10 +240,11 @@ def _remove_deactivated(contexts):
     while ctx is not None:
         parent = ctx.old_contexts[1]
 
-        while parent is not None and not parent.active:
-            parent = parent.old_contexts[1]
-
+        while parent is not None:
+            if parent.active:
+                break
             ctx.old_contexts = parent.old_contexts
+            parent = parent.old_contexts[1]
 
         ctx = parent
 
@@ -267,6 +268,7 @@ def wrap(fn):
     cap_contexts = [_state.contexts]
 
     def wrapped(*args, **kwargs):
+        ret = None
         try:
             # Capture old state
             current_state = _state.contexts
@@ -298,7 +300,7 @@ def wrap(fn):
             # Execute callback if no exception happened while restoring state
             if top is None:
                 try:
-                    fn(*args, **kwargs)
+                    ret = fn(*args, **kwargs)
                 except:
                     exc = sys.exc_info()
                     top = contexts[1]
@@ -330,6 +332,7 @@ def wrap(fn):
                 raise_exc_info(exc)
         finally:
             _state.contexts = current_state
+        return ret
 
     wrapped._wrapped = True
     return wrapped

{"tornado/stack_context.py": "#!/usr/bin/env python\n#\n# Copyright 2010 Facebook\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may\n# not use this file except in compliance with the License. You may obtain\n# a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n# License for the specific language governing permissions and limitations\n# under the License.\n\n\"\"\"`StackContext` allows applications to maintain threadlocal-like state\nthat follows execution as it moves to other execution contexts.\n\nThe motivating examples are to eliminate the need for explicit\n``async_callback`` wrappers (as in `tornado.web.RequestHandler`), and to\nallow some additional context to be kept for logging.\n\nThis is slightly magic, but it's an extension of the idea that an\nexception handler is a kind of stack-local state and when that stack\nis suspended and resumed in a new context that state needs to be\npreserved.  `StackContext` shifts the burden of restoring that state\nfrom each call site (e.g.  wrapping each `.AsyncHTTPClient` callback\nin ``async_callback``) to the mechanisms that transfer control from\none context to another (e.g. `.AsyncHTTPClient` itself, `.IOLoop`,\nthread pools, etc).\n\nExample usage::\n\n    @contextlib.contextmanager\n    def die_on_error():\n        try:\n            yield\n        except Exception:\n            logging.error(\"exception in asynchronous operation\",exc_info=True)\n            sys.exit(1)\n\n    with StackContext(die_on_error):\n        # Any exception thrown here *or in callback and its desendents*\n        # will cause the process to exit instead of spinning endlessly\n        # in the ioloop.\n        http_client.fetch(url, callback)\n    ioloop.start()\n\nMost applications shouln't have to work with `StackContext` directly.\nHere are a few rules of thumb for when it's necessary:\n\n* If you're writing an asynchronous library that doesn't rely on a\n  stack_context-aware library like `tornado.ioloop` or `tornado.iostream`\n  (for example, if you're writing a thread pool), use\n  `.stack_context.wrap()` before any asynchronous operations to capture the\n  stack context from where the operation was started.\n\n* If you're writing an asynchronous library that has some shared\n  resources (such as a connection pool), create those shared resources\n  within a ``with stack_context.NullContext():`` block.  This will prevent\n  ``StackContexts`` from leaking from one request to another.\n\n* If you want to write something like an exception handler that will\n  persist across asynchronous calls, create a new `StackContext` (or\n  `ExceptionStackContext`), and make your asynchronous calls in a ``with``\n  block that references your `StackContext`.\n\"\"\"\n\nfrom __future__ import absolute_import, division, print_function, with_statement\n\nimport sys\nimport threading\nimport operator\n\nfrom tornado.util import raise_exc_info\n\n\nclass StackContextInconsistentError(Exception):\n    pass\n\n\nclass _State(threading.local):\n    def __init__(self):\n        self.contexts = (tuple(), None)\n_state = _State()\n\n\nclass StackContext(object):\n    \"\"\"Establishes the given context as a StackContext that will be transferred.\n\n    Note that the parameter is a callable that returns a context\n    manager, not the context itself.  That is, where for a\n    non-transferable context manager you would say::\n\n      with my_context():\n\n    StackContext takes the function itself rather than its result::\n\n      with StackContext(my_context):\n\n    The result of ``with StackContext() as cb:`` is a deactivation\n    callback.  Run this callback when the StackContext is no longer\n    needed to ensure that it is not propagated any further (note that\n    deactivating a context does not affect any instances of that\n    context that are currently pending).  This is an advanced feature\n    and not necessary in most applications.\n    \"\"\"\n    def __init__(self, context_factory):\n        self.context_factory = context_factory\n        self.contexts = []\n        self.active = True\n\n    def _deactivate(self):\n        self.active = False\n\n    # StackContext protocol\n    def enter(self):\n        context = self.context_factory()\n        self.contexts.append(context)\n        context.__enter__()\n\n    def exit(self, type, value, traceback):\n        context = self.contexts.pop()\n        context.__exit__(type, value, traceback)\n\n    # Note that some of this code is duplicated in ExceptionStackContext\n    # below.  ExceptionStackContext is more common and doesn't need\n    # the full generality of this class.\n    def __enter__(self):\n        self.old_contexts = _state.contexts\n        self.new_contexts = (self.old_contexts[0] + (self,), self)\n        _state.contexts = self.new_contexts\n\n        try:\n            self.enter()\n        except:\n            _state.contexts = self.old_contexts\n            raise\n\n        return self._deactivate\n\n    def __exit__(self, type, value, traceback):\n        try:\n            self.exit(type, value, traceback)\n        finally:\n            final_contexts = _state.contexts\n            _state.contexts = self.old_contexts\n\n            # Generator coroutines and with-statements with non-local\n            # effects interact badly.  Check here for signs of\n            # the stack getting out of sync.\n            # Note that this check comes after restoring _state.context\n            # so that if it fails things are left in a (relatively)\n            # consistent state.\n            if final_contexts is not self.new_contexts:\n                raise StackContextInconsistentError(\n                    'stack_context inconsistency (may be caused by yield '\n                    'within a \"with StackContext\" block)')\n\n            # Break up a reference to itself to allow for faster GC on CPython.\n            self.new_contexts = None\n\n\nclass ExceptionStackContext(object):\n    \"\"\"Specialization of StackContext for exception handling.\n\n    The supplied ``exception_handler`` function will be called in the\n    event of an uncaught exception in this context.  The semantics are\n    similar to a try/finally clause, and intended use cases are to log\n    an error, close a socket, or similar cleanup actions.  The\n    ``exc_info`` triple ``(type, value, traceback)`` will be passed to the\n    exception_handler function.\n\n    If the exception handler returns true, the exception will be\n    consumed and will not be propagated to other exception handlers.\n    \"\"\"\n    def __init__(self, exception_handler):\n        self.exception_handler = exception_handler\n        self.active = True\n\n    def _deactivate(self):\n        self.active = False\n\n    def exit(self, type, value, traceback):\n        if type is not None:\n            return self.exception_handler(type, value, traceback)\n\n    def __enter__(self):\n        self.old_contexts = _state.contexts\n        self.new_contexts = (self.old_contexts[0], self)\n        _state.contexts = self.new_contexts\n\n        return self._deactivate\n\n    def __exit__(self, type, value, traceback):\n        try:\n            if type is not None:\n                return self.exception_handler(type, value, traceback)\n        finally:\n            final_contexts = _state.contexts\n            _state.contexts = self.old_contexts\n\n            if final_contexts is not self.new_contexts:\n                raise StackContextInconsistentError(\n                    'stack_context inconsistency (may be caused by yield '\n                    'within a \"with StackContext\" block)')\n\n            # Break up a reference to itself to allow for faster GC on CPython.\n            self.new_contexts = None\n\n\nclass NullContext(object):\n    \"\"\"Resets the `StackContext`.\n\n    Useful when creating a shared resource on demand (e.g. an\n    `.AsyncHTTPClient`) where the stack that caused the creating is\n    not relevant to future operations.\n    \"\"\"\n    def __enter__(self):\n        self.old_contexts = _state.contexts\n        _state.contexts = (tuple(), None)\n\n    def __exit__(self, type, value, traceback):\n        _state.contexts = self.old_contexts\n\n\ndef _remove_deactivated(contexts):\n    \"\"\"Remove deactivated handlers from the chain\"\"\"\n    # Clean ctx handlers\n    stack_contexts = tuple([h for h in contexts[0] if h.active])\n\n    # Find new head\n    head = contexts[1]\n    while head is not None and not head.active:\n        head = head.old_contexts[1]\n\n    # Process chain\n    ctx = head\n    while ctx is not None:\n        parent = ctx.old_contexts[1]\n\n        while parent is not None and not parent.active:\n            parent = parent.old_contexts[1]\n\n            ctx.old_contexts = parent.old_contexts\n\n        ctx = parent\n\n    return (stack_contexts, head)\n\n\ndef wrap(fn):\n    \"\"\"Returns a callable object that will restore the current `StackContext`\n    when executed.\n\n    Use this whenever saving a callback to be executed later in a\n    different execution context (either in a different thread or\n    asynchronously in the same thread).\n    \"\"\"\n    # Check if function is already wrapped\n    if fn is None or hasattr(fn, '_wrapped'):\n        return fn\n\n    # Capture current stack head\n    # TODO: Any other better way to store contexts and update them in wrapped function?\n    cap_contexts = [_state.contexts]\n\n    def wrapped(*args, **kwargs):\n        try:\n            # Capture old state\n            current_state = _state.contexts\n\n            # Remove deactivated items\n            cap_contexts[0] = contexts = _remove_deactivated(cap_contexts[0])\n\n            # Force new state\n            _state.contexts = contexts\n\n            # Current exception\n            exc = (None, None, None)\n            top = None\n\n            # Apply stack contexts\n            last_ctx = 0\n            stack = contexts[0]\n\n            # Apply state\n            for n in stack:\n                try:\n                    n.enter()\n                    last_ctx += 1\n                except:\n                    # Exception happened. Record exception info and store top-most handler\n                    exc = sys.exc_info()\n                    top = n.old_contexts[1]\n\n            # Execute callback if no exception happened while restoring state\n            if top is None:\n                try:\n                    fn(*args, **kwargs)\n                except:\n                    exc = sys.exc_info()\n                    top = contexts[1]\n\n            # If there was exception, try to handle it by going through the exception chain\n            if top is not None:\n                exc = _handle_exception(top, exc)\n            else:\n                # Otherwise take shorter path and run stack contexts in reverse order\n                while last_ctx > 0:\n                    last_ctx -= 1\n                    c = stack[last_ctx]\n\n                    try:\n                        c.exit(*exc)\n                    except:\n                        exc = sys.exc_info()\n                        top = c.old_contexts[1]\n                        break\n                else:\n                    top = None\n\n                # If if exception happened while unrolling, take longer exception handler path\n                if top is not None:\n                    exc = _handle_exception(top, exc)\n\n            # If exception was not handled, raise it\n            if exc != (None, None, None):\n                raise_exc_info(exc)\n        finally:\n            _state.contexts = current_state\n\n    wrapped._wrapped = True\n    return wrapped\n\n\ndef _handle_exception(tail, exc):\n    while tail is not None:\n        try:\n            if tail.exit(*exc):\n                exc = (None, None, None)\n        except:\n            exc = sys.exc_info()\n\n        tail = tail.old_contexts[1]\n\n    return exc\n\n\ndef run_with_stack_context(context, func):\n    \"\"\"Run a coroutine ``func`` in the given `StackContext`.\n\n    It is not safe to have a ``yield`` statement within a ``with StackContext``\n    block, so it is difficult to use stack context with `.gen.coroutine`.\n    This helper function runs the function in the correct context while\n    keeping the ``yield`` and ``with`` statements syntactically separate.\n\n    Example::\n\n        @gen.coroutine\n        def incorrect():\n            with StackContext(ctx):\n                # ERROR: this will raise StackContextInconsistentError\n                yield other_coroutine()\n\n        @gen.coroutine\n        def correct():\n            yield run_with_stack_context(StackContext(ctx), other_coroutine)\n    \"\"\"\n    with context:\n        return func()\n"}
A user will ask you to solve a task. You should first draft your thinking process (inner monologue). Then, generate the solution.

Your response format must follow the template below:
<think>
Your thoughts or/and draft, like working through an exercise on scratch paper. Be as casual and as long as you want until you are confident to generate a correct solution.
</think>
<solution>
Final solution presented to the user.
</solution>
system
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ISSUE]

**Title:** Wrapped functions return `None` when the outermost `stack_context` is deactivated

**Description:**
When the outermost `stack_context` is deactivated, functions wrapped by `StackContext` unexpectedly return `None` instead of their intended results. This behavior leads to loss of context information, causing parts of the application to malfunction when they rely on the returned context data.

**Example Code:**
```python
def check_contexts():
    # Intended to return the list of active contexts
    return list(self.active_contexts)

def make_wrapped_function():
    with NullContext():
        with StackContext(functools.partial(self.context, 'c0')) as c0, \
             StackContext(functools.partial(self.context, 'c1')) as c1, \
             StackContext(functools.partial(self.context, 'c2')) as c2:
            return wrap(check_contexts), [c0, c1, c2]

func, deactivate_callbacks = make_wrapped_function()
result = func()  # Expected: ['c0', 'c1', 'c2'], Actual: None
```

**Expected Behavior:**
Functions wrapped by `StackContext` should return their expected results (e.g., the list of active contexts) even after the outermost `stack_context` is deactivated.

**Actual Behavior:**
Wrapped functions return `None` instead of the expected list of active contexts when the outermost `stack_context` is deactivated.

[/ISSUE]
--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.

--- BEGIN FILE ---
```
### tornado/stack_context.py
#!/usr/bin/env python
#
# Copyright 2010 Facebook
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

"""`StackContext` allows applications to maintain threadlocal-like state
that follows execution as it moves to other execution contexts.

The motivating examples are to eliminate the need for explicit
``async_callback`` wrappers (as in `tornado.web.RequestHandler`), and to
allow some additional context to be kept for logging.

This is slightly magic, but it's an extension of the idea that an
exception handler is a kind of stack-local state and when that stack
is suspended and resumed in a new context that state needs to be
preserved.  `StackContext` shifts the burden of restoring that state
from each call site (e.g.  wrapping each `.AsyncHTTPClient` callback
in ``async_callback``) to the mechanisms that transfer control from
one context to another (e.g. `.AsyncHTTPClient` itself, `.IOLoop`,
thread pools, etc).

Example usage::

    @contextlib.contextmanager
    def die_on_error():
        try:
            yield
        except Exception:
            logging.error("exception in asynchronous operation",exc_info=True)
            sys.exit(1)

    with StackContext(die_on_error):
        # Any exception thrown here *or in callback and its desendents*
        # will cause the process to exit instead of spinning endlessly
        # in the ioloop.
        http_client.fetch(url, callback)
    ioloop.start()

Most applications shouln't have to work with `StackContext` directly.
Here are a few rules of thumb for when it's necessary:

* If you're writing an asynchronous library that doesn't rely on a
  stack_context-aware library like `tornado.ioloop` or `tornado.iostream`
  (for example, if you're writing a thread pool), use
  `.stack_context.wrap()` before any asynchronous operations to capture the
  stack context from where the operation was started.

* If you're writing an asynchronous library that has some shared
  resources (such as a connection pool), create those shared resources
  within a ``with stack_context.NullContext():`` block.  This will prevent
  ``StackContexts`` from leaking from one request to another.

* If you want to write something like an exception handler that will
  persist across asynchronous calls, create a new `StackContext` (or
  `ExceptionStackContext`), and make your asynchronous calls in a ``with``
  block that references your `StackContext`.
"""

from __future__ import absolute_import, division, print_function, with_statement

import sys
import threading
import operator

from tornado.util import raise_exc_info


class StackContextInconsistentError(Exception):
    pass


class _State(threading.local):
    def __init__(self):
        self.contexts = (tuple(), None)
_state = _State()


class StackContext(object):
    """Establishes the given context as a StackContext that will be transferred.

    Note that the parameter is a callable that returns a context
    manager, not the context itself.  That is, where for a
    non-transferable context manager you would say::

      with my_context():

    StackContext takes the function itself rather than its result::

      with StackContext(my_context):

    The result of ``with StackContext() as cb:`` is a deactivation
    callback.  Run this callback when the StackContext is no longer
    needed to ensure that it is not propagated any further (note that
    deactivating a context does not affect any instances of that
    context that are currently pending).  This is an advanced feature
    and not necessary in most applications.
    """
    def __init__(self, context_factory):
        self.context_factory = context_factory
        self.contexts = []
        self.active = True

    def _deactivate(self):
        self.active = False

    # StackContext protocol
    def enter(self):
        context = self.context_factory()
        self.contexts.append(context)
        context.__enter__()

    def exit(self, type, value, traceback):
        context = self.contexts.pop()
        context.__exit__(type, value, traceback)

    # Note that some of this code is duplicated in ExceptionStackContext
    # below.  ExceptionStackContext is more common and doesn't need
    # the full generality of this class.
    def __enter__(self):
        self.old_contexts = _state.contexts
        self.new_contexts = (self.old_contexts[0] + (self,), self)
        _state.contexts = self.new_contexts

        try:
            self.enter()
        except:
            _state.contexts = self.old_contexts
            raise

        return self._deactivate

    def __exit__(self, type, value, traceback):
        try:
            self.exit(type, value, traceback)
        finally:
            final_contexts = _state.contexts
            _state.contexts = self.old_contexts

            # Generator coroutines and with-statements with non-local
            # effects interact badly.  Check here for signs of
            # the stack getting out of sync.
            # Note that this check comes after restoring _state.context
            # so that if it fails things are left in a (relatively)
            # consistent state.
            if final_contexts is not self.new_contexts:
                raise StackContextInconsistentError(
                    'stack_context inconsistency (may be caused by yield '
                    'within a "with StackContext" block)')

            # Break up a reference to itself to allow for faster GC on CPython.
            self.new_contexts = None


class ExceptionStackContext(object):
    """Specialization of StackContext for exception handling.

    The supplied ``exception_handler`` function will be called in the
    event of an uncaught exception in this context.  The semantics are
    similar to a try/finally clause, and intended use cases are to log
    an error, close a socket, or similar cleanup actions.  The
    ``exc_info`` triple ``(type, value, traceback)`` will be passed to the
    exception_handler function.

    If the exception handler returns true, the exception will be
    consumed and will not be propagated to other exception handlers.
    """
    def __init__(self, exception_handler):
        self.exception_handler = exception_handler
        self.active = True

    def _deactivate(self):
        self.active = False

    def exit(self, type, value, traceback):
        if type is not None:
            return self.exception_handler(type, value, traceback)

    def __enter__(self):
        self.old_contexts = _state.contexts
        self.new_contexts = (self.old_contexts[0], self)
        _state.contexts = self.new_contexts

        return self._deactivate

    def __exit__(self, type, value, traceback):
        try:
            if type is not None:
                return self.exception_handler(type, value, traceback)
        finally:
            final_contexts = _state.contexts
            _state.contexts = self.old_contexts

            if final_contexts is not self.new_contexts:
                raise StackContextInconsistentError(
                    'stack_context inconsistency (may be caused by yield '
                    'within a "with StackContext" block)')

            # Break up a reference to itself to allow for faster GC on CPython.
            self.new_contexts = None


class NullContext(object):
    """Resets the `StackContext`.

    Useful when creating a shared resource on demand (e.g. an
    `.AsyncHTTPClient`) where the stack that caused the creating is
    not relevant to future operations.
    """
    def __enter__(self):
        self.old_contexts = _state.contexts
        _state.contexts = (tuple(), None)

    def __exit__(self, type, value, traceback):
        _state.contexts = self.old_contexts


def _remove_deactivated(contexts):
    """Remove deactivated handlers from the chain"""
    # Clean ctx handlers
    stack_contexts = tuple([h for h in contexts[0] if h.active])

    # Find new head
    head = contexts[1]
    while head is not None and not head.active:
        head = head.old_contexts[1]

    # Process chain
    ctx = head
    while ctx is not None:
        parent = ctx.old_contexts[1]

        while parent is not None and not parent.active:
            parent = parent.old_contexts[1]

            ctx.old_contexts = parent.old_contexts

        ctx = parent

    return (stack_contexts, head)


def wrap(fn):
    """Returns a callable object that will restore the current `StackContext`
    when executed.

    Use this whenever saving a callback to be executed later in a
    different execution context (either in a different thread or
    asynchronously in the same thread).
    """
    # Check if function is already wrapped
    if fn is None or hasattr(fn, '_wrapped'):
        return fn

    # Capture current stack head
    # TODO: Any other better way to store contexts and update them in wrapped function?
    cap_contexts = [_state.contexts]

    def wrapped(*args, **kwargs):
        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:
                    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

    wrapped._wrapped = True
    return wrapped


def _handle_exception(tail, exc):
    while tail is not None:
        try:
            if tail.exit(*exc):
                exc = (None, None, None)
        except:
            exc = sys.exc_info()

        tail = tail.old_contexts[1]

    return exc


def run_with_stack_context(context, func):
    """Run a coroutine ``func`` in the given `StackContext`.

    It is not safe to have a ``yield`` statement within a ``with StackContext``
    block, so it is difficult to use stack context with `.gen.coroutine`.
    This helper function runs the function in the correct context while
    keeping the ``yield`` and ``with`` statements syntactically separate.

    Example::

        @gen.coroutine
        def incorrect():
            with StackContext(ctx):
                # ERROR: this will raise StackContextInconsistentError
                yield other_coroutine()

        @gen.coroutine
        def correct():
            yield run_with_stack_context(StackContext(ctx), other_coroutine)
    """
    with context:
        return func()

```
--- END FILE ---

Please first localize the bug based on the issue statement, and then generate *SEARCH/REPLACE* edits to fix the issue.

Every *SEARCH/REPLACE* edit must use this format:
1. The file path
2. The start of search block: <<<<<<< SEARCH
3. A contiguous chunk of lines to search for in the existing source code
4. The dividing line: =======
5. The lines to replace into the source code
6. The end of the replace block: >>>>>>> REPLACE

Here is an example:

```python
### mathweb/flask/app.py
<<<<<<< SEARCH
from flask import Flask
=======
import math
from flask import Flask
>>>>>>> REPLACE
```
</solution>

Please note that the *SEARCH/REPLACE* edit REQUIRES PROPER INDENTATION. If you would like to add the line '        print(x)', you must fully write that out, with all those spaces before the code!
Wrap each *SEARCH/REPLACE* edit in a code block as shown in the example above. If you have multiple *SEARCH/REPLACE* edits, use a separate code block for each one.
user