{
    "file_diffs": [
        {
            "old_file_content": "import asyncio\nimport concurrent.futures\nimport threading\n\nfrom wsgiref.validate import validator\n\nfrom tornado.routing import RuleRouter\nfrom tornado.testing import AsyncHTTPTestCase, gen_test\nfrom tornado.wsgi import WSGIContainer\n\n\nclass WSGIAppMixin:\n    # TODO: Now that WSGIAdapter is gone, this is a pretty weak test.\n    def get_executor(self):\n        raise NotImplementedError()\n\n    def get_app(self):\n        executor = self.get_executor()\n        # The barrier test in DummyExecutorTest will always wait the full\n        # value of this timeout, so we don't want it to be too high.\n        self.barrier = threading.Barrier(2, timeout=0.3)\n\n        def make_container(app):\n            return WSGIContainer(validator(app), executor=executor)\n\n        return RuleRouter(\n            [\n                (\"/simple\", make_container(self.simple_wsgi_app)),\n                (\"/barrier\", make_container(self.barrier_wsgi_app)),\n            ]\n        )\n\n    def respond_plain(self, start_response):\n        status = \"200 OK\"\n        response_headers = [(\"Content-Type\", \"text/plain\")]\n        start_response(status, response_headers)\n\n    def simple_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        return [b\"Hello world!\"]\n\n    def test_simple(self):\n        response = self.fetch(\"/simple\")\n        self.assertEqual(response.body, b\"Hello world!\")\n\n    def barrier_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        try:\n            n = self.barrier.wait()\n        except threading.BrokenBarrierError:\n            return [b\"broken barrier\"]\n        else:\n            return [b\"ok %d\" % n]\n\n\nclass WSGIContainerDummyExecutorTest(WSGIAppMixin, AsyncHTTPTestCase):\n    def get_executor(self):\n        return None\n\n    @gen_test\n    async def test_concurrent_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n        )\n        for resp in resps:\n            self.assertEqual(resp.body, b\"broken barrier\")\n\n\nclass WSGIContainerThreadPoolTest(WSGIAppMixin, AsyncHTTPTestCase):\n    def get_executor(self):\n        return concurrent.futures.ThreadPoolExecutor()\n\n    @gen_test\n    async def test_concurrent_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n        )\n        self.assertEqual([b\"ok 0\", b\"ok 1\"], sorted([resp.body for resp in resps]))\n",
            "new_file_content": "import asyncio\nimport concurrent.futures\nimport threading\n\nfrom wsgiref.validate import validator\n\nfrom tornado.routing import RuleRouter\nfrom tornado.testing import AsyncHTTPTestCase, gen_test\nfrom tornado.wsgi import WSGIContainer\n\n\nclass WSGIAppMixin:\n    # TODO: Now that WSGIAdapter is gone, this is a pretty weak test.\n    def get_executor(self):\n        raise NotImplementedError()\n\n    def get_app(self):\n        executor = self.get_executor()\n        # The barrier test in DummyExecutorTest will always wait the full\n        # value of this timeout, so we don't want it to be too high.\n        self.barrier = threading.Barrier(2, timeout=0.3)\n\n        def make_container(app):\n            return WSGIContainer(validator(app), executor=executor)\n\n        return RuleRouter(\n            [\n                (\"/simple\", make_container(self.simple_wsgi_app)),\n                (\"/barrier\", make_container(self.barrier_wsgi_app)),\n                (\"/streaming_barrier\", make_container(self.streaming_barrier_wsgi_app)),\n            ]\n        )\n\n    def respond_plain(self, start_response):\n        status = \"200 OK\"\n        response_headers = [(\"Content-Type\", \"text/plain\")]\n        start_response(status, response_headers)\n\n    def simple_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        return [b\"Hello world!\"]\n\n    def barrier_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        try:\n            n = self.barrier.wait()\n        except threading.BrokenBarrierError:\n            return [b\"broken barrier\"]\n        else:\n            return [b\"ok %d\" % n]\n\n    def streaming_barrier_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        yield b\"ok \"\n        try:\n            n = self.barrier.wait()\n        except threading.BrokenBarrierError:\n            yield b\"broken barrier\"\n        else:\n            yield b\"%d\" % n\n\n\nclass WSGIContainerDummyExecutorTest(WSGIAppMixin, AsyncHTTPTestCase):\n    def get_executor(self):\n        return None\n\n    def test_simple(self):\n        response = self.fetch(\"/simple\")\n        self.assertEqual(response.body, b\"Hello world!\")\n\n    @gen_test\n    async def test_concurrent_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n        )\n        for resp in resps:\n            self.assertEqual(resp.body, b\"broken barrier\")\n\n    @gen_test\n    async def test_concurrent_streaming_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n        )\n        for resp in resps:\n            self.assertEqual(resp.body, b\"ok broken barrier\")\n\n\nclass WSGIContainerThreadPoolTest(WSGIAppMixin, AsyncHTTPTestCase):\n    def get_executor(self):\n        return concurrent.futures.ThreadPoolExecutor()\n\n    def test_simple(self):\n        response = self.fetch(\"/simple\")\n        self.assertEqual(response.body, b\"Hello world!\")\n\n    @gen_test\n    async def test_concurrent_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n        )\n        self.assertEqual([b\"ok 0\", b\"ok 1\"], sorted([resp.body for resp in resps]))\n\n    @gen_test\n    async def test_concurrent_streaming_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n        )\n        self.assertEqual([b\"ok 0\", b\"ok 1\"], sorted([resp.body for resp in resps]))\n",
            "header": {
                "file": {
                    "path": "tornado/test/wsgi_test.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "26862092",
                "new_commit_hash": "9fbc744e",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/tornado/test/wsgi_test.py"
            },
            "plus_file": {
                "path": "b/tornado/test/wsgi_test.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 27,
                            "length": 6
                        },
                        "new_range": {
                            "start": 27,
                            "length": 7
                        },
                        "section": "class WSGIAppMixin:"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "            [",
                                "type": "context"
                            },
                            {
                                "content": "                (\"/simple\", make_container(self.simple_wsgi_app)),",
                                "type": "context"
                            },
                            {
                                "content": "                (\"/barrier\", make_container(self.barrier_wsgi_app)),",
                                "type": "context"
                            },
                            {
                                "content": "                (\"/streaming_barrier\", make_container(self.streaming_barrier_wsgi_app)),",
                                "type": "added"
                            },
                            {
                                "content": "            ]",
                                "type": "context"
                            },
                            {
                                "content": "        )",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/test/wsgi_test.py",
                            "type": "method",
                            "name": "WSGIAppMixin.get_app",
                            "content": "class WSGIAppMixin:\n    # TODO: Now that WSGIAdapter is gone, this is a pretty weak test.\n    def get_executor(self):\n        raise NotImplementedError()\n\n    def get_app(self):\n        executor = self.get_executor()\n        # The barrier test in DummyExecutorTest will always wait the full\n        # value of this timeout, so we don't want it to be too high.\n        self.barrier = threading.Barrier(2, timeout=0.3)\n\n        def make_container(app):\n            return WSGIContainer(validator(app), executor=executor)\n\n        return RuleRouter(\n            [\n                (\"/simple\", make_container(self.simple_wsgi_app)),\n                (\"/barrier\", make_container(self.barrier_wsgi_app)),\n                (\"/streaming_barrier\", make_container(self.streaming_barrier_wsgi_app)),\n            ]\n        )\n\n    def respond_plain(self, start_response):\n        status = \"200 OK\"\n        response_headers = [(\"Content-Type\", \"text/plain\")]\n        start_response(status, response_headers)\n\n    def simple_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        return [b\"Hello world!\"]\n\n    def barrier_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        try:\n            n = self.barrier.wait()\n        except threading.BrokenBarrierError:\n            return [b\"broken barrier\"]\n        else:\n            return [b\"ok %d\" % n]\n\n    def streaming_barrier_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        yield b\"ok \"\n        try:\n            n = self.barrier.wait()\n        except threading.BrokenBarrierError:\n            yield b\"broken barrier\"\n        else:\n            yield b\"%d\" % n",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 17,
                            "end_lineno": 32,
                            "parent": {
                                "file_name": "tornado/test/wsgi_test.py",
                                "type": "class",
                                "name": "WSGIAppMixin",
                                "content": "class WSGIAppMixin:\n    # TODO: Now that WSGIAdapter is gone, this is a pretty weak test.\n    def get_executor(self):\n        raise NotImplementedError()\n\n    def get_app(self):\n        executor = self.get_executor()\n        # The barrier test in DummyExecutorTest will always wait the full\n        # value of this timeout, so we don't want it to be too high.\n        self.barrier = threading.Barrier(2, timeout=0.3)\n\n        def make_container(app):\n            return WSGIContainer(validator(app), executor=executor)\n\n        return RuleRouter(\n            [\n                (\"/simple\", make_container(self.simple_wsgi_app)),\n                (\"/barrier\", make_container(self.barrier_wsgi_app)),\n                (\"/streaming_barrier\", make_container(self.streaming_barrier_wsgi_app)),\n            ]\n        )\n\n    def respond_plain(self, start_response):\n        status = \"200 OK\"\n        response_headers = [(\"Content-Type\", \"text/plain\")]\n        start_response(status, response_headers)\n\n    def simple_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        return [b\"Hello world!\"]\n\n    def barrier_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        try:\n            n = self.barrier.wait()\n        except threading.BrokenBarrierError:\n            return [b\"broken barrier\"]\n        else:\n            return [b\"ok %d\" % n]\n\n    def streaming_barrier_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        yield b\"ok \"\n        try:\n            n = self.barrier.wait()\n        except threading.BrokenBarrierError:\n            yield b\"broken barrier\"\n        else:\n            yield b\"%d\" % n",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 12,
                                "end_lineno": 60,
                                "parent": null
                            }
                        },
                        {
                            "file_name": "tornado/test/wsgi_test.py",
                            "type": "class",
                            "name": "WSGIAppMixin",
                            "content": "class WSGIAppMixin:\n    # TODO: Now that WSGIAdapter is gone, this is a pretty weak test.\n    def get_executor(self):\n        raise NotImplementedError()\n\n    def get_app(self):\n        executor = self.get_executor()\n        # The barrier test in DummyExecutorTest will always wait the full\n        # value of this timeout, so we don't want it to be too high.\n        self.barrier = threading.Barrier(2, timeout=0.3)\n\n        def make_container(app):\n            return WSGIContainer(validator(app), executor=executor)\n\n        return RuleRouter(\n            [\n                (\"/simple\", make_container(self.simple_wsgi_app)),\n                (\"/barrier\", make_container(self.barrier_wsgi_app)),\n                (\"/streaming_barrier\", make_container(self.streaming_barrier_wsgi_app)),\n            ]\n        )\n\n    def respond_plain(self, start_response):\n        status = \"200 OK\"\n        response_headers = [(\"Content-Type\", \"text/plain\")]\n        start_response(status, response_headers)\n\n    def simple_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        return [b\"Hello world!\"]\n\n    def barrier_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        try:\n            n = self.barrier.wait()\n        except threading.BrokenBarrierError:\n            return [b\"broken barrier\"]\n        else:\n            return [b\"ok %d\" % n]\n\n    def streaming_barrier_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        yield b\"ok \"\n        try:\n            n = self.barrier.wait()\n        except threading.BrokenBarrierError:\n            yield b\"broken barrier\"\n        else:\n            yield b\"%d\" % n",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 12,
                            "end_lineno": 60,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 39,
                            "length": 10
                        },
                        "new_range": {
                            "start": 40,
                            "length": 6
                        },
                        "section": "class WSGIAppMixin:"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        self.respond_plain(start_response)",
                                "type": "context"
                            },
                            {
                                "content": "        return [b\"Hello world!\"]",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def test_simple(self):",
                                "type": "deleted"
                            },
                            {
                                "content": "        response = self.fetch(\"/simple\")",
                                "type": "deleted"
                            },
                            {
                                "content": "        self.assertEqual(response.body, b\"Hello world!\")",
                                "type": "deleted"
                            },
                            {
                                "content": "",
                                "type": "deleted"
                            },
                            {
                                "content": "    def barrier_wsgi_app(self, environ, start_response):",
                                "type": "context"
                            },
                            {
                                "content": "        self.respond_plain(start_response)",
                                "type": "context"
                            },
                            {
                                "content": "        try:",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/test/wsgi_test.py",
                            "type": "class",
                            "name": "WSGIAppMixin",
                            "content": "class WSGIAppMixin:\n    # TODO: Now that WSGIAdapter is gone, this is a pretty weak test.\n    def get_executor(self):\n        raise NotImplementedError()\n\n    def get_app(self):\n        executor = self.get_executor()\n        # The barrier test in DummyExecutorTest will always wait the full\n        # value of this timeout, so we don't want it to be too high.\n        self.barrier = threading.Barrier(2, timeout=0.3)\n\n        def make_container(app):\n            return WSGIContainer(validator(app), executor=executor)\n\n        return RuleRouter(\n            [\n                (\"/simple\", make_container(self.simple_wsgi_app)),\n                (\"/barrier\", make_container(self.barrier_wsgi_app)),\n            ]\n        )\n\n    def respond_plain(self, start_response):\n        status = \"200 OK\"\n        response_headers = [(\"Content-Type\", \"text/plain\")]\n        start_response(status, response_headers)\n\n    def simple_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        return [b\"Hello world!\"]\n\n    def test_simple(self):\n        response = self.fetch(\"/simple\")\n        self.assertEqual(response.body, b\"Hello world!\")\n\n    def barrier_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        try:\n            n = self.barrier.wait()\n        except threading.BrokenBarrierError:\n            return [b\"broken barrier\"]\n        else:\n            return [b\"ok %d\" % n]",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 12,
                            "end_lineno": 53,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": [
                        {
                            "file_name": "tornado/test/wsgi_test.py",
                            "type": "method",
                            "name": "WSGIAppMixin.test_simple",
                            "content": "class WSGIAppMixin:\n    # TODO: Now that WSGIAdapter is gone, this is a pretty weak test.\n    def get_executor(self):\n        raise NotImplementedError()\n\n    def get_app(self):\n        executor = self.get_executor()\n        # The barrier test in DummyExecutorTest will always wait the full\n        # value of this timeout, so we don't want it to be too high.\n        self.barrier = threading.Barrier(2, timeout=0.3)\n\n        def make_container(app):\n            return WSGIContainer(validator(app), executor=executor)\n\n        return RuleRouter(\n            [\n                (\"/simple\", make_container(self.simple_wsgi_app)),\n                (\"/barrier\", make_container(self.barrier_wsgi_app)),\n            ]\n        )\n\n    def respond_plain(self, start_response):\n        status = \"200 OK\"\n        response_headers = [(\"Content-Type\", \"text/plain\")]\n        start_response(status, response_headers)\n\n    def simple_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        return [b\"Hello world!\"]\n\n    def test_simple(self):\n        response = self.fetch(\"/simple\")\n        self.assertEqual(response.body, b\"Hello world!\")\n\n    def barrier_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        try:\n            n = self.barrier.wait()\n        except threading.BrokenBarrierError:\n            return [b\"broken barrier\"]\n        else:\n            return [b\"ok %d\" % n]",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 42,
                            "end_lineno": 44,
                            "parent": {
                                "file_name": "tornado/test/wsgi_test.py",
                                "type": "class",
                                "name": "WSGIAppMixin",
                                "content": "class WSGIAppMixin:\n    # TODO: Now that WSGIAdapter is gone, this is a pretty weak test.\n    def get_executor(self):\n        raise NotImplementedError()\n\n    def get_app(self):\n        executor = self.get_executor()\n        # The barrier test in DummyExecutorTest will always wait the full\n        # value of this timeout, so we don't want it to be too high.\n        self.barrier = threading.Barrier(2, timeout=0.3)\n\n        def make_container(app):\n            return WSGIContainer(validator(app), executor=executor)\n\n        return RuleRouter(\n            [\n                (\"/simple\", make_container(self.simple_wsgi_app)),\n                (\"/barrier\", make_container(self.barrier_wsgi_app)),\n            ]\n        )\n\n    def respond_plain(self, start_response):\n        status = \"200 OK\"\n        response_headers = [(\"Content-Type\", \"text/plain\")]\n        start_response(status, response_headers)\n\n    def simple_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        return [b\"Hello world!\"]\n\n    def test_simple(self):\n        response = self.fetch(\"/simple\")\n        self.assertEqual(response.body, b\"Hello world!\")\n\n    def barrier_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        try:\n            n = self.barrier.wait()\n        except threading.BrokenBarrierError:\n            return [b\"broken barrier\"]\n        else:\n            return [b\"ok %d\" % n]",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 12,
                                "end_lineno": 53,
                                "parent": null
                            }
                        }
                    ]
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 52,
                            "length": 11
                        },
                        "new_range": {
                            "start": 49,
                            "length": 25
                        },
                        "section": "class WSGIAppMixin:"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        else:",
                                "type": "context"
                            },
                            {
                                "content": "            return [b\"ok %d\" % n]",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def streaming_barrier_wsgi_app(self, environ, start_response):",
                                "type": "added"
                            },
                            {
                                "content": "        self.respond_plain(start_response)",
                                "type": "added"
                            },
                            {
                                "content": "        yield b\"ok \"",
                                "type": "added"
                            },
                            {
                                "content": "        try:",
                                "type": "added"
                            },
                            {
                                "content": "            n = self.barrier.wait()",
                                "type": "added"
                            },
                            {
                                "content": "        except threading.BrokenBarrierError:",
                                "type": "added"
                            },
                            {
                                "content": "            yield b\"broken barrier\"",
                                "type": "added"
                            },
                            {
                                "content": "        else:",
                                "type": "added"
                            },
                            {
                                "content": "            yield b\"%d\" % n",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "class WSGIContainerDummyExecutorTest(WSGIAppMixin, AsyncHTTPTestCase):",
                                "type": "context"
                            },
                            {
                                "content": "    def get_executor(self):",
                                "type": "context"
                            },
                            {
                                "content": "        return None",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def test_simple(self):",
                                "type": "added"
                            },
                            {
                                "content": "        response = self.fetch(\"/simple\")",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertEqual(response.body, b\"Hello world!\")",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    @gen_test",
                                "type": "context"
                            },
                            {
                                "content": "    async def test_concurrent_barrier(self):",
                                "type": "context"
                            },
                            {
                                "content": "        self.barrier.reset()",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/test/wsgi_test.py",
                            "type": "class",
                            "name": "WSGIContainerDummyExecutorTest",
                            "content": "class WSGIContainerDummyExecutorTest(WSGIAppMixin, AsyncHTTPTestCase):\n    def get_executor(self):\n        return None\n\n    def test_simple(self):\n        response = self.fetch(\"/simple\")\n        self.assertEqual(response.body, b\"Hello world!\")\n\n    @gen_test\n    async def test_concurrent_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n        )\n        for resp in resps:\n            self.assertEqual(resp.body, b\"broken barrier\")\n\n    @gen_test\n    async def test_concurrent_streaming_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n        )\n        for resp in resps:\n            self.assertEqual(resp.body, b\"ok broken barrier\")",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 63,
                            "end_lineno": 89,
                            "parent": null
                        },
                        {
                            "file_name": "tornado/test/wsgi_test.py",
                            "type": "class",
                            "name": "WSGIAppMixin",
                            "content": "class WSGIAppMixin:\n    # TODO: Now that WSGIAdapter is gone, this is a pretty weak test.\n    def get_executor(self):\n        raise NotImplementedError()\n\n    def get_app(self):\n        executor = self.get_executor()\n        # The barrier test in DummyExecutorTest will always wait the full\n        # value of this timeout, so we don't want it to be too high.\n        self.barrier = threading.Barrier(2, timeout=0.3)\n\n        def make_container(app):\n            return WSGIContainer(validator(app), executor=executor)\n\n        return RuleRouter(\n            [\n                (\"/simple\", make_container(self.simple_wsgi_app)),\n                (\"/barrier\", make_container(self.barrier_wsgi_app)),\n                (\"/streaming_barrier\", make_container(self.streaming_barrier_wsgi_app)),\n            ]\n        )\n\n    def respond_plain(self, start_response):\n        status = \"200 OK\"\n        response_headers = [(\"Content-Type\", \"text/plain\")]\n        start_response(status, response_headers)\n\n    def simple_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        return [b\"Hello world!\"]\n\n    def barrier_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        try:\n            n = self.barrier.wait()\n        except threading.BrokenBarrierError:\n            return [b\"broken barrier\"]\n        else:\n            return [b\"ok %d\" % n]\n\n    def streaming_barrier_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        yield b\"ok \"\n        try:\n            n = self.barrier.wait()\n        except threading.BrokenBarrierError:\n            yield b\"broken barrier\"\n        else:\n            yield b\"%d\" % n",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 12,
                            "end_lineno": 60,
                            "parent": null
                        }
                    ],
                    "added_entities": [
                        {
                            "file_name": "tornado/test/wsgi_test.py",
                            "type": "method",
                            "name": "WSGIContainerDummyExecutorTest.test_simple",
                            "content": "class WSGIContainerDummyExecutorTest(WSGIAppMixin, AsyncHTTPTestCase):\n    def get_executor(self):\n        return None\n\n    def test_simple(self):\n        response = self.fetch(\"/simple\")\n        self.assertEqual(response.body, b\"Hello world!\")\n\n    @gen_test\n    async def test_concurrent_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n        )\n        for resp in resps:\n            self.assertEqual(resp.body, b\"broken barrier\")\n\n    @gen_test\n    async def test_concurrent_streaming_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n        )\n        for resp in resps:\n            self.assertEqual(resp.body, b\"ok broken barrier\")",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 67,
                            "end_lineno": 69,
                            "parent": {
                                "file_name": "tornado/test/wsgi_test.py",
                                "type": "class",
                                "name": "WSGIContainerDummyExecutorTest",
                                "content": "class WSGIContainerDummyExecutorTest(WSGIAppMixin, AsyncHTTPTestCase):\n    def get_executor(self):\n        return None\n\n    def test_simple(self):\n        response = self.fetch(\"/simple\")\n        self.assertEqual(response.body, b\"Hello world!\")\n\n    @gen_test\n    async def test_concurrent_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n        )\n        for resp in resps:\n            self.assertEqual(resp.body, b\"broken barrier\")\n\n    @gen_test\n    async def test_concurrent_streaming_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n        )\n        for resp in resps:\n            self.assertEqual(resp.body, b\"ok broken barrier\")",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 63,
                                "end_lineno": 89,
                                "parent": null
                            }
                        },
                        {
                            "file_name": "tornado/test/wsgi_test.py",
                            "type": "method",
                            "name": "WSGIAppMixin.streaming_barrier_wsgi_app",
                            "content": "class WSGIAppMixin:\n    # TODO: Now that WSGIAdapter is gone, this is a pretty weak test.\n    def get_executor(self):\n        raise NotImplementedError()\n\n    def get_app(self):\n        executor = self.get_executor()\n        # The barrier test in DummyExecutorTest will always wait the full\n        # value of this timeout, so we don't want it to be too high.\n        self.barrier = threading.Barrier(2, timeout=0.3)\n\n        def make_container(app):\n            return WSGIContainer(validator(app), executor=executor)\n\n        return RuleRouter(\n            [\n                (\"/simple\", make_container(self.simple_wsgi_app)),\n                (\"/barrier\", make_container(self.barrier_wsgi_app)),\n                (\"/streaming_barrier\", make_container(self.streaming_barrier_wsgi_app)),\n            ]\n        )\n\n    def respond_plain(self, start_response):\n        status = \"200 OK\"\n        response_headers = [(\"Content-Type\", \"text/plain\")]\n        start_response(status, response_headers)\n\n    def simple_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        return [b\"Hello world!\"]\n\n    def barrier_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        try:\n            n = self.barrier.wait()\n        except threading.BrokenBarrierError:\n            return [b\"broken barrier\"]\n        else:\n            return [b\"ok %d\" % n]\n\n    def streaming_barrier_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        yield b\"ok \"\n        try:\n            n = self.barrier.wait()\n        except threading.BrokenBarrierError:\n            yield b\"broken barrier\"\n        else:\n            yield b\"%d\" % n",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 52,
                            "end_lineno": 60,
                            "parent": {
                                "file_name": "tornado/test/wsgi_test.py",
                                "type": "class",
                                "name": "WSGIAppMixin",
                                "content": "class WSGIAppMixin:\n    # TODO: Now that WSGIAdapter is gone, this is a pretty weak test.\n    def get_executor(self):\n        raise NotImplementedError()\n\n    def get_app(self):\n        executor = self.get_executor()\n        # The barrier test in DummyExecutorTest will always wait the full\n        # value of this timeout, so we don't want it to be too high.\n        self.barrier = threading.Barrier(2, timeout=0.3)\n\n        def make_container(app):\n            return WSGIContainer(validator(app), executor=executor)\n\n        return RuleRouter(\n            [\n                (\"/simple\", make_container(self.simple_wsgi_app)),\n                (\"/barrier\", make_container(self.barrier_wsgi_app)),\n                (\"/streaming_barrier\", make_container(self.streaming_barrier_wsgi_app)),\n            ]\n        )\n\n    def respond_plain(self, start_response):\n        status = \"200 OK\"\n        response_headers = [(\"Content-Type\", \"text/plain\")]\n        start_response(status, response_headers)\n\n    def simple_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        return [b\"Hello world!\"]\n\n    def barrier_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        try:\n            n = self.barrier.wait()\n        except threading.BrokenBarrierError:\n            return [b\"broken barrier\"]\n        else:\n            return [b\"ok %d\" % n]\n\n    def streaming_barrier_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        yield b\"ok \"\n        try:\n            n = self.barrier.wait()\n        except threading.BrokenBarrierError:\n            yield b\"broken barrier\"\n        else:\n            yield b\"%d\" % n",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 12,
                                "end_lineno": 60,
                                "parent": null
                            }
                        }
                    ],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 67,
                            "length": 11
                        },
                        "new_range": {
                            "start": 78,
                            "length": 25
                        },
                        "section": "class WSGIContainerDummyExecutorTest(WSGIAppMixin, AsyncHTTPTestCase):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        for resp in resps:",
                                "type": "context"
                            },
                            {
                                "content": "            self.assertEqual(resp.body, b\"broken barrier\")",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    @gen_test",
                                "type": "added"
                            },
                            {
                                "content": "    async def test_concurrent_streaming_barrier(self):",
                                "type": "added"
                            },
                            {
                                "content": "        self.barrier.reset()",
                                "type": "added"
                            },
                            {
                                "content": "        resps = await asyncio.gather(",
                                "type": "added"
                            },
                            {
                                "content": "            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),",
                                "type": "added"
                            },
                            {
                                "content": "            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),",
                                "type": "added"
                            },
                            {
                                "content": "        )",
                                "type": "added"
                            },
                            {
                                "content": "        for resp in resps:",
                                "type": "added"
                            },
                            {
                                "content": "            self.assertEqual(resp.body, b\"ok broken barrier\")",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "class WSGIContainerThreadPoolTest(WSGIAppMixin, AsyncHTTPTestCase):",
                                "type": "context"
                            },
                            {
                                "content": "    def get_executor(self):",
                                "type": "context"
                            },
                            {
                                "content": "        return concurrent.futures.ThreadPoolExecutor()",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def test_simple(self):",
                                "type": "added"
                            },
                            {
                                "content": "        response = self.fetch(\"/simple\")",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertEqual(response.body, b\"Hello world!\")",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    @gen_test",
                                "type": "context"
                            },
                            {
                                "content": "    async def test_concurrent_barrier(self):",
                                "type": "context"
                            },
                            {
                                "content": "        self.barrier.reset()",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/test/wsgi_test.py",
                            "type": "class",
                            "name": "WSGIContainerThreadPoolTest",
                            "content": "class WSGIContainerThreadPoolTest(WSGIAppMixin, AsyncHTTPTestCase):\n    def get_executor(self):\n        return concurrent.futures.ThreadPoolExecutor()\n\n    def test_simple(self):\n        response = self.fetch(\"/simple\")\n        self.assertEqual(response.body, b\"Hello world!\")\n\n    @gen_test\n    async def test_concurrent_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n        )\n        self.assertEqual([b\"ok 0\", b\"ok 1\"], sorted([resp.body for resp in resps]))\n\n    @gen_test\n    async def test_concurrent_streaming_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n        )\n        self.assertEqual([b\"ok 0\", b\"ok 1\"], sorted([resp.body for resp in resps]))",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 92,
                            "end_lineno": 116,
                            "parent": null
                        },
                        {
                            "file_name": "tornado/test/wsgi_test.py",
                            "type": "class",
                            "name": "WSGIContainerDummyExecutorTest",
                            "content": "class WSGIContainerDummyExecutorTest(WSGIAppMixin, AsyncHTTPTestCase):\n    def get_executor(self):\n        return None\n\n    def test_simple(self):\n        response = self.fetch(\"/simple\")\n        self.assertEqual(response.body, b\"Hello world!\")\n\n    @gen_test\n    async def test_concurrent_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n        )\n        for resp in resps:\n            self.assertEqual(resp.body, b\"broken barrier\")\n\n    @gen_test\n    async def test_concurrent_streaming_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n        )\n        for resp in resps:\n            self.assertEqual(resp.body, b\"ok broken barrier\")",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 63,
                            "end_lineno": 89,
                            "parent": null
                        }
                    ],
                    "added_entities": [
                        {
                            "file_name": "tornado/test/wsgi_test.py",
                            "type": "method",
                            "name": "WSGIContainerThreadPoolTest.test_simple",
                            "content": "class WSGIContainerThreadPoolTest(WSGIAppMixin, AsyncHTTPTestCase):\n    def get_executor(self):\n        return concurrent.futures.ThreadPoolExecutor()\n\n    def test_simple(self):\n        response = self.fetch(\"/simple\")\n        self.assertEqual(response.body, b\"Hello world!\")\n\n    @gen_test\n    async def test_concurrent_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n        )\n        self.assertEqual([b\"ok 0\", b\"ok 1\"], sorted([resp.body for resp in resps]))\n\n    @gen_test\n    async def test_concurrent_streaming_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n        )\n        self.assertEqual([b\"ok 0\", b\"ok 1\"], sorted([resp.body for resp in resps]))",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 96,
                            "end_lineno": 98,
                            "parent": {
                                "file_name": "tornado/test/wsgi_test.py",
                                "type": "class",
                                "name": "WSGIContainerThreadPoolTest",
                                "content": "class WSGIContainerThreadPoolTest(WSGIAppMixin, AsyncHTTPTestCase):\n    def get_executor(self):\n        return concurrent.futures.ThreadPoolExecutor()\n\n    def test_simple(self):\n        response = self.fetch(\"/simple\")\n        self.assertEqual(response.body, b\"Hello world!\")\n\n    @gen_test\n    async def test_concurrent_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n        )\n        self.assertEqual([b\"ok 0\", b\"ok 1\"], sorted([resp.body for resp in resps]))\n\n    @gen_test\n    async def test_concurrent_streaming_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n        )\n        self.assertEqual([b\"ok 0\", b\"ok 1\"], sorted([resp.body for resp in resps]))",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 92,
                                "end_lineno": 116,
                                "parent": null
                            }
                        },
                        {
                            "file_name": "tornado/test/wsgi_test.py",
                            "type": "method",
                            "name": "WSGIContainerDummyExecutorTest.test_concurrent_streaming_barrier",
                            "content": "class WSGIContainerDummyExecutorTest(WSGIAppMixin, AsyncHTTPTestCase):\n    def get_executor(self):\n        return None\n\n    def test_simple(self):\n        response = self.fetch(\"/simple\")\n        self.assertEqual(response.body, b\"Hello world!\")\n\n    @gen_test\n    async def test_concurrent_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n        )\n        for resp in resps:\n            self.assertEqual(resp.body, b\"broken barrier\")\n\n    @gen_test\n    async def test_concurrent_streaming_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n        )\n        for resp in resps:\n            self.assertEqual(resp.body, b\"ok broken barrier\")",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 82,
                            "end_lineno": 89,
                            "parent": {
                                "file_name": "tornado/test/wsgi_test.py",
                                "type": "class",
                                "name": "WSGIContainerDummyExecutorTest",
                                "content": "class WSGIContainerDummyExecutorTest(WSGIAppMixin, AsyncHTTPTestCase):\n    def get_executor(self):\n        return None\n\n    def test_simple(self):\n        response = self.fetch(\"/simple\")\n        self.assertEqual(response.body, b\"Hello world!\")\n\n    @gen_test\n    async def test_concurrent_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n        )\n        for resp in resps:\n            self.assertEqual(resp.body, b\"broken barrier\")\n\n    @gen_test\n    async def test_concurrent_streaming_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n        )\n        for resp in resps:\n            self.assertEqual(resp.body, b\"ok broken barrier\")",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 63,
                                "end_lineno": 89,
                                "parent": null
                            }
                        }
                    ],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 80,
                            "length": 3
                        },
                        "new_range": {
                            "start": 105,
                            "length": 12
                        },
                        "section": "class WSGIContainerThreadPoolTest(WSGIAppMixin, AsyncHTTPTestCase):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "            self.http_client.fetch(self.get_url(\"/barrier\")),",
                                "type": "context"
                            },
                            {
                                "content": "        )",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertEqual([b\"ok 0\", b\"ok 1\"], sorted([resp.body for resp in resps]))",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    @gen_test",
                                "type": "added"
                            },
                            {
                                "content": "    async def test_concurrent_streaming_barrier(self):",
                                "type": "added"
                            },
                            {
                                "content": "        self.barrier.reset()",
                                "type": "added"
                            },
                            {
                                "content": "        resps = await asyncio.gather(",
                                "type": "added"
                            },
                            {
                                "content": "            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),",
                                "type": "added"
                            },
                            {
                                "content": "            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),",
                                "type": "added"
                            },
                            {
                                "content": "        )",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertEqual([b\"ok 0\", b\"ok 1\"], sorted([resp.body for resp in resps]))",
                                "type": "added"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/test/wsgi_test.py",
                            "type": "class",
                            "name": "WSGIContainerThreadPoolTest",
                            "content": "class WSGIContainerThreadPoolTest(WSGIAppMixin, AsyncHTTPTestCase):\n    def get_executor(self):\n        return concurrent.futures.ThreadPoolExecutor()\n\n    def test_simple(self):\n        response = self.fetch(\"/simple\")\n        self.assertEqual(response.body, b\"Hello world!\")\n\n    @gen_test\n    async def test_concurrent_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n        )\n        self.assertEqual([b\"ok 0\", b\"ok 1\"], sorted([resp.body for resp in resps]))\n\n    @gen_test\n    async def test_concurrent_streaming_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n        )\n        self.assertEqual([b\"ok 0\", b\"ok 1\"], sorted([resp.body for resp in resps]))",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 92,
                            "end_lineno": 116,
                            "parent": null
                        }
                    ],
                    "added_entities": [
                        {
                            "file_name": "tornado/test/wsgi_test.py",
                            "type": "method",
                            "name": "WSGIContainerThreadPoolTest.test_concurrent_streaming_barrier",
                            "content": "class WSGIContainerThreadPoolTest(WSGIAppMixin, AsyncHTTPTestCase):\n    def get_executor(self):\n        return concurrent.futures.ThreadPoolExecutor()\n\n    def test_simple(self):\n        response = self.fetch(\"/simple\")\n        self.assertEqual(response.body, b\"Hello world!\")\n\n    @gen_test\n    async def test_concurrent_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n        )\n        self.assertEqual([b\"ok 0\", b\"ok 1\"], sorted([resp.body for resp in resps]))\n\n    @gen_test\n    async def test_concurrent_streaming_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n        )\n        self.assertEqual([b\"ok 0\", b\"ok 1\"], sorted([resp.body for resp in resps]))",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 110,
                            "end_lineno": 116,
                            "parent": {
                                "file_name": "tornado/test/wsgi_test.py",
                                "type": "class",
                                "name": "WSGIContainerThreadPoolTest",
                                "content": "class WSGIContainerThreadPoolTest(WSGIAppMixin, AsyncHTTPTestCase):\n    def get_executor(self):\n        return concurrent.futures.ThreadPoolExecutor()\n\n    def test_simple(self):\n        response = self.fetch(\"/simple\")\n        self.assertEqual(response.body, b\"Hello world!\")\n\n    @gen_test\n    async def test_concurrent_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n        )\n        self.assertEqual([b\"ok 0\", b\"ok 1\"], sorted([resp.body for resp in resps]))\n\n    @gen_test\n    async def test_concurrent_streaming_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n        )\n        self.assertEqual([b\"ok 0\", b\"ok 1\"], sorted([resp.body for resp in resps]))",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 92,
                                "end_lineno": 116,
                                "parent": null
                            }
                        }
                    ],
                    "deleted_entities": []
                }
            ]
        },
        {
            "old_file_content": "#\n# Copyright 2009 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\"\"\"WSGI support for the Tornado web framework.\n\nWSGI is the Python standard for web servers, and allows for interoperability\nbetween Tornado and other Python web frameworks and servers.\n\nThis module provides WSGI support via the `WSGIContainer` class, which\nmakes it possible to run applications using other WSGI frameworks on\nthe Tornado HTTP server. The reverse is not supported; the Tornado\n`.Application` and `.RequestHandler` classes are designed for use with\nthe Tornado `.HTTPServer` and cannot be used in a generic WSGI\ncontainer.\n\n\"\"\"\n\nimport concurrent.futures\nfrom io import BytesIO\nimport tornado\nimport sys\n\nfrom tornado.concurrent import dummy_executor\nfrom tornado import escape\nfrom tornado import httputil\nfrom tornado.ioloop import IOLoop\nfrom tornado.log import access_log\n\nfrom typing import List, Tuple, Optional, Callable, Any, Dict, Text\nfrom types import TracebackType\nimport typing\n\nif typing.TYPE_CHECKING:\n    from typing import Type  # noqa: F401\n    from _typeshed.wsgi import WSGIApplication as WSGIAppType  # noqa: F401\n\n\n# PEP 3333 specifies that WSGI on python 3 generally deals with byte strings\n# that are smuggled inside objects of type unicode (via the latin1 encoding).\n# This function is like those in the tornado.escape module, but defined\n# here to minimize the temptation to use it in non-wsgi contexts.\ndef to_wsgi_str(s: bytes) -> str:\n    assert isinstance(s, bytes)\n    return s.decode(\"latin1\")\n\n\nclass WSGIContainer(object):\n    r\"\"\"Makes a WSGI-compatible function runnable on Tornado's HTTP server.\n\n    .. warning::\n\n       WSGI is a *synchronous* interface, while Tornado's concurrency model\n       is based on single-threaded asynchronous execution.  This means that\n       running a WSGI app with Tornado's `WSGIContainer` is *less scalable*\n       than running the same app in a multi-threaded WSGI server like\n       ``gunicorn`` or ``uwsgi``.  Use `WSGIContainer` only when there are\n       benefits to combining Tornado and WSGI in the same process that\n       outweigh the reduced scalability.\n\n    Wrap a WSGI function in a `WSGIContainer` and pass it to `.HTTPServer` to\n    run it. For example::\n\n        def simple_app(environ, start_response):\n            status = \"200 OK\"\n            response_headers = [(\"Content-type\", \"text/plain\")]\n            start_response(status, response_headers)\n            return [b\"Hello world!\\n\"]\n\n        async def main():\n            container = tornado.wsgi.WSGIContainer(simple_app)\n            http_server = tornado.httpserver.HTTPServer(container)\n            http_server.listen(8888)\n            await asyncio.Event().wait()\n\n        asyncio.run(main())\n\n    This class is intended to let other frameworks (Django, web.py, etc)\n    run on the Tornado HTTP server and I/O loop.\n\n    The `tornado.web.FallbackHandler` class is often useful for mixing\n    Tornado and WSGI apps in the same server.  See\n    https://github.com/bdarnell/django-tornado-demo for a complete example.\n\n    `WSGIContainer` supports executing the WSGI application in custom executors\n    using `IOLoop.run_in_executor`. The default executor uses\n    `tornado.concurrent.dummy_executor` which works synchronously, but other\n    executors subclassing `concurrent.futures.Executor` may be used. To execute\n    WSGI application code in separate threads in an event-loop compatible way\n    use::\n\n        async def main():\n            executor = concurrent.futures.ThreadPoolExecutor()\n            # ^-- Execute requests in separate threads.\n            container = tornado.wsgi.WSGIContainer(simple_app, executor)\n            # Initialize the WSGI container with custom executor --^\n            http_server = tornado.httpserver.HTTPServer(container)\n            http_server.listen(8888)\n            await asyncio.Event().wait()\n\n    Running the WSGI app with a `ThreadPoolExecutor` remains *less scalable*\n    than running the same app in a multi-threaded WSGI server like ``gunicorn``\n    or ``uwsgi``.\n    \"\"\"\n\n    def __init__(\n        self,\n        wsgi_application: \"WSGIAppType\",\n        executor: concurrent.futures.Executor = None,\n    ) -> None:\n        self.wsgi_application = wsgi_application\n        self.executor = dummy_executor if executor is None else executor\n\n    def __call__(self, request: httputil.HTTPServerRequest) -> None:\n        IOLoop.current().spawn_callback(self.handle_request, request)\n\n    async def handle_request(self, request: httputil.HTTPServerRequest) -> None:\n        data = {}  # type: Dict[str, Any]\n        response = []  # type: List[bytes]\n\n        def start_response(\n            status: str,\n            headers: List[Tuple[str, str]],\n            exc_info: Optional[\n                Tuple[\n                    \"Optional[Type[BaseException]]\",\n                    Optional[BaseException],\n                    Optional[TracebackType],\n                ]\n            ] = None,\n        ) -> Callable[[bytes], Any]:\n            data[\"status\"] = status\n            data[\"headers\"] = headers\n            return response.append\n\n        loop = IOLoop.current()\n        app_response = await loop.run_in_executor(\n            self.executor,\n            self.wsgi_application,\n            self.environ(request),\n            start_response,\n        )\n        try:\n            response.extend(app_response)\n            body = b\"\".join(response)\n        finally:\n            if hasattr(app_response, \"close\"):\n                app_response.close()  # type: ignore\n        if not data:\n            raise Exception(\"WSGI app did not call start_response\")\n\n        status_code_str, reason = data[\"status\"].split(\" \", 1)\n        status_code = int(status_code_str)\n        headers = data[\"headers\"]  # type: List[Tuple[str, str]]\n        header_set = set(k.lower() for (k, v) in headers)\n        body = escape.utf8(body)\n        if status_code != 304:\n            if \"content-length\" not in header_set:\n                headers.append((\"Content-Length\", str(len(body))))\n            if \"content-type\" not in header_set:\n                headers.append((\"Content-Type\", \"text/html; charset=UTF-8\"))\n        if \"server\" not in header_set:\n            headers.append((\"Server\", \"TornadoServer/%s\" % tornado.version))\n\n        start_line = httputil.ResponseStartLine(\"HTTP/1.1\", status_code, reason)\n        header_obj = httputil.HTTPHeaders()\n        for key, value in headers:\n            header_obj.add(key, value)\n        assert request.connection is not None\n        request.connection.write_headers(start_line, header_obj, chunk=body)\n        request.connection.finish()\n        self._log(status_code, request)\n\n    @staticmethod\n    def environ(request: httputil.HTTPServerRequest) -> Dict[Text, Any]:\n        \"\"\"Converts a `tornado.httputil.HTTPServerRequest` to a WSGI environment.\"\"\"\n        hostport = request.host.split(\":\")\n        if len(hostport) == 2:\n            host = hostport[0]\n            port = int(hostport[1])\n        else:\n            host = request.host\n            port = 443 if request.protocol == \"https\" else 80\n        environ = {\n            \"REQUEST_METHOD\": request.method,\n            \"SCRIPT_NAME\": \"\",\n            \"PATH_INFO\": to_wsgi_str(\n                escape.url_unescape(request.path, encoding=None, plus=False)\n            ),\n            \"QUERY_STRING\": request.query,\n            \"REMOTE_ADDR\": request.remote_ip,\n            \"SERVER_NAME\": host,\n            \"SERVER_PORT\": str(port),\n            \"SERVER_PROTOCOL\": request.version,\n            \"wsgi.version\": (1, 0),\n            \"wsgi.url_scheme\": request.protocol,\n            \"wsgi.input\": BytesIO(escape.utf8(request.body)),\n            \"wsgi.errors\": sys.stderr,\n            \"wsgi.multithread\": False,\n            \"wsgi.multiprocess\": True,\n            \"wsgi.run_once\": False,\n        }\n        if \"Content-Type\" in request.headers:\n            environ[\"CONTENT_TYPE\"] = request.headers.pop(\"Content-Type\")\n        if \"Content-Length\" in request.headers:\n            environ[\"CONTENT_LENGTH\"] = request.headers.pop(\"Content-Length\")\n        for key, value in request.headers.items():\n            environ[\"HTTP_\" + key.replace(\"-\", \"_\").upper()] = value\n        return environ\n\n    def _log(self, status_code: int, request: httputil.HTTPServerRequest) -> None:\n        if status_code < 400:\n            log_method = access_log.info\n        elif status_code < 500:\n            log_method = access_log.warning\n        else:\n            log_method = access_log.error\n        request_time = 1000.0 * request.request_time()\n        assert request.method is not None\n        assert request.uri is not None\n        summary = (\n            request.method  # type: ignore[operator]\n            + \" \"\n            + request.uri\n            + \" (\"\n            + request.remote_ip\n            + \")\"\n        )\n        log_method(\"%d %s %.2fms\", status_code, summary, request_time)\n\n\nHTTPRequest = httputil.HTTPServerRequest\n",
            "new_file_content": "#\n# Copyright 2009 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\"\"\"WSGI support for the Tornado web framework.\n\nWSGI is the Python standard for web servers, and allows for interoperability\nbetween Tornado and other Python web frameworks and servers.\n\nThis module provides WSGI support via the `WSGIContainer` class, which\nmakes it possible to run applications using other WSGI frameworks on\nthe Tornado HTTP server. The reverse is not supported; the Tornado\n`.Application` and `.RequestHandler` classes are designed for use with\nthe Tornado `.HTTPServer` and cannot be used in a generic WSGI\ncontainer.\n\n\"\"\"\n\nimport concurrent.futures\nfrom io import BytesIO\nimport tornado\nimport sys\n\nfrom tornado.concurrent import dummy_executor\nfrom tornado import escape\nfrom tornado import httputil\nfrom tornado.ioloop import IOLoop\nfrom tornado.log import access_log\n\nfrom typing import List, Tuple, Optional, Callable, Any, Dict, Text\nfrom types import TracebackType\nimport typing\n\nif typing.TYPE_CHECKING:\n    from typing import Type  # noqa: F401\n    from _typeshed.wsgi import WSGIApplication as WSGIAppType  # noqa: F401\n\n\n# PEP 3333 specifies that WSGI on python 3 generally deals with byte strings\n# that are smuggled inside objects of type unicode (via the latin1 encoding).\n# This function is like those in the tornado.escape module, but defined\n# here to minimize the temptation to use it in non-wsgi contexts.\ndef to_wsgi_str(s: bytes) -> str:\n    assert isinstance(s, bytes)\n    return s.decode(\"latin1\")\n\n\nclass WSGIContainer(object):\n    r\"\"\"Makes a WSGI-compatible function runnable on Tornado's HTTP server.\n\n    .. warning::\n\n       WSGI is a *synchronous* interface, while Tornado's concurrency model\n       is based on single-threaded asynchronous execution.  This means that\n       running a WSGI app with Tornado's `WSGIContainer` is *less scalable*\n       than running the same app in a multi-threaded WSGI server like\n       ``gunicorn`` or ``uwsgi``.  Use `WSGIContainer` only when there are\n       benefits to combining Tornado and WSGI in the same process that\n       outweigh the reduced scalability.\n\n    Wrap a WSGI function in a `WSGIContainer` and pass it to `.HTTPServer` to\n    run it. For example::\n\n        def simple_app(environ, start_response):\n            status = \"200 OK\"\n            response_headers = [(\"Content-type\", \"text/plain\")]\n            start_response(status, response_headers)\n            return [b\"Hello world!\\n\"]\n\n        async def main():\n            container = tornado.wsgi.WSGIContainer(simple_app)\n            http_server = tornado.httpserver.HTTPServer(container)\n            http_server.listen(8888)\n            await asyncio.Event().wait()\n\n        asyncio.run(main())\n\n    This class is intended to let other frameworks (Django, web.py, etc)\n    run on the Tornado HTTP server and I/O loop.\n\n    The `tornado.web.FallbackHandler` class is often useful for mixing\n    Tornado and WSGI apps in the same server.  See\n    https://github.com/bdarnell/django-tornado-demo for a complete example.\n\n    `WSGIContainer` supports executing the WSGI application in custom executors\n    using `.IOLoop.run_in_executor`. The default executor uses\n    ``tornado.concurrent.dummy_executor`` which works synchronously, but other\n    executors subclassing `concurrent.futures.Executor` may be used. To execute\n    WSGI application code in separate threads in an event-loop compatible way\n    use::\n\n        async def main():\n            executor = concurrent.futures.ThreadPoolExecutor()\n            # ^-- Execute requests in separate threads.\n            container = tornado.wsgi.WSGIContainer(simple_app, executor)\n            # Initialize the WSGI container with custom executor --^\n            http_server = tornado.httpserver.HTTPServer(container)\n            http_server.listen(8888)\n            await asyncio.Event().wait()\n\n    Running the WSGI app with a ``ThreadPoolExecutor`` remains *less scalable*\n    than running the same app in a multi-threaded WSGI server like ``gunicorn``\n    or ``uwsgi``.\n    \"\"\"\n\n    def __init__(\n        self,\n        wsgi_application: \"WSGIAppType\",\n        executor: Optional[concurrent.futures.Executor] = None,\n    ) -> None:\n        self.wsgi_application = wsgi_application\n        self.executor = dummy_executor if executor is None else executor\n\n    def __call__(self, request: httputil.HTTPServerRequest) -> None:\n        IOLoop.current().spawn_callback(self.handle_request, request)\n\n    async def handle_request(self, request: httputil.HTTPServerRequest) -> None:\n        data = {}  # type: Dict[str, Any]\n        response = []  # type: List[bytes]\n\n        def start_response(\n            status: str,\n            headers: List[Tuple[str, str]],\n            exc_info: Optional[\n                Tuple[\n                    \"Optional[Type[BaseException]]\",\n                    Optional[BaseException],\n                    Optional[TracebackType],\n                ]\n            ] = None,\n        ) -> Callable[[bytes], Any]:\n            data[\"status\"] = status\n            data[\"headers\"] = headers\n            return response.append\n\n        loop = IOLoop.current()\n        app_response = await loop.run_in_executor(\n            self.executor,\n            self.wsgi_application,\n            self.environ(request),\n            start_response,\n        )\n        try:\n            app_response_iter = iter(app_response)\n\n            def next_chunk() -> Optional[bytes]:\n                try:\n                    return next(app_response_iter)\n                except StopIteration:\n                    # StopIteration is special and is not allowed to pass through\n                    # coroutines normally.\n                    return None\n\n            while True:\n                chunk = await loop.run_in_executor(self.executor, next_chunk)\n                if chunk is None:\n                    break\n                response.append(chunk)\n        finally:\n            if hasattr(app_response, \"close\"):\n                app_response.close()  # type: ignore\n        body = b\"\".join(response)\n        if not data:\n            raise Exception(\"WSGI app did not call start_response\")\n\n        status_code_str, reason = data[\"status\"].split(\" \", 1)\n        status_code = int(status_code_str)\n        headers = data[\"headers\"]  # type: List[Tuple[str, str]]\n        header_set = set(k.lower() for (k, v) in headers)\n        body = escape.utf8(body)\n        if status_code != 304:\n            if \"content-length\" not in header_set:\n                headers.append((\"Content-Length\", str(len(body))))\n            if \"content-type\" not in header_set:\n                headers.append((\"Content-Type\", \"text/html; charset=UTF-8\"))\n        if \"server\" not in header_set:\n            headers.append((\"Server\", \"TornadoServer/%s\" % tornado.version))\n\n        start_line = httputil.ResponseStartLine(\"HTTP/1.1\", status_code, reason)\n        header_obj = httputil.HTTPHeaders()\n        for key, value in headers:\n            header_obj.add(key, value)\n        assert request.connection is not None\n        request.connection.write_headers(start_line, header_obj, chunk=body)\n        request.connection.finish()\n        self._log(status_code, request)\n\n    @staticmethod\n    def environ(request: httputil.HTTPServerRequest) -> Dict[Text, Any]:\n        \"\"\"Converts a `tornado.httputil.HTTPServerRequest` to a WSGI environment.\"\"\"\n        hostport = request.host.split(\":\")\n        if len(hostport) == 2:\n            host = hostport[0]\n            port = int(hostport[1])\n        else:\n            host = request.host\n            port = 443 if request.protocol == \"https\" else 80\n        environ = {\n            \"REQUEST_METHOD\": request.method,\n            \"SCRIPT_NAME\": \"\",\n            \"PATH_INFO\": to_wsgi_str(\n                escape.url_unescape(request.path, encoding=None, plus=False)\n            ),\n            \"QUERY_STRING\": request.query,\n            \"REMOTE_ADDR\": request.remote_ip,\n            \"SERVER_NAME\": host,\n            \"SERVER_PORT\": str(port),\n            \"SERVER_PROTOCOL\": request.version,\n            \"wsgi.version\": (1, 0),\n            \"wsgi.url_scheme\": request.protocol,\n            \"wsgi.input\": BytesIO(escape.utf8(request.body)),\n            \"wsgi.errors\": sys.stderr,\n            \"wsgi.multithread\": False,\n            \"wsgi.multiprocess\": True,\n            \"wsgi.run_once\": False,\n        }\n        if \"Content-Type\" in request.headers:\n            environ[\"CONTENT_TYPE\"] = request.headers.pop(\"Content-Type\")\n        if \"Content-Length\" in request.headers:\n            environ[\"CONTENT_LENGTH\"] = request.headers.pop(\"Content-Length\")\n        for key, value in request.headers.items():\n            environ[\"HTTP_\" + key.replace(\"-\", \"_\").upper()] = value\n        return environ\n\n    def _log(self, status_code: int, request: httputil.HTTPServerRequest) -> None:\n        if status_code < 400:\n            log_method = access_log.info\n        elif status_code < 500:\n            log_method = access_log.warning\n        else:\n            log_method = access_log.error\n        request_time = 1000.0 * request.request_time()\n        assert request.method is not None\n        assert request.uri is not None\n        summary = (\n            request.method  # type: ignore[operator]\n            + \" \"\n            + request.uri\n            + \" (\"\n            + request.remote_ip\n            + \")\"\n        )\n        log_method(\"%d %s %.2fms\", status_code, summary, request_time)\n\n\nHTTPRequest = httputil.HTTPServerRequest\n",
            "header": {
                "file": {
                    "path": "tornado/wsgi.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "66d4ca6d",
                "new_commit_hash": "c37d7dc8",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/tornado/wsgi.py"
            },
            "plus_file": {
                "path": "b/tornado/wsgi.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 94,
                            "length": 8
                        },
                        "new_range": {
                            "start": 94,
                            "length": 8
                        },
                        "section": "class WSGIContainer(object):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "    https://github.com/bdarnell/django-tornado-demo for a complete example.",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    `WSGIContainer` supports executing the WSGI application in custom executors",
                                "type": "context"
                            },
                            {
                                "content": "    using `IOLoop.run_in_executor`. The default executor uses",
                                "type": "deleted"
                            },
                            {
                                "content": "    `tornado.concurrent.dummy_executor` which works synchronously, but other",
                                "type": "deleted"
                            },
                            {
                                "content": "    using `.IOLoop.run_in_executor`. The default executor uses",
                                "type": "added"
                            },
                            {
                                "content": "    ``tornado.concurrent.dummy_executor`` which works synchronously, but other",
                                "type": "added"
                            },
                            {
                                "content": "    executors subclassing `concurrent.futures.Executor` may be used. To execute",
                                "type": "context"
                            },
                            {
                                "content": "    WSGI application code in separate threads in an event-loop compatible way",
                                "type": "context"
                            },
                            {
                                "content": "    use::",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/wsgi.py",
                            "type": "class",
                            "name": "WSGIContainer",
                            "content": "class WSGIContainer(object):\n    r\"\"\"Makes a WSGI-compatible function runnable on Tornado's HTTP server.\n\n    .. warning::\n\n       WSGI is a *synchronous* interface, while Tornado's concurrency model\n       is based on single-threaded asynchronous execution.  This means that\n       running a WSGI app with Tornado's `WSGIContainer` is *less scalable*\n       than running the same app in a multi-threaded WSGI server like\n       ``gunicorn`` or ``uwsgi``.  Use `WSGIContainer` only when there are\n       benefits to combining Tornado and WSGI in the same process that\n       outweigh the reduced scalability.\n\n    Wrap a WSGI function in a `WSGIContainer` and pass it to `.HTTPServer` to\n    run it. For example::\n\n        def simple_app(environ, start_response):\n            status = \"200 OK\"\n            response_headers = [(\"Content-type\", \"text/plain\")]\n            start_response(status, response_headers)\n            return [b\"Hello world!\\n\"]\n\n        async def main():\n            container = tornado.wsgi.WSGIContainer(simple_app)\n            http_server = tornado.httpserver.HTTPServer(container)\n            http_server.listen(8888)\n            await asyncio.Event().wait()\n\n        asyncio.run(main())\n\n    This class is intended to let other frameworks (Django, web.py, etc)\n    run on the Tornado HTTP server and I/O loop.\n\n    The `tornado.web.FallbackHandler` class is often useful for mixing\n    Tornado and WSGI apps in the same server.  See\n    https://github.com/bdarnell/django-tornado-demo for a complete example.\n\n    `WSGIContainer` supports executing the WSGI application in custom executors\n    using `IOLoop.run_in_executor`. The default executor uses\n    `tornado.concurrent.dummy_executor` which works synchronously, but other\n    executors subclassing `concurrent.futures.Executor` may be used. To execute\n    WSGI application code in separate threads in an event-loop compatible way\n    use::\n\n        async def main():\n            executor = concurrent.futures.ThreadPoolExecutor()\n            # ^-- Execute requests in separate threads.\n            container = tornado.wsgi.WSGIContainer(simple_app, executor)\n            # Initialize the WSGI container with custom executor --^\n            http_server = tornado.httpserver.HTTPServer(container)\n            http_server.listen(8888)\n            await asyncio.Event().wait()\n\n    Running the WSGI app with a `ThreadPoolExecutor` remains *less scalable*\n    than running the same app in a multi-threaded WSGI server like ``gunicorn``\n    or ``uwsgi``.\n    \"\"\"\n\n    def __init__(\n        self,\n        wsgi_application: \"WSGIAppType\",\n        executor: concurrent.futures.Executor = None,\n    ) -> None:\n        self.wsgi_application = wsgi_application\n        self.executor = dummy_executor if executor is None else executor\n\n    def __call__(self, request: httputil.HTTPServerRequest) -> None:\n        IOLoop.current().spawn_callback(self.handle_request, request)\n\n    async def handle_request(self, request: httputil.HTTPServerRequest) -> None:\n        data = {}  # type: Dict[str, Any]\n        response = []  # type: List[bytes]\n\n        def start_response(\n            status: str,\n            headers: List[Tuple[str, str]],\n            exc_info: Optional[\n                Tuple[\n                    \"Optional[Type[BaseException]]\",\n                    Optional[BaseException],\n                    Optional[TracebackType],\n                ]\n            ] = None,\n        ) -> Callable[[bytes], Any]:\n            data[\"status\"] = status\n            data[\"headers\"] = headers\n            return response.append\n\n        loop = IOLoop.current()\n        app_response = await loop.run_in_executor(\n            self.executor,\n            self.wsgi_application,\n            self.environ(request),\n            start_response,\n        )\n        try:\n            response.extend(app_response)\n            body = b\"\".join(response)\n        finally:\n            if hasattr(app_response, \"close\"):\n                app_response.close()  # type: ignore\n        if not data:\n            raise Exception(\"WSGI app did not call start_response\")\n\n        status_code_str, reason = data[\"status\"].split(\" \", 1)\n        status_code = int(status_code_str)\n        headers = data[\"headers\"]  # type: List[Tuple[str, str]]\n        header_set = set(k.lower() for (k, v) in headers)\n        body = escape.utf8(body)\n        if status_code != 304:\n            if \"content-length\" not in header_set:\n                headers.append((\"Content-Length\", str(len(body))))\n            if \"content-type\" not in header_set:\n                headers.append((\"Content-Type\", \"text/html; charset=UTF-8\"))\n        if \"server\" not in header_set:\n            headers.append((\"Server\", \"TornadoServer/%s\" % tornado.version))\n\n        start_line = httputil.ResponseStartLine(\"HTTP/1.1\", status_code, reason)\n        header_obj = httputil.HTTPHeaders()\n        for key, value in headers:\n            header_obj.add(key, value)\n        assert request.connection is not None\n        request.connection.write_headers(start_line, header_obj, chunk=body)\n        request.connection.finish()\n        self._log(status_code, request)\n\n    @staticmethod\n    def environ(request: httputil.HTTPServerRequest) -> Dict[Text, Any]:\n        \"\"\"Converts a `tornado.httputil.HTTPServerRequest` to a WSGI environment.\"\"\"\n        hostport = request.host.split(\":\")\n        if len(hostport) == 2:\n            host = hostport[0]\n            port = int(hostport[1])\n        else:\n            host = request.host\n            port = 443 if request.protocol == \"https\" else 80\n        environ = {\n            \"REQUEST_METHOD\": request.method,\n            \"SCRIPT_NAME\": \"\",\n            \"PATH_INFO\": to_wsgi_str(\n                escape.url_unescape(request.path, encoding=None, plus=False)\n            ),\n            \"QUERY_STRING\": request.query,\n            \"REMOTE_ADDR\": request.remote_ip,\n            \"SERVER_NAME\": host,\n            \"SERVER_PORT\": str(port),\n            \"SERVER_PROTOCOL\": request.version,\n            \"wsgi.version\": (1, 0),\n            \"wsgi.url_scheme\": request.protocol,\n            \"wsgi.input\": BytesIO(escape.utf8(request.body)),\n            \"wsgi.errors\": sys.stderr,\n            \"wsgi.multithread\": False,\n            \"wsgi.multiprocess\": True,\n            \"wsgi.run_once\": False,\n        }\n        if \"Content-Type\" in request.headers:\n            environ[\"CONTENT_TYPE\"] = request.headers.pop(\"Content-Type\")\n        if \"Content-Length\" in request.headers:\n            environ[\"CONTENT_LENGTH\"] = request.headers.pop(\"Content-Length\")\n        for key, value in request.headers.items():\n            environ[\"HTTP_\" + key.replace(\"-\", \"_\").upper()] = value\n        return environ\n\n    def _log(self, status_code: int, request: httputil.HTTPServerRequest) -> None:\n        if status_code < 400:\n            log_method = access_log.info\n        elif status_code < 500:\n            log_method = access_log.warning\n        else:\n            log_method = access_log.error\n        request_time = 1000.0 * request.request_time()\n        assert request.method is not None\n        assert request.uri is not None\n        summary = (\n            request.method  # type: ignore[operator]\n            + \" \"\n            + request.uri\n            + \" (\"\n            + request.remote_ip\n            + \")\"\n        )\n        log_method(\"%d %s %.2fms\", status_code, summary, request_time)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 59,
                            "end_lineno": 240,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 109,
                            "length": 7
                        },
                        "new_range": {
                            "start": 109,
                            "length": 7
                        },
                        "section": "class WSGIContainer(object):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "            http_server.listen(8888)",
                                "type": "context"
                            },
                            {
                                "content": "            await asyncio.Event().wait()",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    Running the WSGI app with a `ThreadPoolExecutor` remains *less scalable*",
                                "type": "deleted"
                            },
                            {
                                "content": "    Running the WSGI app with a ``ThreadPoolExecutor`` remains *less scalable*",
                                "type": "added"
                            },
                            {
                                "content": "    than running the same app in a multi-threaded WSGI server like ``gunicorn``",
                                "type": "context"
                            },
                            {
                                "content": "    or ``uwsgi``.",
                                "type": "context"
                            },
                            {
                                "content": "    \"\"\"",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/wsgi.py",
                            "type": "class",
                            "name": "WSGIContainer",
                            "content": "class WSGIContainer(object):\n    r\"\"\"Makes a WSGI-compatible function runnable on Tornado's HTTP server.\n\n    .. warning::\n\n       WSGI is a *synchronous* interface, while Tornado's concurrency model\n       is based on single-threaded asynchronous execution.  This means that\n       running a WSGI app with Tornado's `WSGIContainer` is *less scalable*\n       than running the same app in a multi-threaded WSGI server like\n       ``gunicorn`` or ``uwsgi``.  Use `WSGIContainer` only when there are\n       benefits to combining Tornado and WSGI in the same process that\n       outweigh the reduced scalability.\n\n    Wrap a WSGI function in a `WSGIContainer` and pass it to `.HTTPServer` to\n    run it. For example::\n\n        def simple_app(environ, start_response):\n            status = \"200 OK\"\n            response_headers = [(\"Content-type\", \"text/plain\")]\n            start_response(status, response_headers)\n            return [b\"Hello world!\\n\"]\n\n        async def main():\n            container = tornado.wsgi.WSGIContainer(simple_app)\n            http_server = tornado.httpserver.HTTPServer(container)\n            http_server.listen(8888)\n            await asyncio.Event().wait()\n\n        asyncio.run(main())\n\n    This class is intended to let other frameworks (Django, web.py, etc)\n    run on the Tornado HTTP server and I/O loop.\n\n    The `tornado.web.FallbackHandler` class is often useful for mixing\n    Tornado and WSGI apps in the same server.  See\n    https://github.com/bdarnell/django-tornado-demo for a complete example.\n\n    `WSGIContainer` supports executing the WSGI application in custom executors\n    using `IOLoop.run_in_executor`. The default executor uses\n    `tornado.concurrent.dummy_executor` which works synchronously, but other\n    executors subclassing `concurrent.futures.Executor` may be used. To execute\n    WSGI application code in separate threads in an event-loop compatible way\n    use::\n\n        async def main():\n            executor = concurrent.futures.ThreadPoolExecutor()\n            # ^-- Execute requests in separate threads.\n            container = tornado.wsgi.WSGIContainer(simple_app, executor)\n            # Initialize the WSGI container with custom executor --^\n            http_server = tornado.httpserver.HTTPServer(container)\n            http_server.listen(8888)\n            await asyncio.Event().wait()\n\n    Running the WSGI app with a `ThreadPoolExecutor` remains *less scalable*\n    than running the same app in a multi-threaded WSGI server like ``gunicorn``\n    or ``uwsgi``.\n    \"\"\"\n\n    def __init__(\n        self,\n        wsgi_application: \"WSGIAppType\",\n        executor: concurrent.futures.Executor = None,\n    ) -> None:\n        self.wsgi_application = wsgi_application\n        self.executor = dummy_executor if executor is None else executor\n\n    def __call__(self, request: httputil.HTTPServerRequest) -> None:\n        IOLoop.current().spawn_callback(self.handle_request, request)\n\n    async def handle_request(self, request: httputil.HTTPServerRequest) -> None:\n        data = {}  # type: Dict[str, Any]\n        response = []  # type: List[bytes]\n\n        def start_response(\n            status: str,\n            headers: List[Tuple[str, str]],\n            exc_info: Optional[\n                Tuple[\n                    \"Optional[Type[BaseException]]\",\n                    Optional[BaseException],\n                    Optional[TracebackType],\n                ]\n            ] = None,\n        ) -> Callable[[bytes], Any]:\n            data[\"status\"] = status\n            data[\"headers\"] = headers\n            return response.append\n\n        loop = IOLoop.current()\n        app_response = await loop.run_in_executor(\n            self.executor,\n            self.wsgi_application,\n            self.environ(request),\n            start_response,\n        )\n        try:\n            response.extend(app_response)\n            body = b\"\".join(response)\n        finally:\n            if hasattr(app_response, \"close\"):\n                app_response.close()  # type: ignore\n        if not data:\n            raise Exception(\"WSGI app did not call start_response\")\n\n        status_code_str, reason = data[\"status\"].split(\" \", 1)\n        status_code = int(status_code_str)\n        headers = data[\"headers\"]  # type: List[Tuple[str, str]]\n        header_set = set(k.lower() for (k, v) in headers)\n        body = escape.utf8(body)\n        if status_code != 304:\n            if \"content-length\" not in header_set:\n                headers.append((\"Content-Length\", str(len(body))))\n            if \"content-type\" not in header_set:\n                headers.append((\"Content-Type\", \"text/html; charset=UTF-8\"))\n        if \"server\" not in header_set:\n            headers.append((\"Server\", \"TornadoServer/%s\" % tornado.version))\n\n        start_line = httputil.ResponseStartLine(\"HTTP/1.1\", status_code, reason)\n        header_obj = httputil.HTTPHeaders()\n        for key, value in headers:\n            header_obj.add(key, value)\n        assert request.connection is not None\n        request.connection.write_headers(start_line, header_obj, chunk=body)\n        request.connection.finish()\n        self._log(status_code, request)\n\n    @staticmethod\n    def environ(request: httputil.HTTPServerRequest) -> Dict[Text, Any]:\n        \"\"\"Converts a `tornado.httputil.HTTPServerRequest` to a WSGI environment.\"\"\"\n        hostport = request.host.split(\":\")\n        if len(hostport) == 2:\n            host = hostport[0]\n            port = int(hostport[1])\n        else:\n            host = request.host\n            port = 443 if request.protocol == \"https\" else 80\n        environ = {\n            \"REQUEST_METHOD\": request.method,\n            \"SCRIPT_NAME\": \"\",\n            \"PATH_INFO\": to_wsgi_str(\n                escape.url_unescape(request.path, encoding=None, plus=False)\n            ),\n            \"QUERY_STRING\": request.query,\n            \"REMOTE_ADDR\": request.remote_ip,\n            \"SERVER_NAME\": host,\n            \"SERVER_PORT\": str(port),\n            \"SERVER_PROTOCOL\": request.version,\n            \"wsgi.version\": (1, 0),\n            \"wsgi.url_scheme\": request.protocol,\n            \"wsgi.input\": BytesIO(escape.utf8(request.body)),\n            \"wsgi.errors\": sys.stderr,\n            \"wsgi.multithread\": False,\n            \"wsgi.multiprocess\": True,\n            \"wsgi.run_once\": False,\n        }\n        if \"Content-Type\" in request.headers:\n            environ[\"CONTENT_TYPE\"] = request.headers.pop(\"Content-Type\")\n        if \"Content-Length\" in request.headers:\n            environ[\"CONTENT_LENGTH\"] = request.headers.pop(\"Content-Length\")\n        for key, value in request.headers.items():\n            environ[\"HTTP_\" + key.replace(\"-\", \"_\").upper()] = value\n        return environ\n\n    def _log(self, status_code: int, request: httputil.HTTPServerRequest) -> None:\n        if status_code < 400:\n            log_method = access_log.info\n        elif status_code < 500:\n            log_method = access_log.warning\n        else:\n            log_method = access_log.error\n        request_time = 1000.0 * request.request_time()\n        assert request.method is not None\n        assert request.uri is not None\n        summary = (\n            request.method  # type: ignore[operator]\n            + \" \"\n            + request.uri\n            + \" (\"\n            + request.remote_ip\n            + \")\"\n        )\n        log_method(\"%d %s %.2fms\", status_code, summary, request_time)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 59,
                            "end_lineno": 240,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 117,
                            "length": 7
                        },
                        "new_range": {
                            "start": 117,
                            "length": 7
                        },
                        "section": "class WSGIContainer(object):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "    def __init__(",
                                "type": "context"
                            },
                            {
                                "content": "        self,",
                                "type": "context"
                            },
                            {
                                "content": "        wsgi_application: \"WSGIAppType\",",
                                "type": "context"
                            },
                            {
                                "content": "        executor: concurrent.futures.Executor = None,",
                                "type": "deleted"
                            },
                            {
                                "content": "        executor: Optional[concurrent.futures.Executor] = None,",
                                "type": "added"
                            },
                            {
                                "content": "    ) -> None:",
                                "type": "context"
                            },
                            {
                                "content": "        self.wsgi_application = wsgi_application",
                                "type": "context"
                            },
                            {
                                "content": "        self.executor = dummy_executor if executor is None else executor",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/wsgi.py",
                            "type": "class",
                            "name": "WSGIContainer",
                            "content": "class WSGIContainer(object):\n    r\"\"\"Makes a WSGI-compatible function runnable on Tornado's HTTP server.\n\n    .. warning::\n\n       WSGI is a *synchronous* interface, while Tornado's concurrency model\n       is based on single-threaded asynchronous execution.  This means that\n       running a WSGI app with Tornado's `WSGIContainer` is *less scalable*\n       than running the same app in a multi-threaded WSGI server like\n       ``gunicorn`` or ``uwsgi``.  Use `WSGIContainer` only when there are\n       benefits to combining Tornado and WSGI in the same process that\n       outweigh the reduced scalability.\n\n    Wrap a WSGI function in a `WSGIContainer` and pass it to `.HTTPServer` to\n    run it. For example::\n\n        def simple_app(environ, start_response):\n            status = \"200 OK\"\n            response_headers = [(\"Content-type\", \"text/plain\")]\n            start_response(status, response_headers)\n            return [b\"Hello world!\\n\"]\n\n        async def main():\n            container = tornado.wsgi.WSGIContainer(simple_app)\n            http_server = tornado.httpserver.HTTPServer(container)\n            http_server.listen(8888)\n            await asyncio.Event().wait()\n\n        asyncio.run(main())\n\n    This class is intended to let other frameworks (Django, web.py, etc)\n    run on the Tornado HTTP server and I/O loop.\n\n    The `tornado.web.FallbackHandler` class is often useful for mixing\n    Tornado and WSGI apps in the same server.  See\n    https://github.com/bdarnell/django-tornado-demo for a complete example.\n\n    `WSGIContainer` supports executing the WSGI application in custom executors\n    using `IOLoop.run_in_executor`. The default executor uses\n    `tornado.concurrent.dummy_executor` which works synchronously, but other\n    executors subclassing `concurrent.futures.Executor` may be used. To execute\n    WSGI application code in separate threads in an event-loop compatible way\n    use::\n\n        async def main():\n            executor = concurrent.futures.ThreadPoolExecutor()\n            # ^-- Execute requests in separate threads.\n            container = tornado.wsgi.WSGIContainer(simple_app, executor)\n            # Initialize the WSGI container with custom executor --^\n            http_server = tornado.httpserver.HTTPServer(container)\n            http_server.listen(8888)\n            await asyncio.Event().wait()\n\n    Running the WSGI app with a `ThreadPoolExecutor` remains *less scalable*\n    than running the same app in a multi-threaded WSGI server like ``gunicorn``\n    or ``uwsgi``.\n    \"\"\"\n\n    def __init__(\n        self,\n        wsgi_application: \"WSGIAppType\",\n        executor: concurrent.futures.Executor = None,\n    ) -> None:\n        self.wsgi_application = wsgi_application\n        self.executor = dummy_executor if executor is None else executor\n\n    def __call__(self, request: httputil.HTTPServerRequest) -> None:\n        IOLoop.current().spawn_callback(self.handle_request, request)\n\n    async def handle_request(self, request: httputil.HTTPServerRequest) -> None:\n        data = {}  # type: Dict[str, Any]\n        response = []  # type: List[bytes]\n\n        def start_response(\n            status: str,\n            headers: List[Tuple[str, str]],\n            exc_info: Optional[\n                Tuple[\n                    \"Optional[Type[BaseException]]\",\n                    Optional[BaseException],\n                    Optional[TracebackType],\n                ]\n            ] = None,\n        ) -> Callable[[bytes], Any]:\n            data[\"status\"] = status\n            data[\"headers\"] = headers\n            return response.append\n\n        loop = IOLoop.current()\n        app_response = await loop.run_in_executor(\n            self.executor,\n            self.wsgi_application,\n            self.environ(request),\n            start_response,\n        )\n        try:\n            response.extend(app_response)\n            body = b\"\".join(response)\n        finally:\n            if hasattr(app_response, \"close\"):\n                app_response.close()  # type: ignore\n        if not data:\n            raise Exception(\"WSGI app did not call start_response\")\n\n        status_code_str, reason = data[\"status\"].split(\" \", 1)\n        status_code = int(status_code_str)\n        headers = data[\"headers\"]  # type: List[Tuple[str, str]]\n        header_set = set(k.lower() for (k, v) in headers)\n        body = escape.utf8(body)\n        if status_code != 304:\n            if \"content-length\" not in header_set:\n                headers.append((\"Content-Length\", str(len(body))))\n            if \"content-type\" not in header_set:\n                headers.append((\"Content-Type\", \"text/html; charset=UTF-8\"))\n        if \"server\" not in header_set:\n            headers.append((\"Server\", \"TornadoServer/%s\" % tornado.version))\n\n        start_line = httputil.ResponseStartLine(\"HTTP/1.1\", status_code, reason)\n        header_obj = httputil.HTTPHeaders()\n        for key, value in headers:\n            header_obj.add(key, value)\n        assert request.connection is not None\n        request.connection.write_headers(start_line, header_obj, chunk=body)\n        request.connection.finish()\n        self._log(status_code, request)\n\n    @staticmethod\n    def environ(request: httputil.HTTPServerRequest) -> Dict[Text, Any]:\n        \"\"\"Converts a `tornado.httputil.HTTPServerRequest` to a WSGI environment.\"\"\"\n        hostport = request.host.split(\":\")\n        if len(hostport) == 2:\n            host = hostport[0]\n            port = int(hostport[1])\n        else:\n            host = request.host\n            port = 443 if request.protocol == \"https\" else 80\n        environ = {\n            \"REQUEST_METHOD\": request.method,\n            \"SCRIPT_NAME\": \"\",\n            \"PATH_INFO\": to_wsgi_str(\n                escape.url_unescape(request.path, encoding=None, plus=False)\n            ),\n            \"QUERY_STRING\": request.query,\n            \"REMOTE_ADDR\": request.remote_ip,\n            \"SERVER_NAME\": host,\n            \"SERVER_PORT\": str(port),\n            \"SERVER_PROTOCOL\": request.version,\n            \"wsgi.version\": (1, 0),\n            \"wsgi.url_scheme\": request.protocol,\n            \"wsgi.input\": BytesIO(escape.utf8(request.body)),\n            \"wsgi.errors\": sys.stderr,\n            \"wsgi.multithread\": False,\n            \"wsgi.multiprocess\": True,\n            \"wsgi.run_once\": False,\n        }\n        if \"Content-Type\" in request.headers:\n            environ[\"CONTENT_TYPE\"] = request.headers.pop(\"Content-Type\")\n        if \"Content-Length\" in request.headers:\n            environ[\"CONTENT_LENGTH\"] = request.headers.pop(\"Content-Length\")\n        for key, value in request.headers.items():\n            environ[\"HTTP_\" + key.replace(\"-\", \"_\").upper()] = value\n        return environ\n\n    def _log(self, status_code: int, request: httputil.HTTPServerRequest) -> None:\n        if status_code < 400:\n            log_method = access_log.info\n        elif status_code < 500:\n            log_method = access_log.warning\n        else:\n            log_method = access_log.error\n        request_time = 1000.0 * request.request_time()\n        assert request.method is not None\n        assert request.uri is not None\n        summary = (\n            request.method  # type: ignore[operator]\n            + \" \"\n            + request.uri\n            + \" (\"\n            + request.remote_ip\n            + \")\"\n        )\n        log_method(\"%d %s %.2fms\", status_code, summary, request_time)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 59,
                            "end_lineno": 240,
                            "parent": null
                        },
                        {
                            "file_name": "tornado/wsgi.py",
                            "type": "method",
                            "name": "WSGIContainer.__init__",
                            "content": "class WSGIContainer(object):\n    r\"\"\"Makes a WSGI-compatible function runnable on Tornado's HTTP server.\n\n    .. warning::\n\n       WSGI is a *synchronous* interface, while Tornado's concurrency model\n       is based on single-threaded asynchronous execution.  This means that\n       running a WSGI app with Tornado's `WSGIContainer` is *less scalable*\n       than running the same app in a multi-threaded WSGI server like\n       ``gunicorn`` or ``uwsgi``.  Use `WSGIContainer` only when there are\n       benefits to combining Tornado and WSGI in the same process that\n       outweigh the reduced scalability.\n\n    Wrap a WSGI function in a `WSGIContainer` and pass it to `.HTTPServer` to\n    run it. For example::\n\n        def simple_app(environ, start_response):\n            status = \"200 OK\"\n            response_headers = [(\"Content-type\", \"text/plain\")]\n            start_response(status, response_headers)\n            return [b\"Hello world!\\n\"]\n\n        async def main():\n            container = tornado.wsgi.WSGIContainer(simple_app)\n            http_server = tornado.httpserver.HTTPServer(container)\n            http_server.listen(8888)\n            await asyncio.Event().wait()\n\n        asyncio.run(main())\n\n    This class is intended to let other frameworks (Django, web.py, etc)\n    run on the Tornado HTTP server and I/O loop.\n\n    The `tornado.web.FallbackHandler` class is often useful for mixing\n    Tornado and WSGI apps in the same server.  See\n    https://github.com/bdarnell/django-tornado-demo for a complete example.\n\n    `WSGIContainer` supports executing the WSGI application in custom executors\n    using `IOLoop.run_in_executor`. The default executor uses\n    `tornado.concurrent.dummy_executor` which works synchronously, but other\n    executors subclassing `concurrent.futures.Executor` may be used. To execute\n    WSGI application code in separate threads in an event-loop compatible way\n    use::\n\n        async def main():\n            executor = concurrent.futures.ThreadPoolExecutor()\n            # ^-- Execute requests in separate threads.\n            container = tornado.wsgi.WSGIContainer(simple_app, executor)\n            # Initialize the WSGI container with custom executor --^\n            http_server = tornado.httpserver.HTTPServer(container)\n            http_server.listen(8888)\n            await asyncio.Event().wait()\n\n    Running the WSGI app with a `ThreadPoolExecutor` remains *less scalable*\n    than running the same app in a multi-threaded WSGI server like ``gunicorn``\n    or ``uwsgi``.\n    \"\"\"\n\n    def __init__(\n        self,\n        wsgi_application: \"WSGIAppType\",\n        executor: concurrent.futures.Executor = None,\n    ) -> None:\n        self.wsgi_application = wsgi_application\n        self.executor = dummy_executor if executor is None else executor\n\n    def __call__(self, request: httputil.HTTPServerRequest) -> None:\n        IOLoop.current().spawn_callback(self.handle_request, request)\n\n    async def handle_request(self, request: httputil.HTTPServerRequest) -> None:\n        data = {}  # type: Dict[str, Any]\n        response = []  # type: List[bytes]\n\n        def start_response(\n            status: str,\n            headers: List[Tuple[str, str]],\n            exc_info: Optional[\n                Tuple[\n                    \"Optional[Type[BaseException]]\",\n                    Optional[BaseException],\n                    Optional[TracebackType],\n                ]\n            ] = None,\n        ) -> Callable[[bytes], Any]:\n            data[\"status\"] = status\n            data[\"headers\"] = headers\n            return response.append\n\n        loop = IOLoop.current()\n        app_response = await loop.run_in_executor(\n            self.executor,\n            self.wsgi_application,\n            self.environ(request),\n            start_response,\n        )\n        try:\n            response.extend(app_response)\n            body = b\"\".join(response)\n        finally:\n            if hasattr(app_response, \"close\"):\n                app_response.close()  # type: ignore\n        if not data:\n            raise Exception(\"WSGI app did not call start_response\")\n\n        status_code_str, reason = data[\"status\"].split(\" \", 1)\n        status_code = int(status_code_str)\n        headers = data[\"headers\"]  # type: List[Tuple[str, str]]\n        header_set = set(k.lower() for (k, v) in headers)\n        body = escape.utf8(body)\n        if status_code != 304:\n            if \"content-length\" not in header_set:\n                headers.append((\"Content-Length\", str(len(body))))\n            if \"content-type\" not in header_set:\n                headers.append((\"Content-Type\", \"text/html; charset=UTF-8\"))\n        if \"server\" not in header_set:\n            headers.append((\"Server\", \"TornadoServer/%s\" % tornado.version))\n\n        start_line = httputil.ResponseStartLine(\"HTTP/1.1\", status_code, reason)\n        header_obj = httputil.HTTPHeaders()\n        for key, value in headers:\n            header_obj.add(key, value)\n        assert request.connection is not None\n        request.connection.write_headers(start_line, header_obj, chunk=body)\n        request.connection.finish()\n        self._log(status_code, request)\n\n    @staticmethod\n    def environ(request: httputil.HTTPServerRequest) -> Dict[Text, Any]:\n        \"\"\"Converts a `tornado.httputil.HTTPServerRequest` to a WSGI environment.\"\"\"\n        hostport = request.host.split(\":\")\n        if len(hostport) == 2:\n            host = hostport[0]\n            port = int(hostport[1])\n        else:\n            host = request.host\n            port = 443 if request.protocol == \"https\" else 80\n        environ = {\n            \"REQUEST_METHOD\": request.method,\n            \"SCRIPT_NAME\": \"\",\n            \"PATH_INFO\": to_wsgi_str(\n                escape.url_unescape(request.path, encoding=None, plus=False)\n            ),\n            \"QUERY_STRING\": request.query,\n            \"REMOTE_ADDR\": request.remote_ip,\n            \"SERVER_NAME\": host,\n            \"SERVER_PORT\": str(port),\n            \"SERVER_PROTOCOL\": request.version,\n            \"wsgi.version\": (1, 0),\n            \"wsgi.url_scheme\": request.protocol,\n            \"wsgi.input\": BytesIO(escape.utf8(request.body)),\n            \"wsgi.errors\": sys.stderr,\n            \"wsgi.multithread\": False,\n            \"wsgi.multiprocess\": True,\n            \"wsgi.run_once\": False,\n        }\n        if \"Content-Type\" in request.headers:\n            environ[\"CONTENT_TYPE\"] = request.headers.pop(\"Content-Type\")\n        if \"Content-Length\" in request.headers:\n            environ[\"CONTENT_LENGTH\"] = request.headers.pop(\"Content-Length\")\n        for key, value in request.headers.items():\n            environ[\"HTTP_\" + key.replace(\"-\", \"_\").upper()] = value\n        return environ\n\n    def _log(self, status_code: int, request: httputil.HTTPServerRequest) -> None:\n        if status_code < 400:\n            log_method = access_log.info\n        elif status_code < 500:\n            log_method = access_log.warning\n        else:\n            log_method = access_log.error\n        request_time = 1000.0 * request.request_time()\n        assert request.method is not None\n        assert request.uri is not None\n        summary = (\n            request.method  # type: ignore[operator]\n            + \" \"\n            + request.uri\n            + \" (\"\n            + request.remote_ip\n            + \")\"\n        )\n        log_method(\"%d %s %.2fms\", status_code, summary, request_time)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 117,
                            "end_lineno": 123,
                            "parent": {
                                "file_name": "tornado/wsgi.py",
                                "type": "class",
                                "name": "WSGIContainer",
                                "content": "class WSGIContainer(object):\n    r\"\"\"Makes a WSGI-compatible function runnable on Tornado's HTTP server.\n\n    .. warning::\n\n       WSGI is a *synchronous* interface, while Tornado's concurrency model\n       is based on single-threaded asynchronous execution.  This means that\n       running a WSGI app with Tornado's `WSGIContainer` is *less scalable*\n       than running the same app in a multi-threaded WSGI server like\n       ``gunicorn`` or ``uwsgi``.  Use `WSGIContainer` only when there are\n       benefits to combining Tornado and WSGI in the same process that\n       outweigh the reduced scalability.\n\n    Wrap a WSGI function in a `WSGIContainer` and pass it to `.HTTPServer` to\n    run it. For example::\n\n        def simple_app(environ, start_response):\n            status = \"200 OK\"\n            response_headers = [(\"Content-type\", \"text/plain\")]\n            start_response(status, response_headers)\n            return [b\"Hello world!\\n\"]\n\n        async def main():\n            container = tornado.wsgi.WSGIContainer(simple_app)\n            http_server = tornado.httpserver.HTTPServer(container)\n            http_server.listen(8888)\n            await asyncio.Event().wait()\n\n        asyncio.run(main())\n\n    This class is intended to let other frameworks (Django, web.py, etc)\n    run on the Tornado HTTP server and I/O loop.\n\n    The `tornado.web.FallbackHandler` class is often useful for mixing\n    Tornado and WSGI apps in the same server.  See\n    https://github.com/bdarnell/django-tornado-demo for a complete example.\n\n    `WSGIContainer` supports executing the WSGI application in custom executors\n    using `IOLoop.run_in_executor`. The default executor uses\n    `tornado.concurrent.dummy_executor` which works synchronously, but other\n    executors subclassing `concurrent.futures.Executor` may be used. To execute\n    WSGI application code in separate threads in an event-loop compatible way\n    use::\n\n        async def main():\n            executor = concurrent.futures.ThreadPoolExecutor()\n            # ^-- Execute requests in separate threads.\n            container = tornado.wsgi.WSGIContainer(simple_app, executor)\n            # Initialize the WSGI container with custom executor --^\n            http_server = tornado.httpserver.HTTPServer(container)\n            http_server.listen(8888)\n            await asyncio.Event().wait()\n\n    Running the WSGI app with a `ThreadPoolExecutor` remains *less scalable*\n    than running the same app in a multi-threaded WSGI server like ``gunicorn``\n    or ``uwsgi``.\n    \"\"\"\n\n    def __init__(\n        self,\n        wsgi_application: \"WSGIAppType\",\n        executor: concurrent.futures.Executor = None,\n    ) -> None:\n        self.wsgi_application = wsgi_application\n        self.executor = dummy_executor if executor is None else executor\n\n    def __call__(self, request: httputil.HTTPServerRequest) -> None:\n        IOLoop.current().spawn_callback(self.handle_request, request)\n\n    async def handle_request(self, request: httputil.HTTPServerRequest) -> None:\n        data = {}  # type: Dict[str, Any]\n        response = []  # type: List[bytes]\n\n        def start_response(\n            status: str,\n            headers: List[Tuple[str, str]],\n            exc_info: Optional[\n                Tuple[\n                    \"Optional[Type[BaseException]]\",\n                    Optional[BaseException],\n                    Optional[TracebackType],\n                ]\n            ] = None,\n        ) -> Callable[[bytes], Any]:\n            data[\"status\"] = status\n            data[\"headers\"] = headers\n            return response.append\n\n        loop = IOLoop.current()\n        app_response = await loop.run_in_executor(\n            self.executor,\n            self.wsgi_application,\n            self.environ(request),\n            start_response,\n        )\n        try:\n            response.extend(app_response)\n            body = b\"\".join(response)\n        finally:\n            if hasattr(app_response, \"close\"):\n                app_response.close()  # type: ignore\n        if not data:\n            raise Exception(\"WSGI app did not call start_response\")\n\n        status_code_str, reason = data[\"status\"].split(\" \", 1)\n        status_code = int(status_code_str)\n        headers = data[\"headers\"]  # type: List[Tuple[str, str]]\n        header_set = set(k.lower() for (k, v) in headers)\n        body = escape.utf8(body)\n        if status_code != 304:\n            if \"content-length\" not in header_set:\n                headers.append((\"Content-Length\", str(len(body))))\n            if \"content-type\" not in header_set:\n                headers.append((\"Content-Type\", \"text/html; charset=UTF-8\"))\n        if \"server\" not in header_set:\n            headers.append((\"Server\", \"TornadoServer/%s\" % tornado.version))\n\n        start_line = httputil.ResponseStartLine(\"HTTP/1.1\", status_code, reason)\n        header_obj = httputil.HTTPHeaders()\n        for key, value in headers:\n            header_obj.add(key, value)\n        assert request.connection is not None\n        request.connection.write_headers(start_line, header_obj, chunk=body)\n        request.connection.finish()\n        self._log(status_code, request)\n\n    @staticmethod\n    def environ(request: httputil.HTTPServerRequest) -> Dict[Text, Any]:\n        \"\"\"Converts a `tornado.httputil.HTTPServerRequest` to a WSGI environment.\"\"\"\n        hostport = request.host.split(\":\")\n        if len(hostport) == 2:\n            host = hostport[0]\n            port = int(hostport[1])\n        else:\n            host = request.host\n            port = 443 if request.protocol == \"https\" else 80\n        environ = {\n            \"REQUEST_METHOD\": request.method,\n            \"SCRIPT_NAME\": \"\",\n            \"PATH_INFO\": to_wsgi_str(\n                escape.url_unescape(request.path, encoding=None, plus=False)\n            ),\n            \"QUERY_STRING\": request.query,\n            \"REMOTE_ADDR\": request.remote_ip,\n            \"SERVER_NAME\": host,\n            \"SERVER_PORT\": str(port),\n            \"SERVER_PROTOCOL\": request.version,\n            \"wsgi.version\": (1, 0),\n            \"wsgi.url_scheme\": request.protocol,\n            \"wsgi.input\": BytesIO(escape.utf8(request.body)),\n            \"wsgi.errors\": sys.stderr,\n            \"wsgi.multithread\": False,\n            \"wsgi.multiprocess\": True,\n            \"wsgi.run_once\": False,\n        }\n        if \"Content-Type\" in request.headers:\n            environ[\"CONTENT_TYPE\"] = request.headers.pop(\"Content-Type\")\n        if \"Content-Length\" in request.headers:\n            environ[\"CONTENT_LENGTH\"] = request.headers.pop(\"Content-Length\")\n        for key, value in request.headers.items():\n            environ[\"HTTP_\" + key.replace(\"-\", \"_\").upper()] = value\n        return environ\n\n    def _log(self, status_code: int, request: httputil.HTTPServerRequest) -> None:\n        if status_code < 400:\n            log_method = access_log.info\n        elif status_code < 500:\n            log_method = access_log.warning\n        else:\n            log_method = access_log.error\n        request_time = 1000.0 * request.request_time()\n        assert request.method is not None\n        assert request.uri is not None\n        summary = (\n            request.method  # type: ignore[operator]\n            + \" \"\n            + request.uri\n            + \" (\"\n            + request.remote_ip\n            + \")\"\n        )\n        log_method(\"%d %s %.2fms\", status_code, summary, request_time)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 59,
                                "end_lineno": 240,
                                "parent": null
                            }
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 152,
                            "length": 11
                        },
                        "new_range": {
                            "start": 152,
                            "length": 25
                        },
                        "section": "class WSGIContainer(object):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "            start_response,",
                                "type": "context"
                            },
                            {
                                "content": "        )",
                                "type": "context"
                            },
                            {
                                "content": "        try:",
                                "type": "context"
                            },
                            {
                                "content": "            response.extend(app_response)",
                                "type": "deleted"
                            },
                            {
                                "content": "            body = b\"\".join(response)",
                                "type": "deleted"
                            },
                            {
                                "content": "            app_response_iter = iter(app_response)",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "            def next_chunk() -> Optional[bytes]:",
                                "type": "added"
                            },
                            {
                                "content": "                try:",
                                "type": "added"
                            },
                            {
                                "content": "                    return next(app_response_iter)",
                                "type": "added"
                            },
                            {
                                "content": "                except StopIteration:",
                                "type": "added"
                            },
                            {
                                "content": "                    # StopIteration is special and is not allowed to pass through",
                                "type": "added"
                            },
                            {
                                "content": "                    # coroutines normally.",
                                "type": "added"
                            },
                            {
                                "content": "                    return None",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "            while True:",
                                "type": "added"
                            },
                            {
                                "content": "                chunk = await loop.run_in_executor(self.executor, next_chunk)",
                                "type": "added"
                            },
                            {
                                "content": "                if chunk is None:",
                                "type": "added"
                            },
                            {
                                "content": "                    break",
                                "type": "added"
                            },
                            {
                                "content": "                response.append(chunk)",
                                "type": "added"
                            },
                            {
                                "content": "        finally:",
                                "type": "context"
                            },
                            {
                                "content": "            if hasattr(app_response, \"close\"):",
                                "type": "context"
                            },
                            {
                                "content": "                app_response.close()  # type: ignore",
                                "type": "context"
                            },
                            {
                                "content": "        body = b\"\".join(response)",
                                "type": "added"
                            },
                            {
                                "content": "        if not data:",
                                "type": "context"
                            },
                            {
                                "content": "            raise Exception(\"WSGI app did not call start_response\")",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/wsgi.py",
                            "type": "class",
                            "name": "WSGIContainer",
                            "content": "class WSGIContainer(object):\n    r\"\"\"Makes a WSGI-compatible function runnable on Tornado's HTTP server.\n\n    .. warning::\n\n       WSGI is a *synchronous* interface, while Tornado's concurrency model\n       is based on single-threaded asynchronous execution.  This means that\n       running a WSGI app with Tornado's `WSGIContainer` is *less scalable*\n       than running the same app in a multi-threaded WSGI server like\n       ``gunicorn`` or ``uwsgi``.  Use `WSGIContainer` only when there are\n       benefits to combining Tornado and WSGI in the same process that\n       outweigh the reduced scalability.\n\n    Wrap a WSGI function in a `WSGIContainer` and pass it to `.HTTPServer` to\n    run it. For example::\n\n        def simple_app(environ, start_response):\n            status = \"200 OK\"\n            response_headers = [(\"Content-type\", \"text/plain\")]\n            start_response(status, response_headers)\n            return [b\"Hello world!\\n\"]\n\n        async def main():\n            container = tornado.wsgi.WSGIContainer(simple_app)\n            http_server = tornado.httpserver.HTTPServer(container)\n            http_server.listen(8888)\n            await asyncio.Event().wait()\n\n        asyncio.run(main())\n\n    This class is intended to let other frameworks (Django, web.py, etc)\n    run on the Tornado HTTP server and I/O loop.\n\n    The `tornado.web.FallbackHandler` class is often useful for mixing\n    Tornado and WSGI apps in the same server.  See\n    https://github.com/bdarnell/django-tornado-demo for a complete example.\n\n    `WSGIContainer` supports executing the WSGI application in custom executors\n    using `IOLoop.run_in_executor`. The default executor uses\n    `tornado.concurrent.dummy_executor` which works synchronously, but other\n    executors subclassing `concurrent.futures.Executor` may be used. To execute\n    WSGI application code in separate threads in an event-loop compatible way\n    use::\n\n        async def main():\n            executor = concurrent.futures.ThreadPoolExecutor()\n            # ^-- Execute requests in separate threads.\n            container = tornado.wsgi.WSGIContainer(simple_app, executor)\n            # Initialize the WSGI container with custom executor --^\n            http_server = tornado.httpserver.HTTPServer(container)\n            http_server.listen(8888)\n            await asyncio.Event().wait()\n\n    Running the WSGI app with a `ThreadPoolExecutor` remains *less scalable*\n    than running the same app in a multi-threaded WSGI server like ``gunicorn``\n    or ``uwsgi``.\n    \"\"\"\n\n    def __init__(\n        self,\n        wsgi_application: \"WSGIAppType\",\n        executor: concurrent.futures.Executor = None,\n    ) -> None:\n        self.wsgi_application = wsgi_application\n        self.executor = dummy_executor if executor is None else executor\n\n    def __call__(self, request: httputil.HTTPServerRequest) -> None:\n        IOLoop.current().spawn_callback(self.handle_request, request)\n\n    async def handle_request(self, request: httputil.HTTPServerRequest) -> None:\n        data = {}  # type: Dict[str, Any]\n        response = []  # type: List[bytes]\n\n        def start_response(\n            status: str,\n            headers: List[Tuple[str, str]],\n            exc_info: Optional[\n                Tuple[\n                    \"Optional[Type[BaseException]]\",\n                    Optional[BaseException],\n                    Optional[TracebackType],\n                ]\n            ] = None,\n        ) -> Callable[[bytes], Any]:\n            data[\"status\"] = status\n            data[\"headers\"] = headers\n            return response.append\n\n        loop = IOLoop.current()\n        app_response = await loop.run_in_executor(\n            self.executor,\n            self.wsgi_application,\n            self.environ(request),\n            start_response,\n        )\n        try:\n            response.extend(app_response)\n            body = b\"\".join(response)\n        finally:\n            if hasattr(app_response, \"close\"):\n                app_response.close()  # type: ignore\n        if not data:\n            raise Exception(\"WSGI app did not call start_response\")\n\n        status_code_str, reason = data[\"status\"].split(\" \", 1)\n        status_code = int(status_code_str)\n        headers = data[\"headers\"]  # type: List[Tuple[str, str]]\n        header_set = set(k.lower() for (k, v) in headers)\n        body = escape.utf8(body)\n        if status_code != 304:\n            if \"content-length\" not in header_set:\n                headers.append((\"Content-Length\", str(len(body))))\n            if \"content-type\" not in header_set:\n                headers.append((\"Content-Type\", \"text/html; charset=UTF-8\"))\n        if \"server\" not in header_set:\n            headers.append((\"Server\", \"TornadoServer/%s\" % tornado.version))\n\n        start_line = httputil.ResponseStartLine(\"HTTP/1.1\", status_code, reason)\n        header_obj = httputil.HTTPHeaders()\n        for key, value in headers:\n            header_obj.add(key, value)\n        assert request.connection is not None\n        request.connection.write_headers(start_line, header_obj, chunk=body)\n        request.connection.finish()\n        self._log(status_code, request)\n\n    @staticmethod\n    def environ(request: httputil.HTTPServerRequest) -> Dict[Text, Any]:\n        \"\"\"Converts a `tornado.httputil.HTTPServerRequest` to a WSGI environment.\"\"\"\n        hostport = request.host.split(\":\")\n        if len(hostport) == 2:\n            host = hostport[0]\n            port = int(hostport[1])\n        else:\n            host = request.host\n            port = 443 if request.protocol == \"https\" else 80\n        environ = {\n            \"REQUEST_METHOD\": request.method,\n            \"SCRIPT_NAME\": \"\",\n            \"PATH_INFO\": to_wsgi_str(\n                escape.url_unescape(request.path, encoding=None, plus=False)\n            ),\n            \"QUERY_STRING\": request.query,\n            \"REMOTE_ADDR\": request.remote_ip,\n            \"SERVER_NAME\": host,\n            \"SERVER_PORT\": str(port),\n            \"SERVER_PROTOCOL\": request.version,\n            \"wsgi.version\": (1, 0),\n            \"wsgi.url_scheme\": request.protocol,\n            \"wsgi.input\": BytesIO(escape.utf8(request.body)),\n            \"wsgi.errors\": sys.stderr,\n            \"wsgi.multithread\": False,\n            \"wsgi.multiprocess\": True,\n            \"wsgi.run_once\": False,\n        }\n        if \"Content-Type\" in request.headers:\n            environ[\"CONTENT_TYPE\"] = request.headers.pop(\"Content-Type\")\n        if \"Content-Length\" in request.headers:\n            environ[\"CONTENT_LENGTH\"] = request.headers.pop(\"Content-Length\")\n        for key, value in request.headers.items():\n            environ[\"HTTP_\" + key.replace(\"-\", \"_\").upper()] = value\n        return environ\n\n    def _log(self, status_code: int, request: httputil.HTTPServerRequest) -> None:\n        if status_code < 400:\n            log_method = access_log.info\n        elif status_code < 500:\n            log_method = access_log.warning\n        else:\n            log_method = access_log.error\n        request_time = 1000.0 * request.request_time()\n        assert request.method is not None\n        assert request.uri is not None\n        summary = (\n            request.method  # type: ignore[operator]\n            + \" \"\n            + request.uri\n            + \" (\"\n            + request.remote_ip\n            + \")\"\n        )\n        log_method(\"%d %s %.2fms\", status_code, summary, request_time)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 59,
                            "end_lineno": 240,
                            "parent": null
                        },
                        {
                            "file_name": "tornado/wsgi.py",
                            "type": "method",
                            "name": "WSGIContainer.handle_request",
                            "content": "class WSGIContainer(object):\n    r\"\"\"Makes a WSGI-compatible function runnable on Tornado's HTTP server.\n\n    .. warning::\n\n       WSGI is a *synchronous* interface, while Tornado's concurrency model\n       is based on single-threaded asynchronous execution.  This means that\n       running a WSGI app with Tornado's `WSGIContainer` is *less scalable*\n       than running the same app in a multi-threaded WSGI server like\n       ``gunicorn`` or ``uwsgi``.  Use `WSGIContainer` only when there are\n       benefits to combining Tornado and WSGI in the same process that\n       outweigh the reduced scalability.\n\n    Wrap a WSGI function in a `WSGIContainer` and pass it to `.HTTPServer` to\n    run it. For example::\n\n        def simple_app(environ, start_response):\n            status = \"200 OK\"\n            response_headers = [(\"Content-type\", \"text/plain\")]\n            start_response(status, response_headers)\n            return [b\"Hello world!\\n\"]\n\n        async def main():\n            container = tornado.wsgi.WSGIContainer(simple_app)\n            http_server = tornado.httpserver.HTTPServer(container)\n            http_server.listen(8888)\n            await asyncio.Event().wait()\n\n        asyncio.run(main())\n\n    This class is intended to let other frameworks (Django, web.py, etc)\n    run on the Tornado HTTP server and I/O loop.\n\n    The `tornado.web.FallbackHandler` class is often useful for mixing\n    Tornado and WSGI apps in the same server.  See\n    https://github.com/bdarnell/django-tornado-demo for a complete example.\n\n    `WSGIContainer` supports executing the WSGI application in custom executors\n    using `IOLoop.run_in_executor`. The default executor uses\n    `tornado.concurrent.dummy_executor` which works synchronously, but other\n    executors subclassing `concurrent.futures.Executor` may be used. To execute\n    WSGI application code in separate threads in an event-loop compatible way\n    use::\n\n        async def main():\n            executor = concurrent.futures.ThreadPoolExecutor()\n            # ^-- Execute requests in separate threads.\n            container = tornado.wsgi.WSGIContainer(simple_app, executor)\n            # Initialize the WSGI container with custom executor --^\n            http_server = tornado.httpserver.HTTPServer(container)\n            http_server.listen(8888)\n            await asyncio.Event().wait()\n\n    Running the WSGI app with a `ThreadPoolExecutor` remains *less scalable*\n    than running the same app in a multi-threaded WSGI server like ``gunicorn``\n    or ``uwsgi``.\n    \"\"\"\n\n    def __init__(\n        self,\n        wsgi_application: \"WSGIAppType\",\n        executor: concurrent.futures.Executor = None,\n    ) -> None:\n        self.wsgi_application = wsgi_application\n        self.executor = dummy_executor if executor is None else executor\n\n    def __call__(self, request: httputil.HTTPServerRequest) -> None:\n        IOLoop.current().spawn_callback(self.handle_request, request)\n\n    async def handle_request(self, request: httputil.HTTPServerRequest) -> None:\n        data = {}  # type: Dict[str, Any]\n        response = []  # type: List[bytes]\n\n        def start_response(\n            status: str,\n            headers: List[Tuple[str, str]],\n            exc_info: Optional[\n                Tuple[\n                    \"Optional[Type[BaseException]]\",\n                    Optional[BaseException],\n                    Optional[TracebackType],\n                ]\n            ] = None,\n        ) -> Callable[[bytes], Any]:\n            data[\"status\"] = status\n            data[\"headers\"] = headers\n            return response.append\n\n        loop = IOLoop.current()\n        app_response = await loop.run_in_executor(\n            self.executor,\n            self.wsgi_application,\n            self.environ(request),\n            start_response,\n        )\n        try:\n            response.extend(app_response)\n            body = b\"\".join(response)\n        finally:\n            if hasattr(app_response, \"close\"):\n                app_response.close()  # type: ignore\n        if not data:\n            raise Exception(\"WSGI app did not call start_response\")\n\n        status_code_str, reason = data[\"status\"].split(\" \", 1)\n        status_code = int(status_code_str)\n        headers = data[\"headers\"]  # type: List[Tuple[str, str]]\n        header_set = set(k.lower() for (k, v) in headers)\n        body = escape.utf8(body)\n        if status_code != 304:\n            if \"content-length\" not in header_set:\n                headers.append((\"Content-Length\", str(len(body))))\n            if \"content-type\" not in header_set:\n                headers.append((\"Content-Type\", \"text/html; charset=UTF-8\"))\n        if \"server\" not in header_set:\n            headers.append((\"Server\", \"TornadoServer/%s\" % tornado.version))\n\n        start_line = httputil.ResponseStartLine(\"HTTP/1.1\", status_code, reason)\n        header_obj = httputil.HTTPHeaders()\n        for key, value in headers:\n            header_obj.add(key, value)\n        assert request.connection is not None\n        request.connection.write_headers(start_line, header_obj, chunk=body)\n        request.connection.finish()\n        self._log(status_code, request)\n\n    @staticmethod\n    def environ(request: httputil.HTTPServerRequest) -> Dict[Text, Any]:\n        \"\"\"Converts a `tornado.httputil.HTTPServerRequest` to a WSGI environment.\"\"\"\n        hostport = request.host.split(\":\")\n        if len(hostport) == 2:\n            host = hostport[0]\n            port = int(hostport[1])\n        else:\n            host = request.host\n            port = 443 if request.protocol == \"https\" else 80\n        environ = {\n            \"REQUEST_METHOD\": request.method,\n            \"SCRIPT_NAME\": \"\",\n            \"PATH_INFO\": to_wsgi_str(\n                escape.url_unescape(request.path, encoding=None, plus=False)\n            ),\n            \"QUERY_STRING\": request.query,\n            \"REMOTE_ADDR\": request.remote_ip,\n            \"SERVER_NAME\": host,\n            \"SERVER_PORT\": str(port),\n            \"SERVER_PROTOCOL\": request.version,\n            \"wsgi.version\": (1, 0),\n            \"wsgi.url_scheme\": request.protocol,\n            \"wsgi.input\": BytesIO(escape.utf8(request.body)),\n            \"wsgi.errors\": sys.stderr,\n            \"wsgi.multithread\": False,\n            \"wsgi.multiprocess\": True,\n            \"wsgi.run_once\": False,\n        }\n        if \"Content-Type\" in request.headers:\n            environ[\"CONTENT_TYPE\"] = request.headers.pop(\"Content-Type\")\n        if \"Content-Length\" in request.headers:\n            environ[\"CONTENT_LENGTH\"] = request.headers.pop(\"Content-Length\")\n        for key, value in request.headers.items():\n            environ[\"HTTP_\" + key.replace(\"-\", \"_\").upper()] = value\n        return environ\n\n    def _log(self, status_code: int, request: httputil.HTTPServerRequest) -> None:\n        if status_code < 400:\n            log_method = access_log.info\n        elif status_code < 500:\n            log_method = access_log.warning\n        else:\n            log_method = access_log.error\n        request_time = 1000.0 * request.request_time()\n        assert request.method is not None\n        assert request.uri is not None\n        summary = (\n            request.method  # type: ignore[operator]\n            + \" \"\n            + request.uri\n            + \" (\"\n            + request.remote_ip\n            + \")\"\n        )\n        log_method(\"%d %s %.2fms\", status_code, summary, request_time)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 128,
                            "end_lineno": 183,
                            "parent": {
                                "file_name": "tornado/wsgi.py",
                                "type": "class",
                                "name": "WSGIContainer",
                                "content": "class WSGIContainer(object):\n    r\"\"\"Makes a WSGI-compatible function runnable on Tornado's HTTP server.\n\n    .. warning::\n\n       WSGI is a *synchronous* interface, while Tornado's concurrency model\n       is based on single-threaded asynchronous execution.  This means that\n       running a WSGI app with Tornado's `WSGIContainer` is *less scalable*\n       than running the same app in a multi-threaded WSGI server like\n       ``gunicorn`` or ``uwsgi``.  Use `WSGIContainer` only when there are\n       benefits to combining Tornado and WSGI in the same process that\n       outweigh the reduced scalability.\n\n    Wrap a WSGI function in a `WSGIContainer` and pass it to `.HTTPServer` to\n    run it. For example::\n\n        def simple_app(environ, start_response):\n            status = \"200 OK\"\n            response_headers = [(\"Content-type\", \"text/plain\")]\n            start_response(status, response_headers)\n            return [b\"Hello world!\\n\"]\n\n        async def main():\n            container = tornado.wsgi.WSGIContainer(simple_app)\n            http_server = tornado.httpserver.HTTPServer(container)\n            http_server.listen(8888)\n            await asyncio.Event().wait()\n\n        asyncio.run(main())\n\n    This class is intended to let other frameworks (Django, web.py, etc)\n    run on the Tornado HTTP server and I/O loop.\n\n    The `tornado.web.FallbackHandler` class is often useful for mixing\n    Tornado and WSGI apps in the same server.  See\n    https://github.com/bdarnell/django-tornado-demo for a complete example.\n\n    `WSGIContainer` supports executing the WSGI application in custom executors\n    using `IOLoop.run_in_executor`. The default executor uses\n    `tornado.concurrent.dummy_executor` which works synchronously, but other\n    executors subclassing `concurrent.futures.Executor` may be used. To execute\n    WSGI application code in separate threads in an event-loop compatible way\n    use::\n\n        async def main():\n            executor = concurrent.futures.ThreadPoolExecutor()\n            # ^-- Execute requests in separate threads.\n            container = tornado.wsgi.WSGIContainer(simple_app, executor)\n            # Initialize the WSGI container with custom executor --^\n            http_server = tornado.httpserver.HTTPServer(container)\n            http_server.listen(8888)\n            await asyncio.Event().wait()\n\n    Running the WSGI app with a `ThreadPoolExecutor` remains *less scalable*\n    than running the same app in a multi-threaded WSGI server like ``gunicorn``\n    or ``uwsgi``.\n    \"\"\"\n\n    def __init__(\n        self,\n        wsgi_application: \"WSGIAppType\",\n        executor: concurrent.futures.Executor = None,\n    ) -> None:\n        self.wsgi_application = wsgi_application\n        self.executor = dummy_executor if executor is None else executor\n\n    def __call__(self, request: httputil.HTTPServerRequest) -> None:\n        IOLoop.current().spawn_callback(self.handle_request, request)\n\n    async def handle_request(self, request: httputil.HTTPServerRequest) -> None:\n        data = {}  # type: Dict[str, Any]\n        response = []  # type: List[bytes]\n\n        def start_response(\n            status: str,\n            headers: List[Tuple[str, str]],\n            exc_info: Optional[\n                Tuple[\n                    \"Optional[Type[BaseException]]\",\n                    Optional[BaseException],\n                    Optional[TracebackType],\n                ]\n            ] = None,\n        ) -> Callable[[bytes], Any]:\n            data[\"status\"] = status\n            data[\"headers\"] = headers\n            return response.append\n\n        loop = IOLoop.current()\n        app_response = await loop.run_in_executor(\n            self.executor,\n            self.wsgi_application,\n            self.environ(request),\n            start_response,\n        )\n        try:\n            response.extend(app_response)\n            body = b\"\".join(response)\n        finally:\n            if hasattr(app_response, \"close\"):\n                app_response.close()  # type: ignore\n        if not data:\n            raise Exception(\"WSGI app did not call start_response\")\n\n        status_code_str, reason = data[\"status\"].split(\" \", 1)\n        status_code = int(status_code_str)\n        headers = data[\"headers\"]  # type: List[Tuple[str, str]]\n        header_set = set(k.lower() for (k, v) in headers)\n        body = escape.utf8(body)\n        if status_code != 304:\n            if \"content-length\" not in header_set:\n                headers.append((\"Content-Length\", str(len(body))))\n            if \"content-type\" not in header_set:\n                headers.append((\"Content-Type\", \"text/html; charset=UTF-8\"))\n        if \"server\" not in header_set:\n            headers.append((\"Server\", \"TornadoServer/%s\" % tornado.version))\n\n        start_line = httputil.ResponseStartLine(\"HTTP/1.1\", status_code, reason)\n        header_obj = httputil.HTTPHeaders()\n        for key, value in headers:\n            header_obj.add(key, value)\n        assert request.connection is not None\n        request.connection.write_headers(start_line, header_obj, chunk=body)\n        request.connection.finish()\n        self._log(status_code, request)\n\n    @staticmethod\n    def environ(request: httputil.HTTPServerRequest) -> Dict[Text, Any]:\n        \"\"\"Converts a `tornado.httputil.HTTPServerRequest` to a WSGI environment.\"\"\"\n        hostport = request.host.split(\":\")\n        if len(hostport) == 2:\n            host = hostport[0]\n            port = int(hostport[1])\n        else:\n            host = request.host\n            port = 443 if request.protocol == \"https\" else 80\n        environ = {\n            \"REQUEST_METHOD\": request.method,\n            \"SCRIPT_NAME\": \"\",\n            \"PATH_INFO\": to_wsgi_str(\n                escape.url_unescape(request.path, encoding=None, plus=False)\n            ),\n            \"QUERY_STRING\": request.query,\n            \"REMOTE_ADDR\": request.remote_ip,\n            \"SERVER_NAME\": host,\n            \"SERVER_PORT\": str(port),\n            \"SERVER_PROTOCOL\": request.version,\n            \"wsgi.version\": (1, 0),\n            \"wsgi.url_scheme\": request.protocol,\n            \"wsgi.input\": BytesIO(escape.utf8(request.body)),\n            \"wsgi.errors\": sys.stderr,\n            \"wsgi.multithread\": False,\n            \"wsgi.multiprocess\": True,\n            \"wsgi.run_once\": False,\n        }\n        if \"Content-Type\" in request.headers:\n            environ[\"CONTENT_TYPE\"] = request.headers.pop(\"Content-Type\")\n        if \"Content-Length\" in request.headers:\n            environ[\"CONTENT_LENGTH\"] = request.headers.pop(\"Content-Length\")\n        for key, value in request.headers.items():\n            environ[\"HTTP_\" + key.replace(\"-\", \"_\").upper()] = value\n        return environ\n\n    def _log(self, status_code: int, request: httputil.HTTPServerRequest) -> None:\n        if status_code < 400:\n            log_method = access_log.info\n        elif status_code < 500:\n            log_method = access_log.warning\n        else:\n            log_method = access_log.error\n        request_time = 1000.0 * request.request_time()\n        assert request.method is not None\n        assert request.uri is not None\n        summary = (\n            request.method  # type: ignore[operator]\n            + \" \"\n            + request.uri\n            + \" (\"\n            + request.remote_ip\n            + \")\"\n        )\n        log_method(\"%d %s %.2fms\", status_code, summary, request_time)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 59,
                                "end_lineno": 240,
                                "parent": null
                            }
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        }
    ],
    "old_commit_hash": "ea03332e204a357bb43b2f106a9868b3701d0623^",
    "new_commit_hash": "ea03332e204a357bb43b2f106a9868b3701d0623",
    "commit_message": "wsgi: Iterate the response in executor too",
    "commit_date": "2023-02-16T20:37:56Z",
    "metadata": {}
}
{
    "repo_name": "tornado",
    "new_commit_hash": "ea03332e204a357bb43b2f106a9868b3701d0623",
    "test_file_codes": [
        "import asyncio\nimport concurrent.futures\nimport threading\n\nfrom wsgiref.validate import validator\n\nfrom tornado.routing import RuleRouter\nfrom tornado.testing import AsyncHTTPTestCase, gen_test\nfrom tornado.wsgi import WSGIContainer\n\n\nclass WSGIAppMixin:\n    # TODO: Now that WSGIAdapter is gone, this is a pretty weak test.\n    def get_executor(self):\n        raise NotImplementedError()\n\n    def get_app(self):\n        executor = self.get_executor()\n        # The barrier test in DummyExecutorTest will always wait the full\n        # value of this timeout, so we don't want it to be too high.\n        self.barrier = threading.Barrier(2, timeout=0.3)\n\n        def make_container(app):\n            return WSGIContainer(validator(app), executor=executor)\n\n        return RuleRouter(\n            [\n                (\"/simple\", make_container(self.simple_wsgi_app)),\n                (\"/barrier\", make_container(self.barrier_wsgi_app)),\n                (\"/streaming_barrier\", make_container(self.streaming_barrier_wsgi_app)),\n            ]\n        )\n\n    def respond_plain(self, start_response):\n        status = \"200 OK\"\n        response_headers = [(\"Content-Type\", \"text/plain\")]\n        start_response(status, response_headers)\n\n    def simple_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        return [b\"Hello world!\"]\n\n    def barrier_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        try:\n            n = self.barrier.wait()\n        except threading.BrokenBarrierError:\n            return [b\"broken barrier\"]\n        else:\n            return [b\"ok %d\" % n]\n\n    def streaming_barrier_wsgi_app(self, environ, start_response):\n        self.respond_plain(start_response)\n        yield b\"ok \"\n        try:\n            n = self.barrier.wait()\n        except threading.BrokenBarrierError:\n            yield b\"broken barrier\"\n        else:\n            yield b\"%d\" % n\n\n\nclass WSGIContainerDummyExecutorTest(WSGIAppMixin, AsyncHTTPTestCase):\n    def get_executor(self):\n        return None\n\n    def test_simple(self):\n        response = self.fetch(\"/simple\")\n        self.assertEqual(response.body, b\"Hello world!\")\n\n    @gen_test\n    async def test_concurrent_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n        )\n        for resp in resps:\n            self.assertEqual(resp.body, b\"broken barrier\")\n\n    @gen_test\n    async def test_concurrent_streaming_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n        )\n        for resp in resps:\n            self.assertEqual(resp.body, b\"ok broken barrier\")\n\n\nclass WSGIContainerThreadPoolTest(WSGIAppMixin, AsyncHTTPTestCase):\n    def get_executor(self):\n        return concurrent.futures.ThreadPoolExecutor()\n\n    def test_simple(self):\n        response = self.fetch(\"/simple\")\n        self.assertEqual(response.body, b\"Hello world!\")\n\n    @gen_test\n    async def test_concurrent_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n            self.http_client.fetch(self.get_url(\"/barrier\")),\n        )\n        self.assertEqual([b\"ok 0\", b\"ok 1\"], sorted([resp.body for resp in resps]))\n\n    @gen_test\n    async def test_concurrent_streaming_barrier(self):\n        self.barrier.reset()\n        resps = await asyncio.gather(\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n            self.http_client.fetch(self.get_url(\"/streaming_barrier\")),\n        )\n        self.assertEqual([b\"ok 0\", b\"ok 1\"], sorted([resp.body for resp in resps]))\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 890ms\nPrepared 1 package in 998ms\nInstalled 1 package in 1ms\n + tornado==6.3.dev1 (from file:///home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_ea03332e204a357bb43b2f106a9868b3701d0623)\nResolved 29 packages in 11ms\nInstalled 29 packages in 61ms\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_ea03332e204a357bb43b2f106a9868b3701d0623\n......\ncollected 6 items\n\n==================== short test summary info ====================\nPASSED r2e_tests.test_1::WSGIContainerDummyExecutorTest::test_concurrent_barrier\nPASSED r2e_tests.test_1::WSGIContainerDummyExecutorTest::test_concurrent_streaming_barrier\nPASSED r2e_tests.test_1::WSGIContainerDummyExecutorTest::test_simple\nPASSED r2e_tests.test_1::WSGIContainerThreadPoolTest::test_concurrent_barrier\nPASSED r2e_tests.test_1::WSGIContainerThreadPoolTest::test_concurrent_streaming_barrier\nPASSED r2e_tests.test_1::WSGIContainerThreadPoolTest::test_simple\n=================== 6 passed in 0.64s ===================\n",
    "new_commit_res_stderr": "",
    "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_ea03332e204a357bb43b2f106a9868b3701d0623\n......\ncollected 6 items\n\n=================================== FAILURES ===================================\n__________ WSGIContainerThreadPoolTest.test_concurrent_streaming_barrier __________\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_ea03332e204a357bb43b2f106a9868b3701d0623/tornado/testing.py\", line 102, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_ea03332e204a357bb43b2f106a9868b3701d0623/tornado/testing.py\", line 662, in post_coroutine\n    return self.io_loop.run_sync(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_ea03332e204a357bb43b2f106a9868b3701d0623/tornado/ioloop.py\", line 529, in run_sync\n    return future_cell[0].result()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_ea03332e204a357bb43b2f106a9868b3701d0623/r2e_tests/test_1.py\", line 116, in test_concurrent_streaming_barrier\n    self.assertEqual([b\"ok 0\", b\"ok 1\"], sorted([resp.body for resp in resps]))\nAssertionError: Lists differ: [b'ok 0', b'ok 1'] != [b'ok broken barrier', b'ok broken barrier']\n\nFirst differing element 0:\nb'ok 0'\nb'ok broken barrier'\n\n- [b'ok 0', b'ok 1']\n+ [b'ok broken barrier', b'ok broken barrier']\n\n==================== short test summary info ====================\nPASSED r2e_tests.test_1::WSGIContainerDummyExecutorTest::test_concurrent_barrier\nPASSED r2e_tests.test_1::WSGIContainerDummyExecutorTest::test_concurrent_streaming_barrier\nPASSED r2e_tests.test_1::WSGIContainerDummyExecutorTest::test_simple\nPASSED r2e_tests.test_1::WSGIContainerThreadPoolTest::test_concurrent_barrier\nFAILED r2e_tests.test_1::WSGIContainerThreadPoolTest::test_concurrent_streaming_barrier\nPASSED r2e_tests.test_1::WSGIContainerThreadPoolTest::test_simple\n=================== 1 failed, 5 passed in 0.92s ===================\n",
    "old_commit_res_stderr": ""
}
tornado/test/wsgi_test.py tornado/wsgi.py
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
**Issue Analysis:**

- **Key Parts:**
  - The test `test_concurrent_streaming_barrier` was failing in the old commit.
  - The failure was due to responses returning `[b'ok 0', b'ok 1']` instead of `[b'ok broken barrier', b'ok broken barrier']`.
  - The new commit fixed the issue, making all tests pass.

- **Main Problem:**
  - When using a `ThreadPoolExecutor`, the WSGI application does not handle streaming barriers correctly, resulting in incorrect response data.

- **Expected Behavior:**
  - All concurrent streaming barrier responses should return `[b'ok broken barrier', b'ok broken barrier']`.

- **Actual Behavior:**
  - Responses were returning `[b'ok 0', b'ok 1']`, indicating improper handling of streaming barriers.

- **Issue Description:**
  - The bug occurs when running the WSGI application with a `ThreadPoolExecutor`. The streaming barrier does not function as intended, leading to incorrect response messages.

---

[ISSUE]
**Title:** Incorrect Handling of Streaming Barriers with ThreadPoolExecutor in WSGI Application

**Description:**
When running the WSGI application using a `ThreadPoolExecutor`, streaming barriers do not function correctly. Instead of returning the expected "ok broken barrier" responses, the application returns "ok 0" and "ok 1". This behavior suggests that the streaming response is not properly synchronized, leading to unexpected output.

**Example Buggy Code:**
```python
async def test_concurrent_streaming_barrier(self):
    self.barrier.reset()
    resps = await asyncio.gather(
        self.http_client.fetch(self.get_url('/streaming_barrier')),
        self.http_client.fetch(self.get_url('/streaming_barrier')),
    )
    for resp in resps:
        self.assertEqual(resp.body, b'ok broken barrier')
```
In this test, two concurrent requests to `/streaming_barrier` should both receive `b'ok broken barrier'`. However, they receive `b'ok 0'` and `b'ok 1'` instead.

**Expected Behavior:**
Both streaming barrier responses should return `b'ok broken barrier'`, indicating that the barrier synchronization is functioning correctly.

**Actual Behavior:**
Responses return `b'ok 0'` and `b'ok 1'`, showing that the barrier did not synchronize the responses as intended.
[/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/wsgi.py
#
# Copyright 2009 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.

"""WSGI support for the Tornado web framework.

WSGI is the Python standard for web servers, and allows for interoperability
between Tornado and other Python web frameworks and servers.

This module provides WSGI support via the `WSGIContainer` class, which
makes it possible to run applications using other WSGI frameworks on
the Tornado HTTP server. The reverse is not supported; the Tornado
`.Application` and `.RequestHandler` classes are designed for use with
the Tornado `.HTTPServer` and cannot be used in a generic WSGI
container.

"""

import concurrent.futures
from io import BytesIO
import tornado
import sys

from tornado.concurrent import dummy_executor
from tornado import escape
from tornado import httputil
from tornado.ioloop import IOLoop
from tornado.log import access_log

from typing import List, Tuple, Optional, Callable, Any, Dict, Text
from types import TracebackType
import typing

if typing.TYPE_CHECKING:
    from typing import Type  # noqa: F401
    from _typeshed.wsgi import WSGIApplication as WSGIAppType  # noqa: F401


# PEP 3333 specifies that WSGI on python 3 generally deals with byte strings
# that are smuggled inside objects of type unicode (via the latin1 encoding).
# This function is like those in the tornado.escape module, but defined
# here to minimize the temptation to use it in non-wsgi contexts.
def to_wsgi_str(s: bytes) -> str:
    assert isinstance(s, bytes)
    return s.decode("latin1")


class WSGIContainer(object):
    r"""Makes a WSGI-compatible function runnable on Tornado's HTTP server.

    .. warning::

       WSGI is a *synchronous* interface, while Tornado's concurrency model
       is based on single-threaded asynchronous execution.  This means that
       running a WSGI app with Tornado's `WSGIContainer` is *less scalable*
       than running the same app in a multi-threaded WSGI server like
       ``gunicorn`` or ``uwsgi``.  Use `WSGIContainer` only when there are
       benefits to combining Tornado and WSGI in the same process that
       outweigh the reduced scalability.

    Wrap a WSGI function in a `WSGIContainer` and pass it to `.HTTPServer` to
    run it. For example::

        def simple_app(environ, start_response):
            status = "200 OK"
            response_headers = [("Content-type", "text/plain")]
            start_response(status, response_headers)
            return [b"Hello world!\n"]

        async def main():
            container = tornado.wsgi.WSGIContainer(simple_app)
            http_server = tornado.httpserver.HTTPServer(container)
            http_server.listen(8888)
            await asyncio.Event().wait()

        asyncio.run(main())

    This class is intended to let other frameworks (Django, web.py, etc)
    run on the Tornado HTTP server and I/O loop.

    The `tornado.web.FallbackHandler` class is often useful for mixing
    Tornado and WSGI apps in the same server.  See
    https://github.com/bdarnell/django-tornado-demo for a complete example.

    `WSGIContainer` supports executing the WSGI application in custom executors
    using `IOLoop.run_in_executor`. The default executor uses
    `tornado.concurrent.dummy_executor` which works synchronously, but other
    executors subclassing `concurrent.futures.Executor` may be used. To execute
    WSGI application code in separate threads in an event-loop compatible way
    use::

        async def main():
            executor = concurrent.futures.ThreadPoolExecutor()
            # ^-- Execute requests in separate threads.
            container = tornado.wsgi.WSGIContainer(simple_app, executor)
            # Initialize the WSGI container with custom executor --^
            http_server = tornado.httpserver.HTTPServer(container)
            http_server.listen(8888)
            await asyncio.Event().wait()

    Running the WSGI app with a `ThreadPoolExecutor` remains *less scalable*
    than running the same app in a multi-threaded WSGI server like ``gunicorn``
    or ``uwsgi``.
    """

    def __init__(
        self,
        wsgi_application: "WSGIAppType",
        executor: concurrent.futures.Executor = None,
    ) -> None:
        self.wsgi_application = wsgi_application
        self.executor = dummy_executor if executor is None else executor

    def __call__(self, request: httputil.HTTPServerRequest) -> None:
        IOLoop.current().spawn_callback(self.handle_request, request)

    async def handle_request(self, request: httputil.HTTPServerRequest) -> None:
        data = {}  # type: Dict[str, Any]
        response = []  # type: List[bytes]

        def start_response(
            status: str,
            headers: List[Tuple[str, str]],
            exc_info: Optional[
                Tuple[
                    "Optional[Type[BaseException]]",
                    Optional[BaseException],
                    Optional[TracebackType],
                ]
            ] = None,
        ) -> Callable[[bytes], Any]:
            data["status"] = status
            data["headers"] = headers
            return response.append

        loop = IOLoop.current()
        app_response = await loop.run_in_executor(
            self.executor,
            self.wsgi_application,
            self.environ(request),
            start_response,
        )
        try:
            response.extend(app_response)
            body = b"".join(response)
        finally:
            if hasattr(app_response, "close"):
                app_response.close()  # type: ignore
        if not data:
            raise Exception("WSGI app did not call start_response")

        status_code_str, reason = data["status"].split(" ", 1)
        status_code = int(status_code_str)
        headers = data["headers"]  # type: List[Tuple[str, str]]
        header_set = set(k.lower() for (k, v) in headers)
        body = escape.utf8(body)
        if status_code != 304:
            if "content-length" not in header_set:
                headers.append(("Content-Length", str(len(body))))
            if "content-type" not in header_set:
                headers.append(("Content-Type", "text/html; charset=UTF-8"))
        if "server" not in header_set:
            headers.append(("Server", "TornadoServer/%s" % tornado.version))

        start_line = httputil.ResponseStartLine("HTTP/1.1", status_code, reason)
        header_obj = httputil.HTTPHeaders()
        for key, value in headers:
            header_obj.add(key, value)
        assert request.connection is not None
        request.connection.write_headers(start_line, header_obj, chunk=body)
        request.connection.finish()
        self._log(status_code, request)

    @staticmethod
    def environ(request: httputil.HTTPServerRequest) -> Dict[Text, Any]:
        """Converts a `tornado.httputil.HTTPServerRequest` to a WSGI environment."""
        hostport = request.host.split(":")
        if len(hostport) == 2:
            host = hostport[0]
            port = int(hostport[1])
        else:
            host = request.host
            port = 443 if request.protocol == "https" else 80
        environ = {
            "REQUEST_METHOD": request.method,
            "SCRIPT_NAME": "",
            "PATH_INFO": to_wsgi_str(
                escape.url_unescape(request.path, encoding=None, plus=False)
            ),
            "QUERY_STRING": request.query,
            "REMOTE_ADDR": request.remote_ip,
            "SERVER_NAME": host,
            "SERVER_PORT": str(port),
            "SERVER_PROTOCOL": request.version,
            "wsgi.version": (1, 0),
            "wsgi.url_scheme": request.protocol,
            "wsgi.input": BytesIO(escape.utf8(request.body)),
            "wsgi.errors": sys.stderr,
            "wsgi.multithread": False,
            "wsgi.multiprocess": True,
            "wsgi.run_once": False,
        }
        if "Content-Type" in request.headers:
            environ["CONTENT_TYPE"] = request.headers.pop("Content-Type")
        if "Content-Length" in request.headers:
            environ["CONTENT_LENGTH"] = request.headers.pop("Content-Length")
        for key, value in request.headers.items():
            environ["HTTP_" + key.replace("-", "_").upper()] = value
        return environ

    def _log(self, status_code: int, request: httputil.HTTPServerRequest) -> None:
        if status_code < 400:
            log_method = access_log.info
        elif status_code < 500:
            log_method = access_log.warning
        else:
            log_method = access_log.error
        request_time = 1000.0 * request.request_time()
        assert request.method is not None
        assert request.uri is not None
        summary = (
            request.method  # type: ignore[operator]
            + " "
            + request.uri
            + " ("
            + request.remote_ip
            + ")"
        )
        log_method("%d %s %.2fms", status_code, summary, request_time)


HTTPRequest = httputil.HTTPServerRequest

```
--- 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 Analysis:**

- **Key Parts:**
  - The test `test_concurrent_streaming_barrier` was failing in the old commit.
  - The failure was due to responses returning `[b'ok 0', b'ok 1']` instead of `[b'ok broken barrier', b'ok broken barrier']`.
  - The new commit fixed the issue, making all tests pass.

- **Main Problem:**
  - When using a `ThreadPoolExecutor`, the WSGI application does not handle streaming barriers correctly, resulting in incorrect response data.

- **Expected Behavior:**
  - All concurrent streaming barrier responses should return `[b'ok broken barrier', b'ok broken barrier']`.

- **Actual Behavior:**
  - Responses were returning `[b'ok 0', b'ok 1']`, indicating improper handling of streaming barriers.

- **Issue Description:**
  - The bug occurs when running the WSGI application with a `ThreadPoolExecutor`. The streaming barrier does not function as intended, leading to incorrect response messages.

---

[ISSUE]
**Title:** Incorrect Handling of Streaming Barriers with ThreadPoolExecutor in WSGI Application

**Description:**
When running the WSGI application using a `ThreadPoolExecutor`, streaming barriers do not function correctly. Instead of returning the expected "ok broken barrier" responses, the application returns "ok 0" and "ok 1". This behavior suggests that the streaming response is not properly synchronized, leading to unexpected output.

**Example Buggy Code:**
```python
async def test_concurrent_streaming_barrier(self):
    self.barrier.reset()
    resps = await asyncio.gather(
        self.http_client.fetch(self.get_url('/streaming_barrier')),
        self.http_client.fetch(self.get_url('/streaming_barrier')),
    )
    for resp in resps:
        self.assertEqual(resp.body, b'ok broken barrier')
```
In this test, two concurrent requests to `/streaming_barrier` should both receive `b'ok broken barrier'`. However, they receive `b'ok 0'` and `b'ok 1'` instead.

**Expected Behavior:**
Both streaming barrier responses should return `b'ok broken barrier'`, indicating that the barrier synchronization is functioning correctly.

**Actual Behavior:**
Responses return `b'ok 0'` and `b'ok 1'`, showing that the barrier did not synchronize the responses as intended.
[/ISSUE]
{
    "WSGIContainerDummyExecutorTest.test_concurrent_barrier": "PASSED",
    "WSGIContainerDummyExecutorTest.test_concurrent_streaming_barrier": "PASSED",
    "WSGIContainerDummyExecutorTest.test_simple": "PASSED",
    "WSGIContainerThreadPoolTest.test_concurrent_barrier": "PASSED",
    "WSGIContainerThreadPoolTest.test_concurrent_streaming_barrier": "PASSED",
    "WSGIContainerThreadPoolTest.test_simple": "PASSED"
}
diff --git a/tornado/wsgi.py b/tornado/wsgi.py
index 66d4ca6d..c37d7dc8 100644
--- a/tornado/wsgi.py
+++ b/tornado/wsgi.py
@@ -94,8 +94,8 @@ class WSGIContainer(object):
     https://github.com/bdarnell/django-tornado-demo for a complete example.
 
     `WSGIContainer` supports executing the WSGI application in custom executors
-    using `IOLoop.run_in_executor`. The default executor uses
-    `tornado.concurrent.dummy_executor` which works synchronously, but other
+    using `.IOLoop.run_in_executor`. The default executor uses
+    ``tornado.concurrent.dummy_executor`` which works synchronously, but other
     executors subclassing `concurrent.futures.Executor` may be used. To execute
     WSGI application code in separate threads in an event-loop compatible way
     use::
@@ -109,7 +109,7 @@ class WSGIContainer(object):
             http_server.listen(8888)
             await asyncio.Event().wait()
 
-    Running the WSGI app with a `ThreadPoolExecutor` remains *less scalable*
+    Running the WSGI app with a ``ThreadPoolExecutor`` remains *less scalable*
     than running the same app in a multi-threaded WSGI server like ``gunicorn``
     or ``uwsgi``.
     """
@@ -117,7 +117,7 @@ class WSGIContainer(object):
     def __init__(
         self,
         wsgi_application: "WSGIAppType",
-        executor: concurrent.futures.Executor = None,
+        executor: Optional[concurrent.futures.Executor] = None,
     ) -> None:
         self.wsgi_application = wsgi_application
         self.executor = dummy_executor if executor is None else executor
@@ -152,11 +152,25 @@ class WSGIContainer(object):
             start_response,
         )
         try:
-            response.extend(app_response)
-            body = b"".join(response)
+            app_response_iter = iter(app_response)
+
+            def next_chunk() -> Optional[bytes]:
+                try:
+                    return next(app_response_iter)
+                except StopIteration:
+                    # StopIteration is special and is not allowed to pass through
+                    # coroutines normally.
+                    return None
+
+            while True:
+                chunk = await loop.run_in_executor(self.executor, next_chunk)
+                if chunk is None:
+                    break
+                response.append(chunk)
         finally:
             if hasattr(app_response, "close"):
                 app_response.close()  # type: ignore
+        body = b"".join(response)
         if not data:
             raise Exception("WSGI app did not call start_response")
 
 

{"tornado/wsgi.py": "#\n# Copyright 2009 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\"\"\"WSGI support for the Tornado web framework.\n\nWSGI is the Python standard for web servers, and allows for interoperability\nbetween Tornado and other Python web frameworks and servers.\n\nThis module provides WSGI support via the `WSGIContainer` class, which\nmakes it possible to run applications using other WSGI frameworks on\nthe Tornado HTTP server. The reverse is not supported; the Tornado\n`.Application` and `.RequestHandler` classes are designed for use with\nthe Tornado `.HTTPServer` and cannot be used in a generic WSGI\ncontainer.\n\n\"\"\"\n\nimport concurrent.futures\nfrom io import BytesIO\nimport tornado\nimport sys\n\nfrom tornado.concurrent import dummy_executor\nfrom tornado import escape\nfrom tornado import httputil\nfrom tornado.ioloop import IOLoop\nfrom tornado.log import access_log\n\nfrom typing import List, Tuple, Optional, Callable, Any, Dict, Text\nfrom types import TracebackType\nimport typing\n\nif typing.TYPE_CHECKING:\n    from typing import Type  # noqa: F401\n    from _typeshed.wsgi import WSGIApplication as WSGIAppType  # noqa: F401\n\n\n# PEP 3333 specifies that WSGI on python 3 generally deals with byte strings\n# that are smuggled inside objects of type unicode (via the latin1 encoding).\n# This function is like those in the tornado.escape module, but defined\n# here to minimize the temptation to use it in non-wsgi contexts.\ndef to_wsgi_str(s: bytes) -> str:\n    assert isinstance(s, bytes)\n    return s.decode(\"latin1\")\n\n\nclass WSGIContainer(object):\n    r\"\"\"Makes a WSGI-compatible function runnable on Tornado's HTTP server.\n\n    .. warning::\n\n       WSGI is a *synchronous* interface, while Tornado's concurrency model\n       is based on single-threaded asynchronous execution.  This means that\n       running a WSGI app with Tornado's `WSGIContainer` is *less scalable*\n       than running the same app in a multi-threaded WSGI server like\n       ``gunicorn`` or ``uwsgi``.  Use `WSGIContainer` only when there are\n       benefits to combining Tornado and WSGI in the same process that\n       outweigh the reduced scalability.\n\n    Wrap a WSGI function in a `WSGIContainer` and pass it to `.HTTPServer` to\n    run it. For example::\n\n        def simple_app(environ, start_response):\n            status = \"200 OK\"\n            response_headers = [(\"Content-type\", \"text/plain\")]\n            start_response(status, response_headers)\n            return [b\"Hello world!\\n\"]\n\n        async def main():\n            container = tornado.wsgi.WSGIContainer(simple_app)\n            http_server = tornado.httpserver.HTTPServer(container)\n            http_server.listen(8888)\n            await asyncio.Event().wait()\n\n        asyncio.run(main())\n\n    This class is intended to let other frameworks (Django, web.py, etc)\n    run on the Tornado HTTP server and I/O loop.\n\n    The `tornado.web.FallbackHandler` class is often useful for mixing\n    Tornado and WSGI apps in the same server.  See\n    https://github.com/bdarnell/django-tornado-demo for a complete example.\n\n    `WSGIContainer` supports executing the WSGI application in custom executors\n    using `IOLoop.run_in_executor`. The default executor uses\n    `tornado.concurrent.dummy_executor` which works synchronously, but other\n    executors subclassing `concurrent.futures.Executor` may be used. To execute\n    WSGI application code in separate threads in an event-loop compatible way\n    use::\n\n        async def main():\n            executor = concurrent.futures.ThreadPoolExecutor()\n            # ^-- Execute requests in separate threads.\n            container = tornado.wsgi.WSGIContainer(simple_app, executor)\n            # Initialize the WSGI container with custom executor --^\n            http_server = tornado.httpserver.HTTPServer(container)\n            http_server.listen(8888)\n            await asyncio.Event().wait()\n\n    Running the WSGI app with a `ThreadPoolExecutor` remains *less scalable*\n    than running the same app in a multi-threaded WSGI server like ``gunicorn``\n    or ``uwsgi``.\n    \"\"\"\n\n    def __init__(\n        self,\n        wsgi_application: \"WSGIAppType\",\n        executor: concurrent.futures.Executor = None,\n    ) -> None:\n        self.wsgi_application = wsgi_application\n        self.executor = dummy_executor if executor is None else executor\n\n    def __call__(self, request: httputil.HTTPServerRequest) -> None:\n        IOLoop.current().spawn_callback(self.handle_request, request)\n\n    async def handle_request(self, request: httputil.HTTPServerRequest) -> None:\n        data = {}  # type: Dict[str, Any]\n        response = []  # type: List[bytes]\n\n        def start_response(\n            status: str,\n            headers: List[Tuple[str, str]],\n            exc_info: Optional[\n                Tuple[\n                    \"Optional[Type[BaseException]]\",\n                    Optional[BaseException],\n                    Optional[TracebackType],\n                ]\n            ] = None,\n        ) -> Callable[[bytes], Any]:\n            data[\"status\"] = status\n            data[\"headers\"] = headers\n            return response.append\n\n        loop = IOLoop.current()\n        app_response = await loop.run_in_executor(\n            self.executor,\n            self.wsgi_application,\n            self.environ(request),\n            start_response,\n        )\n        try:\n            response.extend(app_response)\n            body = b\"\".join(response)\n        finally:\n            if hasattr(app_response, \"close\"):\n                app_response.close()  # type: ignore\n        if not data:\n            raise Exception(\"WSGI app did not call start_response\")\n\n        status_code_str, reason = data[\"status\"].split(\" \", 1)\n        status_code = int(status_code_str)\n        headers = data[\"headers\"]  # type: List[Tuple[str, str]]\n        header_set = set(k.lower() for (k, v) in headers)\n        body = escape.utf8(body)\n        if status_code != 304:\n            if \"content-length\" not in header_set:\n                headers.append((\"Content-Length\", str(len(body))))\n            if \"content-type\" not in header_set:\n                headers.append((\"Content-Type\", \"text/html; charset=UTF-8\"))\n        if \"server\" not in header_set:\n            headers.append((\"Server\", \"TornadoServer/%s\" % tornado.version))\n\n        start_line = httputil.ResponseStartLine(\"HTTP/1.1\", status_code, reason)\n        header_obj = httputil.HTTPHeaders()\n        for key, value in headers:\n            header_obj.add(key, value)\n        assert request.connection is not None\n        request.connection.write_headers(start_line, header_obj, chunk=body)\n        request.connection.finish()\n        self._log(status_code, request)\n\n    @staticmethod\n    def environ(request: httputil.HTTPServerRequest) -> Dict[Text, Any]:\n        \"\"\"Converts a `tornado.httputil.HTTPServerRequest` to a WSGI environment.\"\"\"\n        hostport = request.host.split(\":\")\n        if len(hostport) == 2:\n            host = hostport[0]\n            port = int(hostport[1])\n        else:\n            host = request.host\n            port = 443 if request.protocol == \"https\" else 80\n        environ = {\n            \"REQUEST_METHOD\": request.method,\n            \"SCRIPT_NAME\": \"\",\n            \"PATH_INFO\": to_wsgi_str(\n                escape.url_unescape(request.path, encoding=None, plus=False)\n            ),\n            \"QUERY_STRING\": request.query,\n            \"REMOTE_ADDR\": request.remote_ip,\n            \"SERVER_NAME\": host,\n            \"SERVER_PORT\": str(port),\n            \"SERVER_PROTOCOL\": request.version,\n            \"wsgi.version\": (1, 0),\n            \"wsgi.url_scheme\": request.protocol,\n            \"wsgi.input\": BytesIO(escape.utf8(request.body)),\n            \"wsgi.errors\": sys.stderr,\n            \"wsgi.multithread\": False,\n            \"wsgi.multiprocess\": True,\n            \"wsgi.run_once\": False,\n        }\n        if \"Content-Type\" in request.headers:\n            environ[\"CONTENT_TYPE\"] = request.headers.pop(\"Content-Type\")\n        if \"Content-Length\" in request.headers:\n            environ[\"CONTENT_LENGTH\"] = request.headers.pop(\"Content-Length\")\n        for key, value in request.headers.items():\n            environ[\"HTTP_\" + key.replace(\"-\", \"_\").upper()] = value\n        return environ\n\n    def _log(self, status_code: int, request: httputil.HTTPServerRequest) -> None:\n        if status_code < 400:\n            log_method = access_log.info\n        elif status_code < 500:\n            log_method = access_log.warning\n        else:\n            log_method = access_log.error\n        request_time = 1000.0 * request.request_time()\n        assert request.method is not None\n        assert request.uri is not None\n        summary = (\n            request.method  # type: ignore[operator]\n            + \" \"\n            + request.uri\n            + \" (\"\n            + request.remote_ip\n            + \")\"\n        )\n        log_method(\"%d %s %.2fms\", status_code, summary, request_time)\n\n\nHTTPRequest = httputil.HTTPServerRequest\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 Analysis:**

- **Key Parts:**
  - The test `test_concurrent_streaming_barrier` was failing in the old commit.
  - The failure was due to responses returning `[b'ok 0', b'ok 1']` instead of `[b'ok broken barrier', b'ok broken barrier']`.
  - The new commit fixed the issue, making all tests pass.

- **Main Problem:**
  - When using a `ThreadPoolExecutor`, the WSGI application does not handle streaming barriers correctly, resulting in incorrect response data.

- **Expected Behavior:**
  - All concurrent streaming barrier responses should return `[b'ok broken barrier', b'ok broken barrier']`.

- **Actual Behavior:**
  - Responses were returning `[b'ok 0', b'ok 1']`, indicating improper handling of streaming barriers.

- **Issue Description:**
  - The bug occurs when running the WSGI application with a `ThreadPoolExecutor`. The streaming barrier does not function as intended, leading to incorrect response messages.

---

[ISSUE]
**Title:** Incorrect Handling of Streaming Barriers with ThreadPoolExecutor in WSGI Application

**Description:**
When running the WSGI application using a `ThreadPoolExecutor`, streaming barriers do not function correctly. Instead of returning the expected "ok broken barrier" responses, the application returns "ok 0" and "ok 1". This behavior suggests that the streaming response is not properly synchronized, leading to unexpected output.

**Example Buggy Code:**
```python
async def test_concurrent_streaming_barrier(self):
    self.barrier.reset()
    resps = await asyncio.gather(
        self.http_client.fetch(self.get_url('/streaming_barrier')),
        self.http_client.fetch(self.get_url('/streaming_barrier')),
    )
    for resp in resps:
        self.assertEqual(resp.body, b'ok broken barrier')
```
In this test, two concurrent requests to `/streaming_barrier` should both receive `b'ok broken barrier'`. However, they receive `b'ok 0'` and `b'ok 1'` instead.

**Expected Behavior:**
Both streaming barrier responses should return `b'ok broken barrier'`, indicating that the barrier synchronization is functioning correctly.

**Actual Behavior:**
Responses return `b'ok 0'` and `b'ok 1'`, showing that the barrier did not synchronize the responses as intended.
[/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/wsgi.py
#
# Copyright 2009 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.

"""WSGI support for the Tornado web framework.

WSGI is the Python standard for web servers, and allows for interoperability
between Tornado and other Python web frameworks and servers.

This module provides WSGI support via the `WSGIContainer` class, which
makes it possible to run applications using other WSGI frameworks on
the Tornado HTTP server. The reverse is not supported; the Tornado
`.Application` and `.RequestHandler` classes are designed for use with
the Tornado `.HTTPServer` and cannot be used in a generic WSGI
container.

"""

import concurrent.futures
from io import BytesIO
import tornado
import sys

from tornado.concurrent import dummy_executor
from tornado import escape
from tornado import httputil
from tornado.ioloop import IOLoop
from tornado.log import access_log

from typing import List, Tuple, Optional, Callable, Any, Dict, Text
from types import TracebackType
import typing

if typing.TYPE_CHECKING:
    from typing import Type  # noqa: F401
    from _typeshed.wsgi import WSGIApplication as WSGIAppType  # noqa: F401


# PEP 3333 specifies that WSGI on python 3 generally deals with byte strings
# that are smuggled inside objects of type unicode (via the latin1 encoding).
# This function is like those in the tornado.escape module, but defined
# here to minimize the temptation to use it in non-wsgi contexts.
def to_wsgi_str(s: bytes) -> str:
    assert isinstance(s, bytes)
    return s.decode("latin1")


class WSGIContainer(object):
    r"""Makes a WSGI-compatible function runnable on Tornado's HTTP server.

    .. warning::

       WSGI is a *synchronous* interface, while Tornado's concurrency model
       is based on single-threaded asynchronous execution.  This means that
       running a WSGI app with Tornado's `WSGIContainer` is *less scalable*
       than running the same app in a multi-threaded WSGI server like
       ``gunicorn`` or ``uwsgi``.  Use `WSGIContainer` only when there are
       benefits to combining Tornado and WSGI in the same process that
       outweigh the reduced scalability.

    Wrap a WSGI function in a `WSGIContainer` and pass it to `.HTTPServer` to
    run it. For example::

        def simple_app(environ, start_response):
            status = "200 OK"
            response_headers = [("Content-type", "text/plain")]
            start_response(status, response_headers)
            return [b"Hello world!\n"]

        async def main():
            container = tornado.wsgi.WSGIContainer(simple_app)
            http_server = tornado.httpserver.HTTPServer(container)
            http_server.listen(8888)
            await asyncio.Event().wait()

        asyncio.run(main())

    This class is intended to let other frameworks (Django, web.py, etc)
    run on the Tornado HTTP server and I/O loop.

    The `tornado.web.FallbackHandler` class is often useful for mixing
    Tornado and WSGI apps in the same server.  See
    https://github.com/bdarnell/django-tornado-demo for a complete example.

    `WSGIContainer` supports executing the WSGI application in custom executors
    using `IOLoop.run_in_executor`. The default executor uses
    `tornado.concurrent.dummy_executor` which works synchronously, but other
    executors subclassing `concurrent.futures.Executor` may be used. To execute
    WSGI application code in separate threads in an event-loop compatible way
    use::

        async def main():
            executor = concurrent.futures.ThreadPoolExecutor()
            # ^-- Execute requests in separate threads.
            container = tornado.wsgi.WSGIContainer(simple_app, executor)
            # Initialize the WSGI container with custom executor --^
            http_server = tornado.httpserver.HTTPServer(container)
            http_server.listen(8888)
            await asyncio.Event().wait()

    Running the WSGI app with a `ThreadPoolExecutor` remains *less scalable*
    than running the same app in a multi-threaded WSGI server like ``gunicorn``
    or ``uwsgi``.
    """

    def __init__(
        self,
        wsgi_application: "WSGIAppType",
        executor: concurrent.futures.Executor = None,
    ) -> None:
        self.wsgi_application = wsgi_application
        self.executor = dummy_executor if executor is None else executor

    def __call__(self, request: httputil.HTTPServerRequest) -> None:
        IOLoop.current().spawn_callback(self.handle_request, request)

    async def handle_request(self, request: httputil.HTTPServerRequest) -> None:
        data = {}  # type: Dict[str, Any]
        response = []  # type: List[bytes]

        def start_response(
            status: str,
            headers: List[Tuple[str, str]],
            exc_info: Optional[
                Tuple[
                    "Optional[Type[BaseException]]",
                    Optional[BaseException],
                    Optional[TracebackType],
                ]
            ] = None,
        ) -> Callable[[bytes], Any]:
            data["status"] = status
            data["headers"] = headers
            return response.append

        loop = IOLoop.current()
        app_response = await loop.run_in_executor(
            self.executor,
            self.wsgi_application,
            self.environ(request),
            start_response,
        )
        try:
            response.extend(app_response)
            body = b"".join(response)
        finally:
            if hasattr(app_response, "close"):
                app_response.close()  # type: ignore
        if not data:
            raise Exception("WSGI app did not call start_response")

        status_code_str, reason = data["status"].split(" ", 1)
        status_code = int(status_code_str)
        headers = data["headers"]  # type: List[Tuple[str, str]]
        header_set = set(k.lower() for (k, v) in headers)
        body = escape.utf8(body)
        if status_code != 304:
            if "content-length" not in header_set:
                headers.append(("Content-Length", str(len(body))))
            if "content-type" not in header_set:
                headers.append(("Content-Type", "text/html; charset=UTF-8"))
        if "server" not in header_set:
            headers.append(("Server", "TornadoServer/%s" % tornado.version))

        start_line = httputil.ResponseStartLine("HTTP/1.1", status_code, reason)
        header_obj = httputil.HTTPHeaders()
        for key, value in headers:
            header_obj.add(key, value)
        assert request.connection is not None
        request.connection.write_headers(start_line, header_obj, chunk=body)
        request.connection.finish()
        self._log(status_code, request)

    @staticmethod
    def environ(request: httputil.HTTPServerRequest) -> Dict[Text, Any]:
        """Converts a `tornado.httputil.HTTPServerRequest` to a WSGI environment."""
        hostport = request.host.split(":")
        if len(hostport) == 2:
            host = hostport[0]
            port = int(hostport[1])
        else:
            host = request.host
            port = 443 if request.protocol == "https" else 80
        environ = {
            "REQUEST_METHOD": request.method,
            "SCRIPT_NAME": "",
            "PATH_INFO": to_wsgi_str(
                escape.url_unescape(request.path, encoding=None, plus=False)
            ),
            "QUERY_STRING": request.query,
            "REMOTE_ADDR": request.remote_ip,
            "SERVER_NAME": host,
            "SERVER_PORT": str(port),
            "SERVER_PROTOCOL": request.version,
            "wsgi.version": (1, 0),
            "wsgi.url_scheme": request.protocol,
            "wsgi.input": BytesIO(escape.utf8(request.body)),
            "wsgi.errors": sys.stderr,
            "wsgi.multithread": False,
            "wsgi.multiprocess": True,
            "wsgi.run_once": False,
        }
        if "Content-Type" in request.headers:
            environ["CONTENT_TYPE"] = request.headers.pop("Content-Type")
        if "Content-Length" in request.headers:
            environ["CONTENT_LENGTH"] = request.headers.pop("Content-Length")
        for key, value in request.headers.items():
            environ["HTTP_" + key.replace("-", "_").upper()] = value
        return environ

    def _log(self, status_code: int, request: httputil.HTTPServerRequest) -> None:
        if status_code < 400:
            log_method = access_log.info
        elif status_code < 500:
            log_method = access_log.warning
        else:
            log_method = access_log.error
        request_time = 1000.0 * request.request_time()
        assert request.method is not None
        assert request.uri is not None
        summary = (
            request.method  # type: ignore[operator]
            + " "
            + request.uri
            + " ("
            + request.remote_ip
            + ")"
        )
        log_method("%d %s %.2fms", status_code, summary, request_time)


HTTPRequest = httputil.HTTPServerRequest

```
--- 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