{
    "file_diffs": [
        {
            "old_file_content": "#!/usr/bin/env python\n#\n# Copyright 2014 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\"\"\"A non-blocking TCP connection factory.\n\"\"\"\nfrom __future__ import absolute_import, division, print_function, with_statement\n\nimport functools\nimport socket\n\nfrom tornado.concurrent import Future\nfrom tornado.ioloop import IOLoop\nfrom tornado.iostream import IOStream\nfrom tornado import gen\nfrom tornado.netutil import Resolver\n\n_INITIAL_CONNECT_TIMEOUT = 0.3\n\n\nclass _Connector(object):\n    \"\"\"A stateless implementation of the \"Happy Eyeballs\" algorithm.\n\n    \"Happy Eyeballs\" is documented in RFC6555 as the recommended practice\n    for when both IPv4 and IPv6 addresses are available.\n\n    In this implementation, we partition the addresses by family, and\n    make the first connection attempt to whichever address was\n    returned first by ``getaddrinfo``.  If that connection fails or\n    times out, we begin a connection in parallel to the first address\n    of the other family.  If there are additional failures we retry\n    with other addresses, keeping one connection attempt per family\n    in flight at a time.\n\n    http://tools.ietf.org/html/rfc6555\n\n    \"\"\"\n    def __init__(self, addrinfo, io_loop, connect):\n        self.io_loop = io_loop\n        self.connect = connect\n\n        self.future = Future()\n        self.timeout = None\n        self.last_error = None\n        self.remaining = len(addrinfo)\n        self.primary_addrs, self.secondary_addrs = self.split(addrinfo)\n\n    @staticmethod\n    def split(addrinfo):\n        \"\"\"Partition the ``addrinfo`` list by address family.\n\n        Returns two lists.  The first list contains the first entry from\n        ``addrinfo`` and all others with the same family, and the\n        second list contains all other addresses (normally one list will\n        be AF_INET and the other AF_INET6, although non-standard resolvers\n        may return additional families).\n        \"\"\"\n        primary = []\n        secondary = []\n        primary_af = addrinfo[0][0]\n        for af, addr in addrinfo:\n            if af == primary_af:\n                primary.append((af, addr))\n            else:\n                secondary.append((af, addr))\n        return primary, secondary\n\n    def start(self, timeout=_INITIAL_CONNECT_TIMEOUT):\n        self.try_connect(iter(self.primary_addrs))\n        self.set_timout(timeout)\n        return self.future\n\n    def try_connect(self, addrs):\n        try:\n            af, addr = next(addrs)\n        except StopIteration:\n            # We've reached the end of our queue, but the other queue\n            # might still be working.  Send a final error on the future\n            # only when both queues are finished.\n            if self.remaining == 0 and not self.future.done():\n                self.future.set_exception(self.last_error or\n                                          IOError(\"connection failed\"))\n            return\n        future = self.connect(af, addr)\n        future.add_done_callback(functools.partial(self.on_connect_done,\n                                                   addrs, af, addr))\n\n    def on_connect_done(self, addrs, af, addr, future):\n        self.remaining -= 1\n        try:\n            stream = future.result()\n        except Exception as e:\n            if self.future.done():\n                return\n            # Error: try again (but remember what happened so we have an\n            # error to raise in the end)\n            self.last_error = e\n            self.try_connect(addrs)\n            if self.timeout is not None:\n                # If the first attempt failed, don't wait for the\n                # timeout to try an address from the secondary queue.\n                self.io_loop.remove_timeout(self.timeout)\n                self.on_timeout()\n            return\n        self.clear_timeout()\n        if self.future.done():\n            # This is a late arrival; just drop it.\n            stream.close()\n        else:\n            self.future.set_result((af, addr, stream))\n\n    def set_timout(self, timeout):\n        self.timeout = self.io_loop.add_timeout(self.io_loop.time() + timeout,\n                                                self.on_timeout)\n\n    def on_timeout(self):\n        self.timeout = None\n        self.try_connect(iter(self.secondary_addrs))\n\n    def clear_timeout(self):\n        if self.timeout is not None:\n            self.io_loop.remove_timeout(self.timeout)\n\n\nclass TCPClient(object):\n    \"\"\"A non-blocking TCP connection factory.\n\n    .. versionchanged:: 4.1\n       The ``io_loop`` argument is deprecated.\n    \"\"\"\n    def __init__(self, resolver=None, io_loop=None):\n        self.io_loop = io_loop or IOLoop.current()\n        if resolver is not None:\n            self.resolver = resolver\n            self._own_resolver = False\n        else:\n            self.resolver = Resolver(io_loop=io_loop)\n            self._own_resolver = True\n\n    def close(self):\n        if self._own_resolver:\n            self.resolver.close()\n\n    @gen.coroutine\n    def connect(self, host, port, af=socket.AF_UNSPEC, ssl_options=None,\n                max_buffer_size=None):\n        \"\"\"Connect to the given host and port.\n\n        Asynchronously returns an `.IOStream` (or `.SSLIOStream` if\n        ``ssl_options`` is not None).\n        \"\"\"\n        addrinfo = yield self.resolver.resolve(host, port, af)\n        connector = _Connector(\n            addrinfo, self.io_loop,\n            functools.partial(self._create_stream, max_buffer_size))\n        af, addr, stream = yield connector.start()\n        # TODO: For better performance we could cache the (af, addr)\n        # information here and re-use it on subsequent connections to\n        # the same host. (http://tools.ietf.org/html/rfc6555#section-4.2)\n        if ssl_options is not None:\n            stream = yield stream.start_tls(False, ssl_options=ssl_options,\n                                            server_hostname=host)\n        raise gen.Return(stream)\n\n    def _create_stream(self, max_buffer_size, af, addr):\n        # Always connect in plaintext; we'll convert to ssl if necessary\n        # after one connection has completed.\n        try:\n            stream = IOStream(socket.socket(af),\n                            io_loop=self.io_loop,\n                            max_buffer_size=max_buffer_size)\n        except socket.error as e:\n            fu = Future()\n            fu.set_exception(e)\n            return fu\n        else:\n            return stream.connect(addr)\n",
            "new_file_content": "#!/usr/bin/env python\n#\n# Copyright 2014 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\"\"\"A non-blocking TCP connection factory.\n\"\"\"\nfrom __future__ import absolute_import, division, print_function, with_statement\n\nimport functools\nimport socket\n\nfrom tornado.concurrent import Future\nfrom tornado.ioloop import IOLoop\nfrom tornado.iostream import IOStream\nfrom tornado import gen\nfrom tornado.netutil import Resolver\n\n_INITIAL_CONNECT_TIMEOUT = 0.3\n\n\nclass _Connector(object):\n    \"\"\"A stateless implementation of the \"Happy Eyeballs\" algorithm.\n\n    \"Happy Eyeballs\" is documented in RFC6555 as the recommended practice\n    for when both IPv4 and IPv6 addresses are available.\n\n    In this implementation, we partition the addresses by family, and\n    make the first connection attempt to whichever address was\n    returned first by ``getaddrinfo``.  If that connection fails or\n    times out, we begin a connection in parallel to the first address\n    of the other family.  If there are additional failures we retry\n    with other addresses, keeping one connection attempt per family\n    in flight at a time.\n\n    http://tools.ietf.org/html/rfc6555\n\n    \"\"\"\n    def __init__(self, addrinfo, io_loop, connect):\n        self.io_loop = io_loop\n        self.connect = connect\n\n        self.future = Future()\n        self.timeout = None\n        self.last_error = None\n        self.remaining = len(addrinfo)\n        self.primary_addrs, self.secondary_addrs = self.split(addrinfo)\n\n    @staticmethod\n    def split(addrinfo):\n        \"\"\"Partition the ``addrinfo`` list by address family.\n\n        Returns two lists.  The first list contains the first entry from\n        ``addrinfo`` and all others with the same family, and the\n        second list contains all other addresses (normally one list will\n        be AF_INET and the other AF_INET6, although non-standard resolvers\n        may return additional families).\n        \"\"\"\n        primary = []\n        secondary = []\n        primary_af = addrinfo[0][0]\n        for af, addr in addrinfo:\n            if af == primary_af:\n                primary.append((af, addr))\n            else:\n                secondary.append((af, addr))\n        return primary, secondary\n\n    def start(self, timeout=_INITIAL_CONNECT_TIMEOUT):\n        self.try_connect(iter(self.primary_addrs))\n        self.set_timout(timeout)\n        return self.future\n\n    def try_connect(self, addrs):\n        try:\n            af, addr = next(addrs)\n        except StopIteration:\n            # We've reached the end of our queue, but the other queue\n            # might still be working.  Send a final error on the future\n            # only when both queues are finished.\n            if self.remaining == 0 and not self.future.done():\n                self.future.set_exception(self.last_error or\n                                          IOError(\"connection failed\"))\n            return\n        future = self.connect(af, addr)\n        future.add_done_callback(functools.partial(self.on_connect_done,\n                                                   addrs, af, addr))\n\n    def on_connect_done(self, addrs, af, addr, future):\n        self.remaining -= 1\n        try:\n            stream = future.result()\n        except Exception as e:\n            if self.future.done():\n                return\n            # Error: try again (but remember what happened so we have an\n            # error to raise in the end)\n            self.last_error = e\n            self.try_connect(addrs)\n            if self.timeout is not None:\n                # If the first attempt failed, don't wait for the\n                # timeout to try an address from the secondary queue.\n                self.io_loop.remove_timeout(self.timeout)\n                self.on_timeout()\n            return\n        self.clear_timeout()\n        if self.future.done():\n            # This is a late arrival; just drop it.\n            stream.close()\n        else:\n            self.future.set_result((af, addr, stream))\n\n    def set_timout(self, timeout):\n        self.timeout = self.io_loop.add_timeout(self.io_loop.time() + timeout,\n                                                self.on_timeout)\n\n    def on_timeout(self):\n        self.timeout = None\n        self.try_connect(iter(self.secondary_addrs))\n\n    def clear_timeout(self):\n        if self.timeout is not None:\n            self.io_loop.remove_timeout(self.timeout)\n\n\nclass TCPClient(object):\n    \"\"\"A non-blocking TCP connection factory.\n\n    .. versionchanged:: 4.1\n       The ``io_loop`` argument is deprecated.\n    \"\"\"\n    def __init__(self, resolver=None, io_loop=None):\n        self.io_loop = io_loop or IOLoop.current()\n        if resolver is not None:\n            self.resolver = resolver\n            self._own_resolver = False\n        else:\n            self.resolver = Resolver(io_loop=io_loop)\n            self._own_resolver = True\n\n    def close(self):\n        if self._own_resolver:\n            self.resolver.close()\n\n    @gen.coroutine\n    def connect(self, host, port, af=socket.AF_UNSPEC, ssl_options=None,\n                max_buffer_size=None, source_ip=None, source_port=None):\n        \"\"\"Connect to the given host and port.\n\n        Asynchronously returns an `.IOStream` (or `.SSLIOStream` if\n        ``ssl_options`` is not None).\n\n        Using the ``source_ip`` kwarg, one can specify the source\n        IP address to use when establishing the connection.\n        In case the user needs to resolve and\n        use a specific interface, it has to be handled outside\n        of Tornado as this depends very much on the platform.\n\n        Similarly, when the user requires a certain source port, it can\n        be specified using the ``source_port`` arg.\n        \"\"\"\n        addrinfo = yield self.resolver.resolve(host, port, af)\n        connector = _Connector(\n            addrinfo, self.io_loop,\n            functools.partial(self._create_stream, max_buffer_size,\n                              source_ip=source_ip, source_port=source_port)\n        )\n        af, addr, stream = yield connector.start()\n        # TODO: For better performance we could cache the (af, addr)\n        # information here and re-use it on subsequent connections to\n        # the same host. (http://tools.ietf.org/html/rfc6555#section-4.2)\n        if ssl_options is not None:\n            stream = yield stream.start_tls(False, ssl_options=ssl_options,\n                                            server_hostname=host)\n        raise gen.Return(stream)\n\n    def _create_stream(self, max_buffer_size, af, addr, source_ip=None,\n                       source_port=None):\n        # Always connect in plaintext; we'll convert to ssl if necessary\n        # after one connection has completed.\n        source_port_bind = source_port if isinstance(source_port, int) else 0\n        source_ip_bind = source_ip\n        if source_port_bind and not source_ip:\n            # User required a specific port, but did not specify\n            # a certain source IP, will bind to the default loopback.\n            source_ip_bind = '::1' if af == socket.AF_INET6 else '127.0.0.1'\n            # Trying to use the same address family as the requested af socket:\n            # - 127.0.0.1 for IPv4\n            # - ::1 for IPv6\n        socket_obj = socket.socket(af)\n        if source_port_bind or source_ip_bind:\n            # If the user requires binding also to a specific IP/port.\n            socket_obj.bind((source_ip_bind, source_port_bind))\n            # Fail loudly if unable to use the IP/port.\n        try:\n            stream = IOStream(socket_obj,\n                              io_loop=self.io_loop,\n                              max_buffer_size=max_buffer_size)\n        except socket.error as e:\n            fu = Future()\n            fu.set_exception(e)\n            return fu\n        else:\n            return stream.connect(addr)\n",
            "header": {
                "file": {
                    "path": "tornado/tcpclient.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "11146860",
                "new_commit_hash": "1e289174",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/tornado/tcpclient.py"
            },
            "plus_file": {
                "path": "b/tornado/tcpclient.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 155,
                            "length": 16
                        },
                        "new_range": {
                            "start": 155,
                            "length": 27
                        },
                        "section": "class TCPClient(object):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    @gen.coroutine",
                                "type": "context"
                            },
                            {
                                "content": "    def connect(self, host, port, af=socket.AF_UNSPEC, ssl_options=None,",
                                "type": "context"
                            },
                            {
                                "content": "                max_buffer_size=None):",
                                "type": "deleted"
                            },
                            {
                                "content": "                max_buffer_size=None, source_ip=None, source_port=None):",
                                "type": "added"
                            },
                            {
                                "content": "        \"\"\"Connect to the given host and port.",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "        Asynchronously returns an `.IOStream` (or `.SSLIOStream` if",
                                "type": "context"
                            },
                            {
                                "content": "        ``ssl_options`` is not None).",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        Using the ``source_ip`` kwarg, one can specify the source",
                                "type": "added"
                            },
                            {
                                "content": "        IP address to use when establishing the connection.",
                                "type": "added"
                            },
                            {
                                "content": "        In case the user needs to resolve and",
                                "type": "added"
                            },
                            {
                                "content": "        use a specific interface, it has to be handled outside",
                                "type": "added"
                            },
                            {
                                "content": "        of Tornado as this depends very much on the platform.",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        Similarly, when the user requires a certain source port, it can",
                                "type": "added"
                            },
                            {
                                "content": "        be specified using the ``source_port`` arg.",
                                "type": "added"
                            },
                            {
                                "content": "        \"\"\"",
                                "type": "context"
                            },
                            {
                                "content": "        addrinfo = yield self.resolver.resolve(host, port, af)",
                                "type": "context"
                            },
                            {
                                "content": "        connector = _Connector(",
                                "type": "context"
                            },
                            {
                                "content": "            addrinfo, self.io_loop,",
                                "type": "context"
                            },
                            {
                                "content": "            functools.partial(self._create_stream, max_buffer_size))",
                                "type": "deleted"
                            },
                            {
                                "content": "            functools.partial(self._create_stream, max_buffer_size,",
                                "type": "added"
                            },
                            {
                                "content": "                              source_ip=source_ip, source_port=source_port)",
                                "type": "added"
                            },
                            {
                                "content": "        )",
                                "type": "added"
                            },
                            {
                                "content": "        af, addr, stream = yield connector.start()",
                                "type": "context"
                            },
                            {
                                "content": "        # TODO: For better performance we could cache the (af, addr)",
                                "type": "context"
                            },
                            {
                                "content": "        # information here and re-use it on subsequent connections to",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/tcpclient.py",
                            "type": "class",
                            "name": "TCPClient",
                            "content": "class TCPClient(object):\n    \"\"\"A non-blocking TCP connection factory.\n\n    .. versionchanged:: 4.1\n       The ``io_loop`` argument is deprecated.\n    \"\"\"\n    def __init__(self, resolver=None, io_loop=None):\n        self.io_loop = io_loop or IOLoop.current()\n        if resolver is not None:\n            self.resolver = resolver\n            self._own_resolver = False\n        else:\n            self.resolver = Resolver(io_loop=io_loop)\n            self._own_resolver = True\n\n    def close(self):\n        if self._own_resolver:\n            self.resolver.close()\n\n    @gen.coroutine\n    def connect(self, host, port, af=socket.AF_UNSPEC, ssl_options=None,\n                max_buffer_size=None):\n        \"\"\"Connect to the given host and port.\n\n        Asynchronously returns an `.IOStream` (or `.SSLIOStream` if\n        ``ssl_options`` is not None).\n        \"\"\"\n        addrinfo = yield self.resolver.resolve(host, port, af)\n        connector = _Connector(\n            addrinfo, self.io_loop,\n            functools.partial(self._create_stream, max_buffer_size))\n        af, addr, stream = yield connector.start()\n        # TODO: For better performance we could cache the (af, addr)\n        # information here and re-use it on subsequent connections to\n        # the same host. (http://tools.ietf.org/html/rfc6555#section-4.2)\n        if ssl_options is not None:\n            stream = yield stream.start_tls(False, ssl_options=ssl_options,\n                                            server_hostname=host)\n        raise gen.Return(stream)\n\n    def _create_stream(self, max_buffer_size, af, addr):\n        # Always connect in plaintext; we'll convert to ssl if necessary\n        # after one connection has completed.\n        try:\n            stream = IOStream(socket.socket(af),\n                            io_loop=self.io_loop,\n                            max_buffer_size=max_buffer_size)\n        except socket.error as e:\n            fu = Future()\n            fu.set_exception(e)\n            return fu\n        else:\n            return stream.connect(addr)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 137,
                            "end_lineno": 189,
                            "parent": null
                        },
                        {
                            "file_name": "tornado/tcpclient.py",
                            "type": "method",
                            "name": "TCPClient.connect",
                            "content": "class TCPClient(object):\n    \"\"\"A non-blocking TCP connection factory.\n\n    .. versionchanged:: 4.1\n       The ``io_loop`` argument is deprecated.\n    \"\"\"\n    def __init__(self, resolver=None, io_loop=None):\n        self.io_loop = io_loop or IOLoop.current()\n        if resolver is not None:\n            self.resolver = resolver\n            self._own_resolver = False\n        else:\n            self.resolver = Resolver(io_loop=io_loop)\n            self._own_resolver = True\n\n    def close(self):\n        if self._own_resolver:\n            self.resolver.close()\n\n    @gen.coroutine\n    def connect(self, host, port, af=socket.AF_UNSPEC, ssl_options=None,\n                max_buffer_size=None):\n        \"\"\"Connect to the given host and port.\n\n        Asynchronously returns an `.IOStream` (or `.SSLIOStream` if\n        ``ssl_options`` is not None).\n        \"\"\"\n        addrinfo = yield self.resolver.resolve(host, port, af)\n        connector = _Connector(\n            addrinfo, self.io_loop,\n            functools.partial(self._create_stream, max_buffer_size))\n        af, addr, stream = yield connector.start()\n        # TODO: For better performance we could cache the (af, addr)\n        # information here and re-use it on subsequent connections to\n        # the same host. (http://tools.ietf.org/html/rfc6555#section-4.2)\n        if ssl_options is not None:\n            stream = yield stream.start_tls(False, ssl_options=ssl_options,\n                                            server_hostname=host)\n        raise gen.Return(stream)\n\n    def _create_stream(self, max_buffer_size, af, addr):\n        # Always connect in plaintext; we'll convert to ssl if necessary\n        # after one connection has completed.\n        try:\n            stream = IOStream(socket.socket(af),\n                            io_loop=self.io_loop,\n                            max_buffer_size=max_buffer_size)\n        except socket.error as e:\n            fu = Future()\n            fu.set_exception(e)\n            return fu\n        else:\n            return stream.connect(addr)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 157,
                            "end_lineno": 175,
                            "parent": {
                                "file_name": "tornado/tcpclient.py",
                                "type": "class",
                                "name": "TCPClient",
                                "content": "class TCPClient(object):\n    \"\"\"A non-blocking TCP connection factory.\n\n    .. versionchanged:: 4.1\n       The ``io_loop`` argument is deprecated.\n    \"\"\"\n    def __init__(self, resolver=None, io_loop=None):\n        self.io_loop = io_loop or IOLoop.current()\n        if resolver is not None:\n            self.resolver = resolver\n            self._own_resolver = False\n        else:\n            self.resolver = Resolver(io_loop=io_loop)\n            self._own_resolver = True\n\n    def close(self):\n        if self._own_resolver:\n            self.resolver.close()\n\n    @gen.coroutine\n    def connect(self, host, port, af=socket.AF_UNSPEC, ssl_options=None,\n                max_buffer_size=None):\n        \"\"\"Connect to the given host and port.\n\n        Asynchronously returns an `.IOStream` (or `.SSLIOStream` if\n        ``ssl_options`` is not None).\n        \"\"\"\n        addrinfo = yield self.resolver.resolve(host, port, af)\n        connector = _Connector(\n            addrinfo, self.io_loop,\n            functools.partial(self._create_stream, max_buffer_size))\n        af, addr, stream = yield connector.start()\n        # TODO: For better performance we could cache the (af, addr)\n        # information here and re-use it on subsequent connections to\n        # the same host. (http://tools.ietf.org/html/rfc6555#section-4.2)\n        if ssl_options is not None:\n            stream = yield stream.start_tls(False, ssl_options=ssl_options,\n                                            server_hostname=host)\n        raise gen.Return(stream)\n\n    def _create_stream(self, max_buffer_size, af, addr):\n        # Always connect in plaintext; we'll convert to ssl if necessary\n        # after one connection has completed.\n        try:\n            stream = IOStream(socket.socket(af),\n                            io_loop=self.io_loop,\n                            max_buffer_size=max_buffer_size)\n        except socket.error as e:\n            fu = Future()\n            fu.set_exception(e)\n            return fu\n        else:\n            return stream.connect(addr)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 137,
                                "end_lineno": 189,
                                "parent": null
                            }
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 174,
                            "length": 13
                        },
                        "new_range": {
                            "start": 185,
                            "length": 28
                        },
                        "section": "class TCPClient(object):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "                                            server_hostname=host)",
                                "type": "context"
                            },
                            {
                                "content": "        raise gen.Return(stream)",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def _create_stream(self, max_buffer_size, af, addr):",
                                "type": "deleted"
                            },
                            {
                                "content": "    def _create_stream(self, max_buffer_size, af, addr, source_ip=None,",
                                "type": "added"
                            },
                            {
                                "content": "                       source_port=None):",
                                "type": "added"
                            },
                            {
                                "content": "        # Always connect in plaintext; we'll convert to ssl if necessary",
                                "type": "context"
                            },
                            {
                                "content": "        # after one connection has completed.",
                                "type": "context"
                            },
                            {
                                "content": "        source_port_bind = source_port if isinstance(source_port, int) else 0",
                                "type": "added"
                            },
                            {
                                "content": "        source_ip_bind = source_ip",
                                "type": "added"
                            },
                            {
                                "content": "        if source_port_bind and not source_ip:",
                                "type": "added"
                            },
                            {
                                "content": "            # User required a specific port, but did not specify",
                                "type": "added"
                            },
                            {
                                "content": "            # a certain source IP, will bind to the default loopback.",
                                "type": "added"
                            },
                            {
                                "content": "            source_ip_bind = '::1' if af == socket.AF_INET6 else '127.0.0.1'",
                                "type": "added"
                            },
                            {
                                "content": "            # Trying to use the same address family as the requested af socket:",
                                "type": "added"
                            },
                            {
                                "content": "            # - 127.0.0.1 for IPv4",
                                "type": "added"
                            },
                            {
                                "content": "            # - ::1 for IPv6",
                                "type": "added"
                            },
                            {
                                "content": "        socket_obj = socket.socket(af)",
                                "type": "added"
                            },
                            {
                                "content": "        if source_port_bind or source_ip_bind:",
                                "type": "added"
                            },
                            {
                                "content": "            # If the user requires binding also to a specific IP/port.",
                                "type": "added"
                            },
                            {
                                "content": "            socket_obj.bind((source_ip_bind, source_port_bind))",
                                "type": "added"
                            },
                            {
                                "content": "            # Fail loudly if unable to use the IP/port.",
                                "type": "added"
                            },
                            {
                                "content": "        try:",
                                "type": "context"
                            },
                            {
                                "content": "            stream = IOStream(socket.socket(af),",
                                "type": "deleted"
                            },
                            {
                                "content": "                            io_loop=self.io_loop,",
                                "type": "deleted"
                            },
                            {
                                "content": "                            max_buffer_size=max_buffer_size)",
                                "type": "deleted"
                            },
                            {
                                "content": "            stream = IOStream(socket_obj,",
                                "type": "added"
                            },
                            {
                                "content": "                              io_loop=self.io_loop,",
                                "type": "added"
                            },
                            {
                                "content": "                              max_buffer_size=max_buffer_size)",
                                "type": "added"
                            },
                            {
                                "content": "        except socket.error as e:",
                                "type": "context"
                            },
                            {
                                "content": "            fu = Future()",
                                "type": "context"
                            },
                            {
                                "content": "            fu.set_exception(e)",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/tcpclient.py",
                            "type": "method",
                            "name": "TCPClient._create_stream",
                            "content": "class TCPClient(object):\n    \"\"\"A non-blocking TCP connection factory.\n\n    .. versionchanged:: 4.1\n       The ``io_loop`` argument is deprecated.\n    \"\"\"\n    def __init__(self, resolver=None, io_loop=None):\n        self.io_loop = io_loop or IOLoop.current()\n        if resolver is not None:\n            self.resolver = resolver\n            self._own_resolver = False\n        else:\n            self.resolver = Resolver(io_loop=io_loop)\n            self._own_resolver = True\n\n    def close(self):\n        if self._own_resolver:\n            self.resolver.close()\n\n    @gen.coroutine\n    def connect(self, host, port, af=socket.AF_UNSPEC, ssl_options=None,\n                max_buffer_size=None):\n        \"\"\"Connect to the given host and port.\n\n        Asynchronously returns an `.IOStream` (or `.SSLIOStream` if\n        ``ssl_options`` is not None).\n        \"\"\"\n        addrinfo = yield self.resolver.resolve(host, port, af)\n        connector = _Connector(\n            addrinfo, self.io_loop,\n            functools.partial(self._create_stream, max_buffer_size))\n        af, addr, stream = yield connector.start()\n        # TODO: For better performance we could cache the (af, addr)\n        # information here and re-use it on subsequent connections to\n        # the same host. (http://tools.ietf.org/html/rfc6555#section-4.2)\n        if ssl_options is not None:\n            stream = yield stream.start_tls(False, ssl_options=ssl_options,\n                                            server_hostname=host)\n        raise gen.Return(stream)\n\n    def _create_stream(self, max_buffer_size, af, addr):\n        # Always connect in plaintext; we'll convert to ssl if necessary\n        # after one connection has completed.\n        try:\n            stream = IOStream(socket.socket(af),\n                            io_loop=self.io_loop,\n                            max_buffer_size=max_buffer_size)\n        except socket.error as e:\n            fu = Future()\n            fu.set_exception(e)\n            return fu\n        else:\n            return stream.connect(addr)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 177,
                            "end_lineno": 189,
                            "parent": {
                                "file_name": "tornado/tcpclient.py",
                                "type": "class",
                                "name": "TCPClient",
                                "content": "class TCPClient(object):\n    \"\"\"A non-blocking TCP connection factory.\n\n    .. versionchanged:: 4.1\n       The ``io_loop`` argument is deprecated.\n    \"\"\"\n    def __init__(self, resolver=None, io_loop=None):\n        self.io_loop = io_loop or IOLoop.current()\n        if resolver is not None:\n            self.resolver = resolver\n            self._own_resolver = False\n        else:\n            self.resolver = Resolver(io_loop=io_loop)\n            self._own_resolver = True\n\n    def close(self):\n        if self._own_resolver:\n            self.resolver.close()\n\n    @gen.coroutine\n    def connect(self, host, port, af=socket.AF_UNSPEC, ssl_options=None,\n                max_buffer_size=None):\n        \"\"\"Connect to the given host and port.\n\n        Asynchronously returns an `.IOStream` (or `.SSLIOStream` if\n        ``ssl_options`` is not None).\n        \"\"\"\n        addrinfo = yield self.resolver.resolve(host, port, af)\n        connector = _Connector(\n            addrinfo, self.io_loop,\n            functools.partial(self._create_stream, max_buffer_size))\n        af, addr, stream = yield connector.start()\n        # TODO: For better performance we could cache the (af, addr)\n        # information here and re-use it on subsequent connections to\n        # the same host. (http://tools.ietf.org/html/rfc6555#section-4.2)\n        if ssl_options is not None:\n            stream = yield stream.start_tls(False, ssl_options=ssl_options,\n                                            server_hostname=host)\n        raise gen.Return(stream)\n\n    def _create_stream(self, max_buffer_size, af, addr):\n        # Always connect in plaintext; we'll convert to ssl if necessary\n        # after one connection has completed.\n        try:\n            stream = IOStream(socket.socket(af),\n                            io_loop=self.io_loop,\n                            max_buffer_size=max_buffer_size)\n        except socket.error as e:\n            fu = Future()\n            fu.set_exception(e)\n            return fu\n        else:\n            return stream.connect(addr)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 137,
                                "end_lineno": 189,
                                "parent": null
                            }
                        },
                        {
                            "file_name": "tornado/tcpclient.py",
                            "type": "class",
                            "name": "TCPClient",
                            "content": "class TCPClient(object):\n    \"\"\"A non-blocking TCP connection factory.\n\n    .. versionchanged:: 4.1\n       The ``io_loop`` argument is deprecated.\n    \"\"\"\n    def __init__(self, resolver=None, io_loop=None):\n        self.io_loop = io_loop or IOLoop.current()\n        if resolver is not None:\n            self.resolver = resolver\n            self._own_resolver = False\n        else:\n            self.resolver = Resolver(io_loop=io_loop)\n            self._own_resolver = True\n\n    def close(self):\n        if self._own_resolver:\n            self.resolver.close()\n\n    @gen.coroutine\n    def connect(self, host, port, af=socket.AF_UNSPEC, ssl_options=None,\n                max_buffer_size=None):\n        \"\"\"Connect to the given host and port.\n\n        Asynchronously returns an `.IOStream` (or `.SSLIOStream` if\n        ``ssl_options`` is not None).\n        \"\"\"\n        addrinfo = yield self.resolver.resolve(host, port, af)\n        connector = _Connector(\n            addrinfo, self.io_loop,\n            functools.partial(self._create_stream, max_buffer_size))\n        af, addr, stream = yield connector.start()\n        # TODO: For better performance we could cache the (af, addr)\n        # information here and re-use it on subsequent connections to\n        # the same host. (http://tools.ietf.org/html/rfc6555#section-4.2)\n        if ssl_options is not None:\n            stream = yield stream.start_tls(False, ssl_options=ssl_options,\n                                            server_hostname=host)\n        raise gen.Return(stream)\n\n    def _create_stream(self, max_buffer_size, af, addr):\n        # Always connect in plaintext; we'll convert to ssl if necessary\n        # after one connection has completed.\n        try:\n            stream = IOStream(socket.socket(af),\n                            io_loop=self.io_loop,\n                            max_buffer_size=max_buffer_size)\n        except socket.error as e:\n            fu = Future()\n            fu.set_exception(e)\n            return fu\n        else:\n            return stream.connect(addr)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 137,
                            "end_lineno": 189,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        },
        {
            "old_file_content": "#!/usr/bin/env python\n#\n# Copyright 2014 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\nfrom __future__ import absolute_import, division, print_function, with_statement\n\nfrom contextlib import closing\nimport os\nimport socket\n\nfrom tornado.concurrent import Future\nfrom tornado.netutil import bind_sockets, Resolver\nfrom tornado.tcpclient import TCPClient, _Connector\nfrom tornado.tcpserver import TCPServer\nfrom tornado.testing import AsyncTestCase, gen_test\nfrom tornado.test.util import skipIfNoIPv6, unittest, refusing_port\n\n# Fake address families for testing.  Used in place of AF_INET\n# and AF_INET6 because some installations do not have AF_INET6.\nAF1, AF2 = 1, 2\n\n\nclass TestTCPServer(TCPServer):\n    def __init__(self, family):\n        super(TestTCPServer, self).__init__()\n        self.streams = []\n        sockets = bind_sockets(None, 'localhost', family)\n        self.add_sockets(sockets)\n        self.port = sockets[0].getsockname()[1]\n\n    def handle_stream(self, stream, address):\n        self.streams.append(stream)\n\n    def stop(self):\n        super(TestTCPServer, self).stop()\n        for stream in self.streams:\n            stream.close()\n\n\nclass TCPClientTest(AsyncTestCase):\n    def setUp(self):\n        super(TCPClientTest, self).setUp()\n        self.server = None\n        self.client = TCPClient()\n\n    def start_server(self, family):\n        if family == socket.AF_UNSPEC and 'TRAVIS' in os.environ:\n            self.skipTest(\"dual-stack servers often have port conflicts on travis\")\n        self.server = TestTCPServer(family)\n        return self.server.port\n\n    def stop_server(self):\n        if self.server is not None:\n            self.server.stop()\n            self.server = None\n\n    def tearDown(self):\n        self.client.close()\n        self.stop_server()\n        super(TCPClientTest, self).tearDown()\n\n    def skipIfLocalhostV4(self):\n        # The port used here doesn't matter, but some systems require it\n        # to be non-zero if we do not also pass AI_PASSIVE.\n        Resolver().resolve('localhost', 80, callback=self.stop)\n        addrinfo = self.wait()\n        families = set(addr[0] for addr in addrinfo)\n        if socket.AF_INET6 not in families:\n            self.skipTest(\"localhost does not resolve to ipv6\")\n\n    @gen_test\n    def do_test_connect(self, family, host):\n        port = self.start_server(family)\n        stream = yield self.client.connect(host, port)\n        with closing(stream):\n            stream.write(b\"hello\")\n            data = yield self.server.streams[0].read_bytes(5)\n            self.assertEqual(data, b\"hello\")\n\n    def test_connect_ipv4_ipv4(self):\n        self.do_test_connect(socket.AF_INET, '127.0.0.1')\n\n    def test_connect_ipv4_dual(self):\n        self.do_test_connect(socket.AF_INET, 'localhost')\n\n    @skipIfNoIPv6\n    def test_connect_ipv6_ipv6(self):\n        self.skipIfLocalhostV4()\n        self.do_test_connect(socket.AF_INET6, '::1')\n\n    @skipIfNoIPv6\n    def test_connect_ipv6_dual(self):\n        self.skipIfLocalhostV4()\n        if Resolver.configured_class().__name__.endswith('TwistedResolver'):\n            self.skipTest('TwistedResolver does not support multiple addresses')\n        self.do_test_connect(socket.AF_INET6, 'localhost')\n\n    def test_connect_unspec_ipv4(self):\n        self.do_test_connect(socket.AF_UNSPEC, '127.0.0.1')\n\n    @skipIfNoIPv6\n    def test_connect_unspec_ipv6(self):\n        self.skipIfLocalhostV4()\n        self.do_test_connect(socket.AF_UNSPEC, '::1')\n\n    def test_connect_unspec_dual(self):\n        self.do_test_connect(socket.AF_UNSPEC, 'localhost')\n\n    @gen_test\n    def test_refused_ipv4(self):\n        cleanup_func, port = refusing_port()\n        self.addCleanup(cleanup_func)\n        with self.assertRaises(IOError):\n            yield self.client.connect('127.0.0.1', port)\n\n\nclass TestConnectorSplit(unittest.TestCase):\n    def test_one_family(self):\n        # These addresses aren't in the right format, but split doesn't care.\n        primary, secondary = _Connector.split(\n            [(AF1, 'a'),\n             (AF1, 'b')])\n        self.assertEqual(primary, [(AF1, 'a'),\n                                   (AF1, 'b')])\n        self.assertEqual(secondary, [])\n\n    def test_mixed(self):\n        primary, secondary = _Connector.split(\n            [(AF1, 'a'),\n             (AF2, 'b'),\n             (AF1, 'c'),\n             (AF2, 'd')])\n        self.assertEqual(primary, [(AF1, 'a'), (AF1, 'c')])\n        self.assertEqual(secondary, [(AF2, 'b'), (AF2, 'd')])\n\n\nclass ConnectorTest(AsyncTestCase):\n    class FakeStream(object):\n        def __init__(self):\n            self.closed = False\n\n        def close(self):\n            self.closed = True\n\n    def setUp(self):\n        super(ConnectorTest, self).setUp()\n        self.connect_futures = {}\n        self.streams = {}\n        self.addrinfo = [(AF1, 'a'), (AF1, 'b'),\n                         (AF2, 'c'), (AF2, 'd')]\n\n    def tearDown(self):\n        # Unless explicitly checked (and popped) in the test, we shouldn't\n        # be closing any streams\n        for stream in self.streams.values():\n            self.assertFalse(stream.closed)\n        super(ConnectorTest, self).tearDown()\n\n    def create_stream(self, af, addr):\n        future = Future()\n        self.connect_futures[(af, addr)] = future\n        return future\n\n    def assert_pending(self, *keys):\n        self.assertEqual(sorted(self.connect_futures.keys()), sorted(keys))\n\n    def resolve_connect(self, af, addr, success):\n        future = self.connect_futures.pop((af, addr))\n        if success:\n            self.streams[addr] = ConnectorTest.FakeStream()\n            future.set_result(self.streams[addr])\n        else:\n            future.set_exception(IOError())\n\n    def start_connect(self, addrinfo):\n        conn = _Connector(addrinfo, self.io_loop, self.create_stream)\n        # Give it a huge timeout; we'll trigger timeouts manually.\n        future = conn.start(3600)\n        return conn, future\n\n    def test_immediate_success(self):\n        conn, future = self.start_connect(self.addrinfo)\n        self.assertEqual(list(self.connect_futures.keys()),\n                         [(AF1, 'a')])\n        self.resolve_connect(AF1, 'a', True)\n        self.assertEqual(future.result(), (AF1, 'a', self.streams['a']))\n\n    def test_immediate_failure(self):\n        # Fail with just one address.\n        conn, future = self.start_connect([(AF1, 'a')])\n        self.assert_pending((AF1, 'a'))\n        self.resolve_connect(AF1, 'a', False)\n        self.assertRaises(IOError, future.result)\n\n    def test_one_family_second_try(self):\n        conn, future = self.start_connect([(AF1, 'a'), (AF1, 'b')])\n        self.assert_pending((AF1, 'a'))\n        self.resolve_connect(AF1, 'a', False)\n        self.assert_pending((AF1, 'b'))\n        self.resolve_connect(AF1, 'b', True)\n        self.assertEqual(future.result(), (AF1, 'b', self.streams['b']))\n\n    def test_one_family_second_try_failure(self):\n        conn, future = self.start_connect([(AF1, 'a'), (AF1, 'b')])\n        self.assert_pending((AF1, 'a'))\n        self.resolve_connect(AF1, 'a', False)\n        self.assert_pending((AF1, 'b'))\n        self.resolve_connect(AF1, 'b', False)\n        self.assertRaises(IOError, future.result)\n\n    def test_one_family_second_try_timeout(self):\n        conn, future = self.start_connect([(AF1, 'a'), (AF1, 'b')])\n        self.assert_pending((AF1, 'a'))\n        # trigger the timeout while the first lookup is pending;\n        # nothing happens.\n        conn.on_timeout()\n        self.assert_pending((AF1, 'a'))\n        self.resolve_connect(AF1, 'a', False)\n        self.assert_pending((AF1, 'b'))\n        self.resolve_connect(AF1, 'b', True)\n        self.assertEqual(future.result(), (AF1, 'b', self.streams['b']))\n\n    def test_two_families_immediate_failure(self):\n        conn, future = self.start_connect(self.addrinfo)\n        self.assert_pending((AF1, 'a'))\n        self.resolve_connect(AF1, 'a', False)\n        self.assert_pending((AF1, 'b'), (AF2, 'c'))\n        self.resolve_connect(AF1, 'b', False)\n        self.resolve_connect(AF2, 'c', True)\n        self.assertEqual(future.result(), (AF2, 'c', self.streams['c']))\n\n    def test_two_families_timeout(self):\n        conn, future = self.start_connect(self.addrinfo)\n        self.assert_pending((AF1, 'a'))\n        conn.on_timeout()\n        self.assert_pending((AF1, 'a'), (AF2, 'c'))\n        self.resolve_connect(AF2, 'c', True)\n        self.assertEqual(future.result(), (AF2, 'c', self.streams['c']))\n        # resolving 'a' after the connection has completed doesn't start 'b'\n        self.resolve_connect(AF1, 'a', False)\n        self.assert_pending()\n\n    def test_success_after_timeout(self):\n        conn, future = self.start_connect(self.addrinfo)\n        self.assert_pending((AF1, 'a'))\n        conn.on_timeout()\n        self.assert_pending((AF1, 'a'), (AF2, 'c'))\n        self.resolve_connect(AF1, 'a', True)\n        self.assertEqual(future.result(), (AF1, 'a', self.streams['a']))\n        # resolving 'c' after completion closes the connection.\n        self.resolve_connect(AF2, 'c', True)\n        self.assertTrue(self.streams.pop('c').closed)\n\n    def test_all_fail(self):\n        conn, future = self.start_connect(self.addrinfo)\n        self.assert_pending((AF1, 'a'))\n        conn.on_timeout()\n        self.assert_pending((AF1, 'a'), (AF2, 'c'))\n        self.resolve_connect(AF2, 'c', False)\n        self.assert_pending((AF1, 'a'), (AF2, 'd'))\n        self.resolve_connect(AF2, 'd', False)\n        # one queue is now empty\n        self.assert_pending((AF1, 'a'))\n        self.resolve_connect(AF1, 'a', False)\n        self.assert_pending((AF1, 'b'))\n        self.assertFalse(future.done())\n        self.resolve_connect(AF1, 'b', False)\n        self.assertRaises(IOError, future.result)\n",
            "new_file_content": "#!/usr/bin/env python\n#\n# Copyright 2014 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\nfrom __future__ import absolute_import, division, print_function, with_statement\n\nfrom contextlib import closing\nimport os\nimport socket\n\nfrom tornado.concurrent import Future\nfrom tornado.netutil import bind_sockets, Resolver\nfrom tornado.tcpclient import TCPClient, _Connector\nfrom tornado.tcpserver import TCPServer\nfrom tornado.testing import AsyncTestCase, gen_test\nfrom tornado.test.util import skipIfNoIPv6, unittest, refusing_port, skipIfNonUnix\n\n# Fake address families for testing.  Used in place of AF_INET\n# and AF_INET6 because some installations do not have AF_INET6.\nAF1, AF2 = 1, 2\n\n\nclass TestTCPServer(TCPServer):\n    def __init__(self, family):\n        super(TestTCPServer, self).__init__()\n        self.streams = []\n        sockets = bind_sockets(None, 'localhost', family)\n        self.add_sockets(sockets)\n        self.port = sockets[0].getsockname()[1]\n\n    def handle_stream(self, stream, address):\n        self.streams.append(stream)\n\n    def stop(self):\n        super(TestTCPServer, self).stop()\n        for stream in self.streams:\n            stream.close()\n\n\nclass TCPClientTest(AsyncTestCase):\n    def setUp(self):\n        super(TCPClientTest, self).setUp()\n        self.server = None\n        self.client = TCPClient()\n\n    def start_server(self, family):\n        if family == socket.AF_UNSPEC and 'TRAVIS' in os.environ:\n            self.skipTest(\"dual-stack servers often have port conflicts on travis\")\n        self.server = TestTCPServer(family)\n        return self.server.port\n\n    def stop_server(self):\n        if self.server is not None:\n            self.server.stop()\n            self.server = None\n\n    def tearDown(self):\n        self.client.close()\n        self.stop_server()\n        super(TCPClientTest, self).tearDown()\n\n    def skipIfLocalhostV4(self):\n        # The port used here doesn't matter, but some systems require it\n        # to be non-zero if we do not also pass AI_PASSIVE.\n        Resolver().resolve('localhost', 80, callback=self.stop)\n        addrinfo = self.wait()\n        families = set(addr[0] for addr in addrinfo)\n        if socket.AF_INET6 not in families:\n            self.skipTest(\"localhost does not resolve to ipv6\")\n\n    @gen_test\n    def do_test_connect(self, family, host, source_ip=None, source_port=None):\n        port = self.start_server(family)\n        stream = yield self.client.connect(host, port,\n                                           source_ip=source_ip,\n                                           source_port=source_port)\n        with closing(stream):\n            stream.write(b\"hello\")\n            data = yield self.server.streams[0].read_bytes(5)\n            self.assertEqual(data, b\"hello\")\n\n    def test_connect_ipv4_ipv4(self):\n        self.do_test_connect(socket.AF_INET, '127.0.0.1')\n\n    def test_connect_ipv4_dual(self):\n        self.do_test_connect(socket.AF_INET, 'localhost')\n\n    @skipIfNoIPv6\n    def test_connect_ipv6_ipv6(self):\n        self.skipIfLocalhostV4()\n        self.do_test_connect(socket.AF_INET6, '::1')\n\n    @skipIfNoIPv6\n    def test_connect_ipv6_dual(self):\n        self.skipIfLocalhostV4()\n        if Resolver.configured_class().__name__.endswith('TwistedResolver'):\n            self.skipTest('TwistedResolver does not support multiple addresses')\n        self.do_test_connect(socket.AF_INET6, 'localhost')\n\n    def test_connect_unspec_ipv4(self):\n        self.do_test_connect(socket.AF_UNSPEC, '127.0.0.1')\n\n    @skipIfNoIPv6\n    def test_connect_unspec_ipv6(self):\n        self.skipIfLocalhostV4()\n        self.do_test_connect(socket.AF_UNSPEC, '::1')\n\n    def test_connect_unspec_dual(self):\n        self.do_test_connect(socket.AF_UNSPEC, 'localhost')\n\n    @gen_test\n    def test_refused_ipv4(self):\n        cleanup_func, port = refusing_port()\n        self.addCleanup(cleanup_func)\n        with self.assertRaises(IOError):\n            yield self.client.connect('127.0.0.1', port)\n\n    def test_source_ip_fail(self):\n        '''\n        Fail when trying to use the source IP Address '8.8.8.8'.\n        '''\n        self.assertRaises(socket.error,\n                          self.do_test_connect,\n                          socket.AF_INET,\n                          '127.0.0.1',\n                          source_ip='8.8.8.8')\n\n    def test_source_ip_success(self):\n        '''\n        Success when trying to use the source IP Address '127.0.0.1'\n        '''\n        self.do_test_connect(socket.AF_INET, '127.0.0.1', source_ip='127.0.0.1')\n\n    @skipIfNonUnix\n    def test_source_port_fail(self):\n        '''\n        Fail when trying to use source port 1.\n        '''\n        self.assertRaises(socket.error,\n                          self.do_test_connect,\n                          socket.AF_INET,\n                          '127.0.0.1',\n                          source_port=1)\n\n\nclass TestConnectorSplit(unittest.TestCase):\n    def test_one_family(self):\n        # These addresses aren't in the right format, but split doesn't care.\n        primary, secondary = _Connector.split(\n            [(AF1, 'a'),\n             (AF1, 'b')])\n        self.assertEqual(primary, [(AF1, 'a'),\n                                   (AF1, 'b')])\n        self.assertEqual(secondary, [])\n\n    def test_mixed(self):\n        primary, secondary = _Connector.split(\n            [(AF1, 'a'),\n             (AF2, 'b'),\n             (AF1, 'c'),\n             (AF2, 'd')])\n        self.assertEqual(primary, [(AF1, 'a'), (AF1, 'c')])\n        self.assertEqual(secondary, [(AF2, 'b'), (AF2, 'd')])\n\n\nclass ConnectorTest(AsyncTestCase):\n    class FakeStream(object):\n        def __init__(self):\n            self.closed = False\n\n        def close(self):\n            self.closed = True\n\n    def setUp(self):\n        super(ConnectorTest, self).setUp()\n        self.connect_futures = {}\n        self.streams = {}\n        self.addrinfo = [(AF1, 'a'), (AF1, 'b'),\n                         (AF2, 'c'), (AF2, 'd')]\n\n    def tearDown(self):\n        # Unless explicitly checked (and popped) in the test, we shouldn't\n        # be closing any streams\n        for stream in self.streams.values():\n            self.assertFalse(stream.closed)\n        super(ConnectorTest, self).tearDown()\n\n    def create_stream(self, af, addr):\n        future = Future()\n        self.connect_futures[(af, addr)] = future\n        return future\n\n    def assert_pending(self, *keys):\n        self.assertEqual(sorted(self.connect_futures.keys()), sorted(keys))\n\n    def resolve_connect(self, af, addr, success):\n        future = self.connect_futures.pop((af, addr))\n        if success:\n            self.streams[addr] = ConnectorTest.FakeStream()\n            future.set_result(self.streams[addr])\n        else:\n            future.set_exception(IOError())\n\n    def start_connect(self, addrinfo):\n        conn = _Connector(addrinfo, self.io_loop, self.create_stream)\n        # Give it a huge timeout; we'll trigger timeouts manually.\n        future = conn.start(3600)\n        return conn, future\n\n    def test_immediate_success(self):\n        conn, future = self.start_connect(self.addrinfo)\n        self.assertEqual(list(self.connect_futures.keys()),\n                         [(AF1, 'a')])\n        self.resolve_connect(AF1, 'a', True)\n        self.assertEqual(future.result(), (AF1, 'a', self.streams['a']))\n\n    def test_immediate_failure(self):\n        # Fail with just one address.\n        conn, future = self.start_connect([(AF1, 'a')])\n        self.assert_pending((AF1, 'a'))\n        self.resolve_connect(AF1, 'a', False)\n        self.assertRaises(IOError, future.result)\n\n    def test_one_family_second_try(self):\n        conn, future = self.start_connect([(AF1, 'a'), (AF1, 'b')])\n        self.assert_pending((AF1, 'a'))\n        self.resolve_connect(AF1, 'a', False)\n        self.assert_pending((AF1, 'b'))\n        self.resolve_connect(AF1, 'b', True)\n        self.assertEqual(future.result(), (AF1, 'b', self.streams['b']))\n\n    def test_one_family_second_try_failure(self):\n        conn, future = self.start_connect([(AF1, 'a'), (AF1, 'b')])\n        self.assert_pending((AF1, 'a'))\n        self.resolve_connect(AF1, 'a', False)\n        self.assert_pending((AF1, 'b'))\n        self.resolve_connect(AF1, 'b', False)\n        self.assertRaises(IOError, future.result)\n\n    def test_one_family_second_try_timeout(self):\n        conn, future = self.start_connect([(AF1, 'a'), (AF1, 'b')])\n        self.assert_pending((AF1, 'a'))\n        # trigger the timeout while the first lookup is pending;\n        # nothing happens.\n        conn.on_timeout()\n        self.assert_pending((AF1, 'a'))\n        self.resolve_connect(AF1, 'a', False)\n        self.assert_pending((AF1, 'b'))\n        self.resolve_connect(AF1, 'b', True)\n        self.assertEqual(future.result(), (AF1, 'b', self.streams['b']))\n\n    def test_two_families_immediate_failure(self):\n        conn, future = self.start_connect(self.addrinfo)\n        self.assert_pending((AF1, 'a'))\n        self.resolve_connect(AF1, 'a', False)\n        self.assert_pending((AF1, 'b'), (AF2, 'c'))\n        self.resolve_connect(AF1, 'b', False)\n        self.resolve_connect(AF2, 'c', True)\n        self.assertEqual(future.result(), (AF2, 'c', self.streams['c']))\n\n    def test_two_families_timeout(self):\n        conn, future = self.start_connect(self.addrinfo)\n        self.assert_pending((AF1, 'a'))\n        conn.on_timeout()\n        self.assert_pending((AF1, 'a'), (AF2, 'c'))\n        self.resolve_connect(AF2, 'c', True)\n        self.assertEqual(future.result(), (AF2, 'c', self.streams['c']))\n        # resolving 'a' after the connection has completed doesn't start 'b'\n        self.resolve_connect(AF1, 'a', False)\n        self.assert_pending()\n\n    def test_success_after_timeout(self):\n        conn, future = self.start_connect(self.addrinfo)\n        self.assert_pending((AF1, 'a'))\n        conn.on_timeout()\n        self.assert_pending((AF1, 'a'), (AF2, 'c'))\n        self.resolve_connect(AF1, 'a', True)\n        self.assertEqual(future.result(), (AF1, 'a', self.streams['a']))\n        # resolving 'c' after completion closes the connection.\n        self.resolve_connect(AF2, 'c', True)\n        self.assertTrue(self.streams.pop('c').closed)\n\n    def test_all_fail(self):\n        conn, future = self.start_connect(self.addrinfo)\n        self.assert_pending((AF1, 'a'))\n        conn.on_timeout()\n        self.assert_pending((AF1, 'a'), (AF2, 'c'))\n        self.resolve_connect(AF2, 'c', False)\n        self.assert_pending((AF1, 'a'), (AF2, 'd'))\n        self.resolve_connect(AF2, 'd', False)\n        # one queue is now empty\n        self.assert_pending((AF1, 'a'))\n        self.resolve_connect(AF1, 'a', False)\n        self.assert_pending((AF1, 'b'))\n        self.assertFalse(future.done())\n        self.resolve_connect(AF1, 'b', False)\n        self.assertRaises(IOError, future.result)\n",
            "header": {
                "file": {
                    "path": "tornado/test/tcpclient_test.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "1a4201e6",
                "new_commit_hash": "702e0308",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/tornado/test/tcpclient_test.py"
            },
            "plus_file": {
                "path": "b/tornado/test/tcpclient_test.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 25,
                            "length": 7
                        },
                        "new_range": {
                            "start": 25,
                            "length": 7
                        },
                        "section": "from tornado.netutil import bind_sockets, Resolver"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "from tornado.tcpclient import TCPClient, _Connector",
                                "type": "context"
                            },
                            {
                                "content": "from tornado.tcpserver import TCPServer",
                                "type": "context"
                            },
                            {
                                "content": "from tornado.testing import AsyncTestCase, gen_test",
                                "type": "context"
                            },
                            {
                                "content": "from tornado.test.util import skipIfNoIPv6, unittest, refusing_port",
                                "type": "deleted"
                            },
                            {
                                "content": "from tornado.test.util import skipIfNoIPv6, unittest, refusing_port, skipIfNonUnix",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "# Fake address families for testing.  Used in place of AF_INET",
                                "type": "context"
                            },
                            {
                                "content": "# and AF_INET6 because some installations do not have AF_INET6.",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [],
                    "added_entities": [
                        {
                            "file_name": "tornado/test/tcpclient_test.py",
                            "type": "statement",
                            "name": "",
                            "content": "from tornado.test.util import skipIfNoIPv6, unittest, refusing_port, skipIfNonUnix",
                            "ast_type_str": "ImportFrom",
                            "start_lineno": 28,
                            "end_lineno": 28,
                            "parent": null
                        }
                    ],
                    "deleted_entities": [
                        {
                            "file_name": "tornado/test/tcpclient_test.py",
                            "type": "statement",
                            "name": "",
                            "content": "from tornado.test.util import skipIfNoIPv6, unittest, refusing_port",
                            "ast_type_str": "ImportFrom",
                            "start_lineno": 28,
                            "end_lineno": 28,
                            "parent": null
                        }
                    ]
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 81,
                            "length": 9
                        },
                        "new_range": {
                            "start": 81,
                            "length": 11
                        },
                        "section": "class TCPClientTest(AsyncTestCase):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "            self.skipTest(\"localhost does not resolve to ipv6\")",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    @gen_test",
                                "type": "context"
                            },
                            {
                                "content": "    def do_test_connect(self, family, host):",
                                "type": "deleted"
                            },
                            {
                                "content": "    def do_test_connect(self, family, host, source_ip=None, source_port=None):",
                                "type": "added"
                            },
                            {
                                "content": "        port = self.start_server(family)",
                                "type": "context"
                            },
                            {
                                "content": "        stream = yield self.client.connect(host, port)",
                                "type": "deleted"
                            },
                            {
                                "content": "        stream = yield self.client.connect(host, port,",
                                "type": "added"
                            },
                            {
                                "content": "                                           source_ip=source_ip,",
                                "type": "added"
                            },
                            {
                                "content": "                                           source_port=source_port)",
                                "type": "added"
                            },
                            {
                                "content": "        with closing(stream):",
                                "type": "context"
                            },
                            {
                                "content": "            stream.write(b\"hello\")",
                                "type": "context"
                            },
                            {
                                "content": "            data = yield self.server.streams[0].read_bytes(5)",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/test/tcpclient_test.py",
                            "type": "method",
                            "name": "TCPClientTest.do_test_connect",
                            "content": "class TCPClientTest(AsyncTestCase):\n    def setUp(self):\n        super(TCPClientTest, self).setUp()\n        self.server = None\n        self.client = TCPClient()\n\n    def start_server(self, family):\n        if family == socket.AF_UNSPEC and 'TRAVIS' in os.environ:\n            self.skipTest(\"dual-stack servers often have port conflicts on travis\")\n        self.server = TestTCPServer(family)\n        return self.server.port\n\n    def stop_server(self):\n        if self.server is not None:\n            self.server.stop()\n            self.server = None\n\n    def tearDown(self):\n        self.client.close()\n        self.stop_server()\n        super(TCPClientTest, self).tearDown()\n\n    def skipIfLocalhostV4(self):\n        # The port used here doesn't matter, but some systems require it\n        # to be non-zero if we do not also pass AI_PASSIVE.\n        Resolver().resolve('localhost', 80, callback=self.stop)\n        addrinfo = self.wait()\n        families = set(addr[0] for addr in addrinfo)\n        if socket.AF_INET6 not in families:\n            self.skipTest(\"localhost does not resolve to ipv6\")\n\n    @gen_test\n    def do_test_connect(self, family, host):\n        port = self.start_server(family)\n        stream = yield self.client.connect(host, port)\n        with closing(stream):\n            stream.write(b\"hello\")\n            data = yield self.server.streams[0].read_bytes(5)\n            self.assertEqual(data, b\"hello\")\n\n    def test_connect_ipv4_ipv4(self):\n        self.do_test_connect(socket.AF_INET, '127.0.0.1')\n\n    def test_connect_ipv4_dual(self):\n        self.do_test_connect(socket.AF_INET, 'localhost')\n\n    @skipIfNoIPv6\n    def test_connect_ipv6_ipv6(self):\n        self.skipIfLocalhostV4()\n        self.do_test_connect(socket.AF_INET6, '::1')\n\n    @skipIfNoIPv6\n    def test_connect_ipv6_dual(self):\n        self.skipIfLocalhostV4()\n        if Resolver.configured_class().__name__.endswith('TwistedResolver'):\n            self.skipTest('TwistedResolver does not support multiple addresses')\n        self.do_test_connect(socket.AF_INET6, 'localhost')\n\n    def test_connect_unspec_ipv4(self):\n        self.do_test_connect(socket.AF_UNSPEC, '127.0.0.1')\n\n    @skipIfNoIPv6\n    def test_connect_unspec_ipv6(self):\n        self.skipIfLocalhostV4()\n        self.do_test_connect(socket.AF_UNSPEC, '::1')\n\n    def test_connect_unspec_dual(self):\n        self.do_test_connect(socket.AF_UNSPEC, 'localhost')\n\n    @gen_test\n    def test_refused_ipv4(self):\n        cleanup_func, port = refusing_port()\n        self.addCleanup(cleanup_func)\n        with self.assertRaises(IOError):\n            yield self.client.connect('127.0.0.1', port)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 84,
                            "end_lineno": 90,
                            "parent": {
                                "file_name": "tornado/test/tcpclient_test.py",
                                "type": "class",
                                "name": "TCPClientTest",
                                "content": "class TCPClientTest(AsyncTestCase):\n    def setUp(self):\n        super(TCPClientTest, self).setUp()\n        self.server = None\n        self.client = TCPClient()\n\n    def start_server(self, family):\n        if family == socket.AF_UNSPEC and 'TRAVIS' in os.environ:\n            self.skipTest(\"dual-stack servers often have port conflicts on travis\")\n        self.server = TestTCPServer(family)\n        return self.server.port\n\n    def stop_server(self):\n        if self.server is not None:\n            self.server.stop()\n            self.server = None\n\n    def tearDown(self):\n        self.client.close()\n        self.stop_server()\n        super(TCPClientTest, self).tearDown()\n\n    def skipIfLocalhostV4(self):\n        # The port used here doesn't matter, but some systems require it\n        # to be non-zero if we do not also pass AI_PASSIVE.\n        Resolver().resolve('localhost', 80, callback=self.stop)\n        addrinfo = self.wait()\n        families = set(addr[0] for addr in addrinfo)\n        if socket.AF_INET6 not in families:\n            self.skipTest(\"localhost does not resolve to ipv6\")\n\n    @gen_test\n    def do_test_connect(self, family, host):\n        port = self.start_server(family)\n        stream = yield self.client.connect(host, port)\n        with closing(stream):\n            stream.write(b\"hello\")\n            data = yield self.server.streams[0].read_bytes(5)\n            self.assertEqual(data, b\"hello\")\n\n    def test_connect_ipv4_ipv4(self):\n        self.do_test_connect(socket.AF_INET, '127.0.0.1')\n\n    def test_connect_ipv4_dual(self):\n        self.do_test_connect(socket.AF_INET, 'localhost')\n\n    @skipIfNoIPv6\n    def test_connect_ipv6_ipv6(self):\n        self.skipIfLocalhostV4()\n        self.do_test_connect(socket.AF_INET6, '::1')\n\n    @skipIfNoIPv6\n    def test_connect_ipv6_dual(self):\n        self.skipIfLocalhostV4()\n        if Resolver.configured_class().__name__.endswith('TwistedResolver'):\n            self.skipTest('TwistedResolver does not support multiple addresses')\n        self.do_test_connect(socket.AF_INET6, 'localhost')\n\n    def test_connect_unspec_ipv4(self):\n        self.do_test_connect(socket.AF_UNSPEC, '127.0.0.1')\n\n    @skipIfNoIPv6\n    def test_connect_unspec_ipv6(self):\n        self.skipIfLocalhostV4()\n        self.do_test_connect(socket.AF_UNSPEC, '::1')\n\n    def test_connect_unspec_dual(self):\n        self.do_test_connect(socket.AF_UNSPEC, 'localhost')\n\n    @gen_test\n    def test_refused_ipv4(self):\n        cleanup_func, port = refusing_port()\n        self.addCleanup(cleanup_func)\n        with self.assertRaises(IOError):\n            yield self.client.connect('127.0.0.1', port)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 52,
                                "end_lineno": 126,
                                "parent": null
                            }
                        },
                        {
                            "file_name": "tornado/test/tcpclient_test.py",
                            "type": "class",
                            "name": "TCPClientTest",
                            "content": "class TCPClientTest(AsyncTestCase):\n    def setUp(self):\n        super(TCPClientTest, self).setUp()\n        self.server = None\n        self.client = TCPClient()\n\n    def start_server(self, family):\n        if family == socket.AF_UNSPEC and 'TRAVIS' in os.environ:\n            self.skipTest(\"dual-stack servers often have port conflicts on travis\")\n        self.server = TestTCPServer(family)\n        return self.server.port\n\n    def stop_server(self):\n        if self.server is not None:\n            self.server.stop()\n            self.server = None\n\n    def tearDown(self):\n        self.client.close()\n        self.stop_server()\n        super(TCPClientTest, self).tearDown()\n\n    def skipIfLocalhostV4(self):\n        # The port used here doesn't matter, but some systems require it\n        # to be non-zero if we do not also pass AI_PASSIVE.\n        Resolver().resolve('localhost', 80, callback=self.stop)\n        addrinfo = self.wait()\n        families = set(addr[0] for addr in addrinfo)\n        if socket.AF_INET6 not in families:\n            self.skipTest(\"localhost does not resolve to ipv6\")\n\n    @gen_test\n    def do_test_connect(self, family, host):\n        port = self.start_server(family)\n        stream = yield self.client.connect(host, port)\n        with closing(stream):\n            stream.write(b\"hello\")\n            data = yield self.server.streams[0].read_bytes(5)\n            self.assertEqual(data, b\"hello\")\n\n    def test_connect_ipv4_ipv4(self):\n        self.do_test_connect(socket.AF_INET, '127.0.0.1')\n\n    def test_connect_ipv4_dual(self):\n        self.do_test_connect(socket.AF_INET, 'localhost')\n\n    @skipIfNoIPv6\n    def test_connect_ipv6_ipv6(self):\n        self.skipIfLocalhostV4()\n        self.do_test_connect(socket.AF_INET6, '::1')\n\n    @skipIfNoIPv6\n    def test_connect_ipv6_dual(self):\n        self.skipIfLocalhostV4()\n        if Resolver.configured_class().__name__.endswith('TwistedResolver'):\n            self.skipTest('TwistedResolver does not support multiple addresses')\n        self.do_test_connect(socket.AF_INET6, 'localhost')\n\n    def test_connect_unspec_ipv4(self):\n        self.do_test_connect(socket.AF_UNSPEC, '127.0.0.1')\n\n    @skipIfNoIPv6\n    def test_connect_unspec_ipv6(self):\n        self.skipIfLocalhostV4()\n        self.do_test_connect(socket.AF_UNSPEC, '::1')\n\n    def test_connect_unspec_dual(self):\n        self.do_test_connect(socket.AF_UNSPEC, 'localhost')\n\n    @gen_test\n    def test_refused_ipv4(self):\n        cleanup_func, port = refusing_port()\n        self.addCleanup(cleanup_func)\n        with self.assertRaises(IOError):\n            yield self.client.connect('127.0.0.1', port)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 52,
                            "end_lineno": 126,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 125,
                            "length": 6
                        },
                        "new_range": {
                            "start": 127,
                            "length": 33
                        },
                        "section": "class TCPClientTest(AsyncTestCase):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        with self.assertRaises(IOError):",
                                "type": "context"
                            },
                            {
                                "content": "            yield self.client.connect('127.0.0.1', port)",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def test_source_ip_fail(self):",
                                "type": "added"
                            },
                            {
                                "content": "        '''",
                                "type": "added"
                            },
                            {
                                "content": "        Fail when trying to use the source IP Address '8.8.8.8'.",
                                "type": "added"
                            },
                            {
                                "content": "        '''",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertRaises(socket.error,",
                                "type": "added"
                            },
                            {
                                "content": "                          self.do_test_connect,",
                                "type": "added"
                            },
                            {
                                "content": "                          socket.AF_INET,",
                                "type": "added"
                            },
                            {
                                "content": "                          '127.0.0.1',",
                                "type": "added"
                            },
                            {
                                "content": "                          source_ip='8.8.8.8')",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    def test_source_ip_success(self):",
                                "type": "added"
                            },
                            {
                                "content": "        '''",
                                "type": "added"
                            },
                            {
                                "content": "        Success when trying to use the source IP Address '127.0.0.1'",
                                "type": "added"
                            },
                            {
                                "content": "        '''",
                                "type": "added"
                            },
                            {
                                "content": "        self.do_test_connect(socket.AF_INET, '127.0.0.1', source_ip='127.0.0.1')",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    @skipIfNonUnix",
                                "type": "added"
                            },
                            {
                                "content": "    def test_source_port_fail(self):",
                                "type": "added"
                            },
                            {
                                "content": "        '''",
                                "type": "added"
                            },
                            {
                                "content": "        Fail when trying to use source port 1.",
                                "type": "added"
                            },
                            {
                                "content": "        '''",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertRaises(socket.error,",
                                "type": "added"
                            },
                            {
                                "content": "                          self.do_test_connect,",
                                "type": "added"
                            },
                            {
                                "content": "                          socket.AF_INET,",
                                "type": "added"
                            },
                            {
                                "content": "                          '127.0.0.1',",
                                "type": "added"
                            },
                            {
                                "content": "                          source_port=1)",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "class TestConnectorSplit(unittest.TestCase):",
                                "type": "context"
                            },
                            {
                                "content": "    def test_one_family(self):",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/test/tcpclient_test.py",
                            "type": "class",
                            "name": "TCPClientTest",
                            "content": "class TCPClientTest(AsyncTestCase):\n    def setUp(self):\n        super(TCPClientTest, self).setUp()\n        self.server = None\n        self.client = TCPClient()\n\n    def start_server(self, family):\n        if family == socket.AF_UNSPEC and 'TRAVIS' in os.environ:\n            self.skipTest(\"dual-stack servers often have port conflicts on travis\")\n        self.server = TestTCPServer(family)\n        return self.server.port\n\n    def stop_server(self):\n        if self.server is not None:\n            self.server.stop()\n            self.server = None\n\n    def tearDown(self):\n        self.client.close()\n        self.stop_server()\n        super(TCPClientTest, self).tearDown()\n\n    def skipIfLocalhostV4(self):\n        # The port used here doesn't matter, but some systems require it\n        # to be non-zero if we do not also pass AI_PASSIVE.\n        Resolver().resolve('localhost', 80, callback=self.stop)\n        addrinfo = self.wait()\n        families = set(addr[0] for addr in addrinfo)\n        if socket.AF_INET6 not in families:\n            self.skipTest(\"localhost does not resolve to ipv6\")\n\n    @gen_test\n    def do_test_connect(self, family, host, source_ip=None, source_port=None):\n        port = self.start_server(family)\n        stream = yield self.client.connect(host, port,\n                                           source_ip=source_ip,\n                                           source_port=source_port)\n        with closing(stream):\n            stream.write(b\"hello\")\n            data = yield self.server.streams[0].read_bytes(5)\n            self.assertEqual(data, b\"hello\")\n\n    def test_connect_ipv4_ipv4(self):\n        self.do_test_connect(socket.AF_INET, '127.0.0.1')\n\n    def test_connect_ipv4_dual(self):\n        self.do_test_connect(socket.AF_INET, 'localhost')\n\n    @skipIfNoIPv6\n    def test_connect_ipv6_ipv6(self):\n        self.skipIfLocalhostV4()\n        self.do_test_connect(socket.AF_INET6, '::1')\n\n    @skipIfNoIPv6\n    def test_connect_ipv6_dual(self):\n        self.skipIfLocalhostV4()\n        if Resolver.configured_class().__name__.endswith('TwistedResolver'):\n            self.skipTest('TwistedResolver does not support multiple addresses')\n        self.do_test_connect(socket.AF_INET6, 'localhost')\n\n    def test_connect_unspec_ipv4(self):\n        self.do_test_connect(socket.AF_UNSPEC, '127.0.0.1')\n\n    @skipIfNoIPv6\n    def test_connect_unspec_ipv6(self):\n        self.skipIfLocalhostV4()\n        self.do_test_connect(socket.AF_UNSPEC, '::1')\n\n    def test_connect_unspec_dual(self):\n        self.do_test_connect(socket.AF_UNSPEC, 'localhost')\n\n    @gen_test\n    def test_refused_ipv4(self):\n        cleanup_func, port = refusing_port()\n        self.addCleanup(cleanup_func)\n        with self.assertRaises(IOError):\n            yield self.client.connect('127.0.0.1', port)\n\n    def test_source_ip_fail(self):\n        '''\n        Fail when trying to use the source IP Address '8.8.8.8'.\n        '''\n        self.assertRaises(socket.error,\n                          self.do_test_connect,\n                          socket.AF_INET,\n                          '127.0.0.1',\n                          source_ip='8.8.8.8')\n\n    def test_source_ip_success(self):\n        '''\n        Success when trying to use the source IP Address '127.0.0.1'\n        '''\n        self.do_test_connect(socket.AF_INET, '127.0.0.1', source_ip='127.0.0.1')\n\n    @skipIfNonUnix\n    def test_source_port_fail(self):\n        '''\n        Fail when trying to use source port 1.\n        '''\n        self.assertRaises(socket.error,\n                          self.do_test_connect,\n                          socket.AF_INET,\n                          '127.0.0.1',\n                          source_port=1)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 52,
                            "end_lineno": 155,
                            "parent": null
                        }
                    ],
                    "added_entities": [
                        {
                            "file_name": "tornado/test/tcpclient_test.py",
                            "type": "method",
                            "name": "TCPClientTest.test_source_port_fail",
                            "content": "class TCPClientTest(AsyncTestCase):\n    def setUp(self):\n        super(TCPClientTest, self).setUp()\n        self.server = None\n        self.client = TCPClient()\n\n    def start_server(self, family):\n        if family == socket.AF_UNSPEC and 'TRAVIS' in os.environ:\n            self.skipTest(\"dual-stack servers often have port conflicts on travis\")\n        self.server = TestTCPServer(family)\n        return self.server.port\n\n    def stop_server(self):\n        if self.server is not None:\n            self.server.stop()\n            self.server = None\n\n    def tearDown(self):\n        self.client.close()\n        self.stop_server()\n        super(TCPClientTest, self).tearDown()\n\n    def skipIfLocalhostV4(self):\n        # The port used here doesn't matter, but some systems require it\n        # to be non-zero if we do not also pass AI_PASSIVE.\n        Resolver().resolve('localhost', 80, callback=self.stop)\n        addrinfo = self.wait()\n        families = set(addr[0] for addr in addrinfo)\n        if socket.AF_INET6 not in families:\n            self.skipTest(\"localhost does not resolve to ipv6\")\n\n    @gen_test\n    def do_test_connect(self, family, host, source_ip=None, source_port=None):\n        port = self.start_server(family)\n        stream = yield self.client.connect(host, port,\n                                           source_ip=source_ip,\n                                           source_port=source_port)\n        with closing(stream):\n            stream.write(b\"hello\")\n            data = yield self.server.streams[0].read_bytes(5)\n            self.assertEqual(data, b\"hello\")\n\n    def test_connect_ipv4_ipv4(self):\n        self.do_test_connect(socket.AF_INET, '127.0.0.1')\n\n    def test_connect_ipv4_dual(self):\n        self.do_test_connect(socket.AF_INET, 'localhost')\n\n    @skipIfNoIPv6\n    def test_connect_ipv6_ipv6(self):\n        self.skipIfLocalhostV4()\n        self.do_test_connect(socket.AF_INET6, '::1')\n\n    @skipIfNoIPv6\n    def test_connect_ipv6_dual(self):\n        self.skipIfLocalhostV4()\n        if Resolver.configured_class().__name__.endswith('TwistedResolver'):\n            self.skipTest('TwistedResolver does not support multiple addresses')\n        self.do_test_connect(socket.AF_INET6, 'localhost')\n\n    def test_connect_unspec_ipv4(self):\n        self.do_test_connect(socket.AF_UNSPEC, '127.0.0.1')\n\n    @skipIfNoIPv6\n    def test_connect_unspec_ipv6(self):\n        self.skipIfLocalhostV4()\n        self.do_test_connect(socket.AF_UNSPEC, '::1')\n\n    def test_connect_unspec_dual(self):\n        self.do_test_connect(socket.AF_UNSPEC, 'localhost')\n\n    @gen_test\n    def test_refused_ipv4(self):\n        cleanup_func, port = refusing_port()\n        self.addCleanup(cleanup_func)\n        with self.assertRaises(IOError):\n            yield self.client.connect('127.0.0.1', port)\n\n    def test_source_ip_fail(self):\n        '''\n        Fail when trying to use the source IP Address '8.8.8.8'.\n        '''\n        self.assertRaises(socket.error,\n                          self.do_test_connect,\n                          socket.AF_INET,\n                          '127.0.0.1',\n                          source_ip='8.8.8.8')\n\n    def test_source_ip_success(self):\n        '''\n        Success when trying to use the source IP Address '127.0.0.1'\n        '''\n        self.do_test_connect(socket.AF_INET, '127.0.0.1', source_ip='127.0.0.1')\n\n    @skipIfNonUnix\n    def test_source_port_fail(self):\n        '''\n        Fail when trying to use source port 1.\n        '''\n        self.assertRaises(socket.error,\n                          self.do_test_connect,\n                          socket.AF_INET,\n                          '127.0.0.1',\n                          source_port=1)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 147,
                            "end_lineno": 155,
                            "parent": {
                                "file_name": "tornado/test/tcpclient_test.py",
                                "type": "class",
                                "name": "TCPClientTest",
                                "content": "class TCPClientTest(AsyncTestCase):\n    def setUp(self):\n        super(TCPClientTest, self).setUp()\n        self.server = None\n        self.client = TCPClient()\n\n    def start_server(self, family):\n        if family == socket.AF_UNSPEC and 'TRAVIS' in os.environ:\n            self.skipTest(\"dual-stack servers often have port conflicts on travis\")\n        self.server = TestTCPServer(family)\n        return self.server.port\n\n    def stop_server(self):\n        if self.server is not None:\n            self.server.stop()\n            self.server = None\n\n    def tearDown(self):\n        self.client.close()\n        self.stop_server()\n        super(TCPClientTest, self).tearDown()\n\n    def skipIfLocalhostV4(self):\n        # The port used here doesn't matter, but some systems require it\n        # to be non-zero if we do not also pass AI_PASSIVE.\n        Resolver().resolve('localhost', 80, callback=self.stop)\n        addrinfo = self.wait()\n        families = set(addr[0] for addr in addrinfo)\n        if socket.AF_INET6 not in families:\n            self.skipTest(\"localhost does not resolve to ipv6\")\n\n    @gen_test\n    def do_test_connect(self, family, host, source_ip=None, source_port=None):\n        port = self.start_server(family)\n        stream = yield self.client.connect(host, port,\n                                           source_ip=source_ip,\n                                           source_port=source_port)\n        with closing(stream):\n            stream.write(b\"hello\")\n            data = yield self.server.streams[0].read_bytes(5)\n            self.assertEqual(data, b\"hello\")\n\n    def test_connect_ipv4_ipv4(self):\n        self.do_test_connect(socket.AF_INET, '127.0.0.1')\n\n    def test_connect_ipv4_dual(self):\n        self.do_test_connect(socket.AF_INET, 'localhost')\n\n    @skipIfNoIPv6\n    def test_connect_ipv6_ipv6(self):\n        self.skipIfLocalhostV4()\n        self.do_test_connect(socket.AF_INET6, '::1')\n\n    @skipIfNoIPv6\n    def test_connect_ipv6_dual(self):\n        self.skipIfLocalhostV4()\n        if Resolver.configured_class().__name__.endswith('TwistedResolver'):\n            self.skipTest('TwistedResolver does not support multiple addresses')\n        self.do_test_connect(socket.AF_INET6, 'localhost')\n\n    def test_connect_unspec_ipv4(self):\n        self.do_test_connect(socket.AF_UNSPEC, '127.0.0.1')\n\n    @skipIfNoIPv6\n    def test_connect_unspec_ipv6(self):\n        self.skipIfLocalhostV4()\n        self.do_test_connect(socket.AF_UNSPEC, '::1')\n\n    def test_connect_unspec_dual(self):\n        self.do_test_connect(socket.AF_UNSPEC, 'localhost')\n\n    @gen_test\n    def test_refused_ipv4(self):\n        cleanup_func, port = refusing_port()\n        self.addCleanup(cleanup_func)\n        with self.assertRaises(IOError):\n            yield self.client.connect('127.0.0.1', port)\n\n    def test_source_ip_fail(self):\n        '''\n        Fail when trying to use the source IP Address '8.8.8.8'.\n        '''\n        self.assertRaises(socket.error,\n                          self.do_test_connect,\n                          socket.AF_INET,\n                          '127.0.0.1',\n                          source_ip='8.8.8.8')\n\n    def test_source_ip_success(self):\n        '''\n        Success when trying to use the source IP Address '127.0.0.1'\n        '''\n        self.do_test_connect(socket.AF_INET, '127.0.0.1', source_ip='127.0.0.1')\n\n    @skipIfNonUnix\n    def test_source_port_fail(self):\n        '''\n        Fail when trying to use source port 1.\n        '''\n        self.assertRaises(socket.error,\n                          self.do_test_connect,\n                          socket.AF_INET,\n                          '127.0.0.1',\n                          source_port=1)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 52,
                                "end_lineno": 155,
                                "parent": null
                            }
                        },
                        {
                            "file_name": "tornado/test/tcpclient_test.py",
                            "type": "method",
                            "name": "TCPClientTest.test_source_ip_fail",
                            "content": "class TCPClientTest(AsyncTestCase):\n    def setUp(self):\n        super(TCPClientTest, self).setUp()\n        self.server = None\n        self.client = TCPClient()\n\n    def start_server(self, family):\n        if family == socket.AF_UNSPEC and 'TRAVIS' in os.environ:\n            self.skipTest(\"dual-stack servers often have port conflicts on travis\")\n        self.server = TestTCPServer(family)\n        return self.server.port\n\n    def stop_server(self):\n        if self.server is not None:\n            self.server.stop()\n            self.server = None\n\n    def tearDown(self):\n        self.client.close()\n        self.stop_server()\n        super(TCPClientTest, self).tearDown()\n\n    def skipIfLocalhostV4(self):\n        # The port used here doesn't matter, but some systems require it\n        # to be non-zero if we do not also pass AI_PASSIVE.\n        Resolver().resolve('localhost', 80, callback=self.stop)\n        addrinfo = self.wait()\n        families = set(addr[0] for addr in addrinfo)\n        if socket.AF_INET6 not in families:\n            self.skipTest(\"localhost does not resolve to ipv6\")\n\n    @gen_test\n    def do_test_connect(self, family, host, source_ip=None, source_port=None):\n        port = self.start_server(family)\n        stream = yield self.client.connect(host, port,\n                                           source_ip=source_ip,\n                                           source_port=source_port)\n        with closing(stream):\n            stream.write(b\"hello\")\n            data = yield self.server.streams[0].read_bytes(5)\n            self.assertEqual(data, b\"hello\")\n\n    def test_connect_ipv4_ipv4(self):\n        self.do_test_connect(socket.AF_INET, '127.0.0.1')\n\n    def test_connect_ipv4_dual(self):\n        self.do_test_connect(socket.AF_INET, 'localhost')\n\n    @skipIfNoIPv6\n    def test_connect_ipv6_ipv6(self):\n        self.skipIfLocalhostV4()\n        self.do_test_connect(socket.AF_INET6, '::1')\n\n    @skipIfNoIPv6\n    def test_connect_ipv6_dual(self):\n        self.skipIfLocalhostV4()\n        if Resolver.configured_class().__name__.endswith('TwistedResolver'):\n            self.skipTest('TwistedResolver does not support multiple addresses')\n        self.do_test_connect(socket.AF_INET6, 'localhost')\n\n    def test_connect_unspec_ipv4(self):\n        self.do_test_connect(socket.AF_UNSPEC, '127.0.0.1')\n\n    @skipIfNoIPv6\n    def test_connect_unspec_ipv6(self):\n        self.skipIfLocalhostV4()\n        self.do_test_connect(socket.AF_UNSPEC, '::1')\n\n    def test_connect_unspec_dual(self):\n        self.do_test_connect(socket.AF_UNSPEC, 'localhost')\n\n    @gen_test\n    def test_refused_ipv4(self):\n        cleanup_func, port = refusing_port()\n        self.addCleanup(cleanup_func)\n        with self.assertRaises(IOError):\n            yield self.client.connect('127.0.0.1', port)\n\n    def test_source_ip_fail(self):\n        '''\n        Fail when trying to use the source IP Address '8.8.8.8'.\n        '''\n        self.assertRaises(socket.error,\n                          self.do_test_connect,\n                          socket.AF_INET,\n                          '127.0.0.1',\n                          source_ip='8.8.8.8')\n\n    def test_source_ip_success(self):\n        '''\n        Success when trying to use the source IP Address '127.0.0.1'\n        '''\n        self.do_test_connect(socket.AF_INET, '127.0.0.1', source_ip='127.0.0.1')\n\n    @skipIfNonUnix\n    def test_source_port_fail(self):\n        '''\n        Fail when trying to use source port 1.\n        '''\n        self.assertRaises(socket.error,\n                          self.do_test_connect,\n                          socket.AF_INET,\n                          '127.0.0.1',\n                          source_port=1)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 130,
                            "end_lineno": 138,
                            "parent": {
                                "file_name": "tornado/test/tcpclient_test.py",
                                "type": "class",
                                "name": "TCPClientTest",
                                "content": "class TCPClientTest(AsyncTestCase):\n    def setUp(self):\n        super(TCPClientTest, self).setUp()\n        self.server = None\n        self.client = TCPClient()\n\n    def start_server(self, family):\n        if family == socket.AF_UNSPEC and 'TRAVIS' in os.environ:\n            self.skipTest(\"dual-stack servers often have port conflicts on travis\")\n        self.server = TestTCPServer(family)\n        return self.server.port\n\n    def stop_server(self):\n        if self.server is not None:\n            self.server.stop()\n            self.server = None\n\n    def tearDown(self):\n        self.client.close()\n        self.stop_server()\n        super(TCPClientTest, self).tearDown()\n\n    def skipIfLocalhostV4(self):\n        # The port used here doesn't matter, but some systems require it\n        # to be non-zero if we do not also pass AI_PASSIVE.\n        Resolver().resolve('localhost', 80, callback=self.stop)\n        addrinfo = self.wait()\n        families = set(addr[0] for addr in addrinfo)\n        if socket.AF_INET6 not in families:\n            self.skipTest(\"localhost does not resolve to ipv6\")\n\n    @gen_test\n    def do_test_connect(self, family, host, source_ip=None, source_port=None):\n        port = self.start_server(family)\n        stream = yield self.client.connect(host, port,\n                                           source_ip=source_ip,\n                                           source_port=source_port)\n        with closing(stream):\n            stream.write(b\"hello\")\n            data = yield self.server.streams[0].read_bytes(5)\n            self.assertEqual(data, b\"hello\")\n\n    def test_connect_ipv4_ipv4(self):\n        self.do_test_connect(socket.AF_INET, '127.0.0.1')\n\n    def test_connect_ipv4_dual(self):\n        self.do_test_connect(socket.AF_INET, 'localhost')\n\n    @skipIfNoIPv6\n    def test_connect_ipv6_ipv6(self):\n        self.skipIfLocalhostV4()\n        self.do_test_connect(socket.AF_INET6, '::1')\n\n    @skipIfNoIPv6\n    def test_connect_ipv6_dual(self):\n        self.skipIfLocalhostV4()\n        if Resolver.configured_class().__name__.endswith('TwistedResolver'):\n            self.skipTest('TwistedResolver does not support multiple addresses')\n        self.do_test_connect(socket.AF_INET6, 'localhost')\n\n    def test_connect_unspec_ipv4(self):\n        self.do_test_connect(socket.AF_UNSPEC, '127.0.0.1')\n\n    @skipIfNoIPv6\n    def test_connect_unspec_ipv6(self):\n        self.skipIfLocalhostV4()\n        self.do_test_connect(socket.AF_UNSPEC, '::1')\n\n    def test_connect_unspec_dual(self):\n        self.do_test_connect(socket.AF_UNSPEC, 'localhost')\n\n    @gen_test\n    def test_refused_ipv4(self):\n        cleanup_func, port = refusing_port()\n        self.addCleanup(cleanup_func)\n        with self.assertRaises(IOError):\n            yield self.client.connect('127.0.0.1', port)\n\n    def test_source_ip_fail(self):\n        '''\n        Fail when trying to use the source IP Address '8.8.8.8'.\n        '''\n        self.assertRaises(socket.error,\n                          self.do_test_connect,\n                          socket.AF_INET,\n                          '127.0.0.1',\n                          source_ip='8.8.8.8')\n\n    def test_source_ip_success(self):\n        '''\n        Success when trying to use the source IP Address '127.0.0.1'\n        '''\n        self.do_test_connect(socket.AF_INET, '127.0.0.1', source_ip='127.0.0.1')\n\n    @skipIfNonUnix\n    def test_source_port_fail(self):\n        '''\n        Fail when trying to use source port 1.\n        '''\n        self.assertRaises(socket.error,\n                          self.do_test_connect,\n                          socket.AF_INET,\n                          '127.0.0.1',\n                          source_port=1)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 52,
                                "end_lineno": 155,
                                "parent": null
                            }
                        },
                        {
                            "file_name": "tornado/test/tcpclient_test.py",
                            "type": "method",
                            "name": "TCPClientTest.test_source_ip_success",
                            "content": "class TCPClientTest(AsyncTestCase):\n    def setUp(self):\n        super(TCPClientTest, self).setUp()\n        self.server = None\n        self.client = TCPClient()\n\n    def start_server(self, family):\n        if family == socket.AF_UNSPEC and 'TRAVIS' in os.environ:\n            self.skipTest(\"dual-stack servers often have port conflicts on travis\")\n        self.server = TestTCPServer(family)\n        return self.server.port\n\n    def stop_server(self):\n        if self.server is not None:\n            self.server.stop()\n            self.server = None\n\n    def tearDown(self):\n        self.client.close()\n        self.stop_server()\n        super(TCPClientTest, self).tearDown()\n\n    def skipIfLocalhostV4(self):\n        # The port used here doesn't matter, but some systems require it\n        # to be non-zero if we do not also pass AI_PASSIVE.\n        Resolver().resolve('localhost', 80, callback=self.stop)\n        addrinfo = self.wait()\n        families = set(addr[0] for addr in addrinfo)\n        if socket.AF_INET6 not in families:\n            self.skipTest(\"localhost does not resolve to ipv6\")\n\n    @gen_test\n    def do_test_connect(self, family, host, source_ip=None, source_port=None):\n        port = self.start_server(family)\n        stream = yield self.client.connect(host, port,\n                                           source_ip=source_ip,\n                                           source_port=source_port)\n        with closing(stream):\n            stream.write(b\"hello\")\n            data = yield self.server.streams[0].read_bytes(5)\n            self.assertEqual(data, b\"hello\")\n\n    def test_connect_ipv4_ipv4(self):\n        self.do_test_connect(socket.AF_INET, '127.0.0.1')\n\n    def test_connect_ipv4_dual(self):\n        self.do_test_connect(socket.AF_INET, 'localhost')\n\n    @skipIfNoIPv6\n    def test_connect_ipv6_ipv6(self):\n        self.skipIfLocalhostV4()\n        self.do_test_connect(socket.AF_INET6, '::1')\n\n    @skipIfNoIPv6\n    def test_connect_ipv6_dual(self):\n        self.skipIfLocalhostV4()\n        if Resolver.configured_class().__name__.endswith('TwistedResolver'):\n            self.skipTest('TwistedResolver does not support multiple addresses')\n        self.do_test_connect(socket.AF_INET6, 'localhost')\n\n    def test_connect_unspec_ipv4(self):\n        self.do_test_connect(socket.AF_UNSPEC, '127.0.0.1')\n\n    @skipIfNoIPv6\n    def test_connect_unspec_ipv6(self):\n        self.skipIfLocalhostV4()\n        self.do_test_connect(socket.AF_UNSPEC, '::1')\n\n    def test_connect_unspec_dual(self):\n        self.do_test_connect(socket.AF_UNSPEC, 'localhost')\n\n    @gen_test\n    def test_refused_ipv4(self):\n        cleanup_func, port = refusing_port()\n        self.addCleanup(cleanup_func)\n        with self.assertRaises(IOError):\n            yield self.client.connect('127.0.0.1', port)\n\n    def test_source_ip_fail(self):\n        '''\n        Fail when trying to use the source IP Address '8.8.8.8'.\n        '''\n        self.assertRaises(socket.error,\n                          self.do_test_connect,\n                          socket.AF_INET,\n                          '127.0.0.1',\n                          source_ip='8.8.8.8')\n\n    def test_source_ip_success(self):\n        '''\n        Success when trying to use the source IP Address '127.0.0.1'\n        '''\n        self.do_test_connect(socket.AF_INET, '127.0.0.1', source_ip='127.0.0.1')\n\n    @skipIfNonUnix\n    def test_source_port_fail(self):\n        '''\n        Fail when trying to use source port 1.\n        '''\n        self.assertRaises(socket.error,\n                          self.do_test_connect,\n                          socket.AF_INET,\n                          '127.0.0.1',\n                          source_port=1)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 140,
                            "end_lineno": 144,
                            "parent": {
                                "file_name": "tornado/test/tcpclient_test.py",
                                "type": "class",
                                "name": "TCPClientTest",
                                "content": "class TCPClientTest(AsyncTestCase):\n    def setUp(self):\n        super(TCPClientTest, self).setUp()\n        self.server = None\n        self.client = TCPClient()\n\n    def start_server(self, family):\n        if family == socket.AF_UNSPEC and 'TRAVIS' in os.environ:\n            self.skipTest(\"dual-stack servers often have port conflicts on travis\")\n        self.server = TestTCPServer(family)\n        return self.server.port\n\n    def stop_server(self):\n        if self.server is not None:\n            self.server.stop()\n            self.server = None\n\n    def tearDown(self):\n        self.client.close()\n        self.stop_server()\n        super(TCPClientTest, self).tearDown()\n\n    def skipIfLocalhostV4(self):\n        # The port used here doesn't matter, but some systems require it\n        # to be non-zero if we do not also pass AI_PASSIVE.\n        Resolver().resolve('localhost', 80, callback=self.stop)\n        addrinfo = self.wait()\n        families = set(addr[0] for addr in addrinfo)\n        if socket.AF_INET6 not in families:\n            self.skipTest(\"localhost does not resolve to ipv6\")\n\n    @gen_test\n    def do_test_connect(self, family, host, source_ip=None, source_port=None):\n        port = self.start_server(family)\n        stream = yield self.client.connect(host, port,\n                                           source_ip=source_ip,\n                                           source_port=source_port)\n        with closing(stream):\n            stream.write(b\"hello\")\n            data = yield self.server.streams[0].read_bytes(5)\n            self.assertEqual(data, b\"hello\")\n\n    def test_connect_ipv4_ipv4(self):\n        self.do_test_connect(socket.AF_INET, '127.0.0.1')\n\n    def test_connect_ipv4_dual(self):\n        self.do_test_connect(socket.AF_INET, 'localhost')\n\n    @skipIfNoIPv6\n    def test_connect_ipv6_ipv6(self):\n        self.skipIfLocalhostV4()\n        self.do_test_connect(socket.AF_INET6, '::1')\n\n    @skipIfNoIPv6\n    def test_connect_ipv6_dual(self):\n        self.skipIfLocalhostV4()\n        if Resolver.configured_class().__name__.endswith('TwistedResolver'):\n            self.skipTest('TwistedResolver does not support multiple addresses')\n        self.do_test_connect(socket.AF_INET6, 'localhost')\n\n    def test_connect_unspec_ipv4(self):\n        self.do_test_connect(socket.AF_UNSPEC, '127.0.0.1')\n\n    @skipIfNoIPv6\n    def test_connect_unspec_ipv6(self):\n        self.skipIfLocalhostV4()\n        self.do_test_connect(socket.AF_UNSPEC, '::1')\n\n    def test_connect_unspec_dual(self):\n        self.do_test_connect(socket.AF_UNSPEC, 'localhost')\n\n    @gen_test\n    def test_refused_ipv4(self):\n        cleanup_func, port = refusing_port()\n        self.addCleanup(cleanup_func)\n        with self.assertRaises(IOError):\n            yield self.client.connect('127.0.0.1', port)\n\n    def test_source_ip_fail(self):\n        '''\n        Fail when trying to use the source IP Address '8.8.8.8'.\n        '''\n        self.assertRaises(socket.error,\n                          self.do_test_connect,\n                          socket.AF_INET,\n                          '127.0.0.1',\n                          source_ip='8.8.8.8')\n\n    def test_source_ip_success(self):\n        '''\n        Success when trying to use the source IP Address '127.0.0.1'\n        '''\n        self.do_test_connect(socket.AF_INET, '127.0.0.1', source_ip='127.0.0.1')\n\n    @skipIfNonUnix\n    def test_source_port_fail(self):\n        '''\n        Fail when trying to use source port 1.\n        '''\n        self.assertRaises(socket.error,\n                          self.do_test_connect,\n                          socket.AF_INET,\n                          '127.0.0.1',\n                          source_port=1)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 52,
                                "end_lineno": 155,
                                "parent": null
                            }
                        }
                    ],
                    "deleted_entities": []
                }
            ]
        }
    ],
    "old_commit_hash": "e704489dd1a897ca66c8a7becb963556929cfef6^",
    "new_commit_hash": "e704489dd1a897ca66c8a7becb963556929cfef6",
    "commit_message": "Merge pull request #1935 from mirceaulinic/SOURCE-IP\n\nTCPClient: connect using specific source IP address and port",
    "commit_date": "2017-02-09T19:06:34-05:00",
    "metadata": {}
}
{
    "repo_name": "tornado",
    "new_commit_hash": "e704489dd1a897ca66c8a7becb963556929cfef6",
    "test_file_codes": [
        "#!/usr/bin/env python\n#\n# Copyright 2014 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\nfrom __future__ import absolute_import, division, print_function, with_statement\n\nfrom contextlib import closing\nimport os\nimport socket\n\nfrom tornado.concurrent import Future\nfrom tornado.netutil import bind_sockets, Resolver\nfrom tornado.tcpclient import TCPClient, _Connector\nfrom tornado.tcpserver import TCPServer\nfrom tornado.testing import AsyncTestCase, gen_test\nfrom tornado.test.util import skipIfNoIPv6, unittest, refusing_port, skipIfNonUnix\n\n# Fake address families for testing.  Used in place of AF_INET\n# and AF_INET6 because some installations do not have AF_INET6.\nAF1, AF2 = 1, 2\n\n\nclass TestTCPServer(TCPServer):\n    def __init__(self, family):\n        super(TestTCPServer, self).__init__()\n        self.streams = []\n        sockets = bind_sockets(None, 'localhost', family)\n        self.add_sockets(sockets)\n        self.port = sockets[0].getsockname()[1]\n\n    def handle_stream(self, stream, address):\n        self.streams.append(stream)\n\n    def stop(self):\n        super(TestTCPServer, self).stop()\n        for stream in self.streams:\n            stream.close()\n\n\nclass TCPClientTest(AsyncTestCase):\n    def setUp(self):\n        super(TCPClientTest, self).setUp()\n        self.server = None\n        self.client = TCPClient()\n\n    def start_server(self, family):\n        if family == socket.AF_UNSPEC and 'TRAVIS' in os.environ:\n            self.skipTest(\"dual-stack servers often have port conflicts on travis\")\n        self.server = TestTCPServer(family)\n        return self.server.port\n\n    def stop_server(self):\n        if self.server is not None:\n            self.server.stop()\n            self.server = None\n\n    def tearDown(self):\n        self.client.close()\n        self.stop_server()\n        super(TCPClientTest, self).tearDown()\n\n    def skipIfLocalhostV4(self):\n        # The port used here doesn't matter, but some systems require it\n        # to be non-zero if we do not also pass AI_PASSIVE.\n        Resolver().resolve('localhost', 80, callback=self.stop)\n        addrinfo = self.wait()\n        families = set(addr[0] for addr in addrinfo)\n        if socket.AF_INET6 not in families:\n            self.skipTest(\"localhost does not resolve to ipv6\")\n\n    @gen_test\n    def do_test_connect(self, family, host, source_ip=None, source_port=None):\n        port = self.start_server(family)\n        stream = yield self.client.connect(host, port,\n                                           source_ip=source_ip,\n                                           source_port=source_port)\n        with closing(stream):\n            stream.write(b\"hello\")\n            data = yield self.server.streams[0].read_bytes(5)\n            self.assertEqual(data, b\"hello\")\n\n    def test_connect_ipv4_ipv4(self):\n        self.do_test_connect(socket.AF_INET, '127.0.0.1')\n\n    def test_connect_ipv4_dual(self):\n        self.do_test_connect(socket.AF_INET, 'localhost')\n\n    @skipIfNoIPv6\n    def test_connect_ipv6_ipv6(self):\n        self.skipIfLocalhostV4()\n        self.do_test_connect(socket.AF_INET6, '::1')\n\n    @skipIfNoIPv6\n    def test_connect_ipv6_dual(self):\n        self.skipIfLocalhostV4()\n        if Resolver.configured_class().__name__.endswith('TwistedResolver'):\n            self.skipTest('TwistedResolver does not support multiple addresses')\n        self.do_test_connect(socket.AF_INET6, 'localhost')\n\n    def test_connect_unspec_ipv4(self):\n        self.do_test_connect(socket.AF_UNSPEC, '127.0.0.1')\n\n    @skipIfNoIPv6\n    def test_connect_unspec_ipv6(self):\n        self.skipIfLocalhostV4()\n        self.do_test_connect(socket.AF_UNSPEC, '::1')\n\n    def test_connect_unspec_dual(self):\n        self.do_test_connect(socket.AF_UNSPEC, 'localhost')\n\n    @gen_test\n    def test_refused_ipv4(self):\n        cleanup_func, port = refusing_port()\n        self.addCleanup(cleanup_func)\n        with self.assertRaises(IOError):\n            yield self.client.connect('127.0.0.1', port)\n\n    def test_source_ip_fail(self):\n        '''\n        Fail when trying to use the source IP Address '8.8.8.8'.\n        '''\n        self.assertRaises(socket.error,\n                          self.do_test_connect,\n                          socket.AF_INET,\n                          '127.0.0.1',\n                          source_ip='8.8.8.8')\n\n    def test_source_ip_success(self):\n        '''\n        Success when trying to use the source IP Address '127.0.0.1'\n        '''\n        self.do_test_connect(socket.AF_INET, '127.0.0.1', source_ip='127.0.0.1')\n\n    @skipIfNonUnix\n    def test_source_port_fail(self):\n        '''\n        Fail when trying to use source port 1.\n        '''\n        self.assertRaises(socket.error,\n                          self.do_test_connect,\n                          socket.AF_INET,\n                          '127.0.0.1',\n                          source_port=1)\n\n\nclass TestConnectorSplit(unittest.TestCase):\n    def test_one_family(self):\n        # These addresses aren't in the right format, but split doesn't care.\n        primary, secondary = _Connector.split(\n            [(AF1, 'a'),\n             (AF1, 'b')])\n        self.assertEqual(primary, [(AF1, 'a'),\n                                   (AF1, 'b')])\n        self.assertEqual(secondary, [])\n\n    def test_mixed(self):\n        primary, secondary = _Connector.split(\n            [(AF1, 'a'),\n             (AF2, 'b'),\n             (AF1, 'c'),\n             (AF2, 'd')])\n        self.assertEqual(primary, [(AF1, 'a'), (AF1, 'c')])\n        self.assertEqual(secondary, [(AF2, 'b'), (AF2, 'd')])\n\n\nclass ConnectorTest(AsyncTestCase):\n    class FakeStream(object):\n        def __init__(self):\n            self.closed = False\n\n        def close(self):\n            self.closed = True\n\n    def setUp(self):\n        super(ConnectorTest, self).setUp()\n        self.connect_futures = {}\n        self.streams = {}\n        self.addrinfo = [(AF1, 'a'), (AF1, 'b'),\n                         (AF2, 'c'), (AF2, 'd')]\n\n    def tearDown(self):\n        # Unless explicitly checked (and popped) in the test, we shouldn't\n        # be closing any streams\n        for stream in self.streams.values():\n            self.assertFalse(stream.closed)\n        super(ConnectorTest, self).tearDown()\n\n    def create_stream(self, af, addr):\n        future = Future()\n        self.connect_futures[(af, addr)] = future\n        return future\n\n    def assert_pending(self, *keys):\n        self.assertEqual(sorted(self.connect_futures.keys()), sorted(keys))\n\n    def resolve_connect(self, af, addr, success):\n        future = self.connect_futures.pop((af, addr))\n        if success:\n            self.streams[addr] = ConnectorTest.FakeStream()\n            future.set_result(self.streams[addr])\n        else:\n            future.set_exception(IOError())\n\n    def start_connect(self, addrinfo):\n        conn = _Connector(addrinfo, self.io_loop, self.create_stream)\n        # Give it a huge timeout; we'll trigger timeouts manually.\n        future = conn.start(3600)\n        return conn, future\n\n    def test_immediate_success(self):\n        conn, future = self.start_connect(self.addrinfo)\n        self.assertEqual(list(self.connect_futures.keys()),\n                         [(AF1, 'a')])\n        self.resolve_connect(AF1, 'a', True)\n        self.assertEqual(future.result(), (AF1, 'a', self.streams['a']))\n\n    def test_immediate_failure(self):\n        # Fail with just one address.\n        conn, future = self.start_connect([(AF1, 'a')])\n        self.assert_pending((AF1, 'a'))\n        self.resolve_connect(AF1, 'a', False)\n        self.assertRaises(IOError, future.result)\n\n    def test_one_family_second_try(self):\n        conn, future = self.start_connect([(AF1, 'a'), (AF1, 'b')])\n        self.assert_pending((AF1, 'a'))\n        self.resolve_connect(AF1, 'a', False)\n        self.assert_pending((AF1, 'b'))\n        self.resolve_connect(AF1, 'b', True)\n        self.assertEqual(future.result(), (AF1, 'b', self.streams['b']))\n\n    def test_one_family_second_try_failure(self):\n        conn, future = self.start_connect([(AF1, 'a'), (AF1, 'b')])\n        self.assert_pending((AF1, 'a'))\n        self.resolve_connect(AF1, 'a', False)\n        self.assert_pending((AF1, 'b'))\n        self.resolve_connect(AF1, 'b', False)\n        self.assertRaises(IOError, future.result)\n\n    def test_one_family_second_try_timeout(self):\n        conn, future = self.start_connect([(AF1, 'a'), (AF1, 'b')])\n        self.assert_pending((AF1, 'a'))\n        # trigger the timeout while the first lookup is pending;\n        # nothing happens.\n        conn.on_timeout()\n        self.assert_pending((AF1, 'a'))\n        self.resolve_connect(AF1, 'a', False)\n        self.assert_pending((AF1, 'b'))\n        self.resolve_connect(AF1, 'b', True)\n        self.assertEqual(future.result(), (AF1, 'b', self.streams['b']))\n\n    def test_two_families_immediate_failure(self):\n        conn, future = self.start_connect(self.addrinfo)\n        self.assert_pending((AF1, 'a'))\n        self.resolve_connect(AF1, 'a', False)\n        self.assert_pending((AF1, 'b'), (AF2, 'c'))\n        self.resolve_connect(AF1, 'b', False)\n        self.resolve_connect(AF2, 'c', True)\n        self.assertEqual(future.result(), (AF2, 'c', self.streams['c']))\n\n    def test_two_families_timeout(self):\n        conn, future = self.start_connect(self.addrinfo)\n        self.assert_pending((AF1, 'a'))\n        conn.on_timeout()\n        self.assert_pending((AF1, 'a'), (AF2, 'c'))\n        self.resolve_connect(AF2, 'c', True)\n        self.assertEqual(future.result(), (AF2, 'c', self.streams['c']))\n        # resolving 'a' after the connection has completed doesn't start 'b'\n        self.resolve_connect(AF1, 'a', False)\n        self.assert_pending()\n\n    def test_success_after_timeout(self):\n        conn, future = self.start_connect(self.addrinfo)\n        self.assert_pending((AF1, 'a'))\n        conn.on_timeout()\n        self.assert_pending((AF1, 'a'), (AF2, 'c'))\n        self.resolve_connect(AF1, 'a', True)\n        self.assertEqual(future.result(), (AF1, 'a', self.streams['a']))\n        # resolving 'c' after completion closes the connection.\n        self.resolve_connect(AF2, 'c', True)\n        self.assertTrue(self.streams.pop('c').closed)\n\n    def test_all_fail(self):\n        conn, future = self.start_connect(self.addrinfo)\n        self.assert_pending((AF1, 'a'))\n        conn.on_timeout()\n        self.assert_pending((AF1, 'a'), (AF2, 'c'))\n        self.resolve_connect(AF2, 'c', False)\n        self.assert_pending((AF1, 'a'), (AF2, 'd'))\n        self.resolve_connect(AF2, 'd', False)\n        # one queue is now empty\n        self.assert_pending((AF1, 'a'))\n        self.resolve_connect(AF1, 'a', False)\n        self.assert_pending((AF1, 'b'))\n        self.assertFalse(future.done())\n        self.resolve_connect(AF1, 'b', False)\n        self.assertRaises(IOError, future.result)\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 853ms\nPrepared 1 package in 1.04s\nInstalled 1 package in 1ms\n + tornado==4.5.dev1 (from file:///home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6)\nResolved 29 packages in 16ms\nInstalled 29 packages in 166ms\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_e704489dd1a897ca66c8a7becb963556929cfef6\n......................\ncollected 22 items\n\n==================== short test summary info ====================\nPASSED r2e_tests.test_1::ConnectorTest::test_all_fail\nPASSED r2e_tests.test_1::ConnectorTest::test_immediate_failure\nPASSED r2e_tests.test_1::ConnectorTest::test_immediate_success\nPASSED r2e_tests.test_1::ConnectorTest::test_one_family_second_try\nPASSED r2e_tests.test_1::ConnectorTest::test_one_family_second_try_failure\nPASSED r2e_tests.test_1::ConnectorTest::test_one_family_second_try_timeout\nPASSED r2e_tests.test_1::ConnectorTest::test_success_after_timeout\nPASSED r2e_tests.test_1::ConnectorTest::test_two_families_immediate_failure\nPASSED r2e_tests.test_1::ConnectorTest::test_two_families_timeout\nPASSED r2e_tests.test_1::TCPClientTest::test_connect_ipv4_dual\nPASSED r2e_tests.test_1::TCPClientTest::test_connect_ipv4_ipv4\nSKIPPED r2e_tests.test_1::TCPClientTest::test_connect_ipv6_dual\nSKIPPED r2e_tests.test_1::TCPClientTest::test_connect_ipv6_ipv6\nPASSED r2e_tests.test_1::TCPClientTest::test_connect_unspec_dual\nPASSED r2e_tests.test_1::TCPClientTest::test_connect_unspec_ipv4\nSKIPPED r2e_tests.test_1::TCPClientTest::test_connect_unspec_ipv6\nPASSED r2e_tests.test_1::TCPClientTest::test_refused_ipv4\nPASSED r2e_tests.test_1::TCPClientTest::test_source_ip_fail\nPASSED r2e_tests.test_1::TCPClientTest::test_source_ip_success\nPASSED r2e_tests.test_1::TCPClientTest::test_source_port_fail\nPASSED r2e_tests.test_1::TestConnectorSplit::test_mixed\nPASSED r2e_tests.test_1::TestConnectorSplit::test_one_family\n=================== 19 passed, 3 skipped in 0.01s ===================\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_e704489dd1a897ca66c8a7becb963556929cfef6\n......................\ncollected 22 items\n\n=================================== ERRORS =====================================\n__________ TCPClientTest.test_connect_ipv4_dual __________\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_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/testing.py\", line 136, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/r2e_tests/test_1.py\", line 98, in test_connect_ipv4_dual\n    self.do_test_connect(socket.AF_INET, 'localhost')\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/testing.py\", line 527, in post_coroutine\n    return self.io_loop.run_sync(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/ioloop.py\", line 458, in run_sync\n    return future_cell[0].result()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/concurrent.py\", line 237, in result\n    raise_exc_info(self._exc_info)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/gen.py\", line 1051, in run\n    yielded = self.gen.throw(*exc_info)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/types.py\", line 217, in throw\n    return self.__wrapped.throw(tp, *rest)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/r2e_tests/test_1.py\", line 86, in do_test_connect\n    stream = yield self.client.connect(host, port,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/gen.py\", line 1045, in run\n    value = future.result()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/concurrent.py\", line 237, in result\n    raise_exc_info(self._exc_info)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/gen.py\", line 290, in wrapper\n    result = func(*args, **kwargs)\nTypeError: connect() got an unexpected keyword argument 'source_ip'\n__________ TCPClientTest.test_connect_ipv4_ipv4 __________\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_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/testing.py\", line 136, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/r2e_tests/test_1.py\", line 95, in test_connect_ipv4_ipv4\n    self.do_test_connect(socket.AF_INET, '127.0.0.1')\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/testing.py\", line 527, in post_coroutine\n    return self.io_loop.run_sync(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/ioloop.py\", line 458, in run_sync\n    return future_cell[0].result()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/concurrent.py\", line 237, in result\n    raise_exc_info(self._exc_info)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/gen.py\", line 1051, in run\n    yielded = self.gen.throw(*exc_info)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/types.py\", line 217, in throw\n    return self.__wrapped.throw(tp, *rest)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/r2e_tests/test_1.py\", line 86, in do_test_connect\n    stream = yield self.client.connect(host, port,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/gen.py\", line 1045, in run\n    value = future.result()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/concurrent.py\", line 237, in result\n    raise_exc_info(self._exc_info)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/gen.py\", line 290, in wrapper\n    result = func(*args, **kwargs)\nTypeError: connect() got an unexpected keyword argument 'source_ip'\n__________ TCPClientTest.test_connect_unspec_dual __________\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_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/testing.py\", line 136, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/r2e_tests/test_1.py\", line 121, in test_connect_unspec_dual\n    self.do_test_connect(socket.AF_UNSPEC, 'localhost')\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/testing.py\", line 527, in post_coroutine\n    return self.io_loop.run_sync(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/ioloop.py\", line 458, in run_sync\n    return future_cell[0].result()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/concurrent.py\", line 237, in result\n    raise_exc_info(self._exc_info)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/gen.py\", line 1051, in run\n    yielded = self.gen.throw(*exc_info)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/types.py\", line 217, in throw\n    return self.__wrapped.throw(tp, *rest)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/r2e_tests/test_1.py\", line 86, in do_test_connect\n    stream = yield self.client.connect(host, port,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/gen.py\", line 1045, in run\n    value = future.result()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/concurrent.py\", line 237, in result\n    raise_exc_info(self._exc_info)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/gen.py\", line 290, in wrapper\n    result = func(*args, **kwargs)\nTypeError: connect() got an unexpected keyword argument 'source_ip'\n__________ TCPClientTest.test_connect_unspec_ipv4 __________\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_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/testing.py\", line 136, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/r2e_tests/test_1.py\", line 113, in test_connect_unspec_ipv4\n    self.do_test_connect(socket.AF_UNSPEC, '127.0.0.1')\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/testing.py\", line 527, in post_coroutine\n    return self.io_loop.run_sync(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/ioloop.py\", line 458, in run_sync\n    return future_cell[0].result()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/concurrent.py\", line 237, in result\n    raise_exc_info(self._exc_info)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/gen.py\", line 1051, in run\n    yielded = self.gen.throw(*exc_info)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/types.py\", line 217, in throw\n    return self.__wrapped.throw(tp, *rest)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/r2e_tests/test_1.py\", line 86, in do_test_connect\n    stream = yield self.client.connect(host, port,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/gen.py\", line 1045, in run\n    value = future.result()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/concurrent.py\", line 237, in result\n    raise_exc_info(self._exc_info)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/gen.py\", line 290, in wrapper\n    result = func(*args, **kwargs)\nTypeError: connect() got an unexpected keyword argument 'source_ip'\n__________ TCPClientTest.test_source_ip_fail __________\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_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/testing.py\", line 136, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/r2e_tests/test_1.py\", line 134, in test_source_ip_fail\n    self.assertRaises(socket.error,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 739, in assertRaises\n    return context.handle('assertRaises', args, kwargs)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 201, in handle\n    callable_obj(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/testing.py\", line 527, in post_coroutine\n    return self.io_loop.run_sync(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/ioloop.py\", line 458, in run_sync\n    return future_cell[0].result()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/concurrent.py\", line 237, in result\n    raise_exc_info(self._exc_info)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/gen.py\", line 1051, in run\n    yielded = self.gen.throw(*exc_info)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/types.py\", line 217, in throw\n    return self.__wrapped.throw(tp, *rest)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/r2e_tests/test_1.py\", line 86, in do_test_connect\n    stream = yield self.client.connect(host, port,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/gen.py\", line 1045, in run\n    value = future.result()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/concurrent.py\", line 237, in result\n    raise_exc_info(self._exc_info)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/gen.py\", line 290, in wrapper\n    result = func(*args, **kwargs)\nTypeError: connect() got an unexpected keyword argument 'source_ip'\n__________ TCPClientTest.test_source_ip_success __________\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_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/testing.py\", line 136, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/r2e_tests/test_1.py\", line 144, in test_source_ip_success\n    self.do_test_connect(socket.AF_INET, '127.0.0.1', source_ip='127.0.0.1')\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/testing.py\", line 527, in post_coroutine\n    return self.io_loop.run_sync(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/ioloop.py\", line 458, in run_sync\n    return future_cell[0].result()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/concurrent.py\", line 237, in result\n    raise_exc_info(self._exc_info)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/gen.py\", line 1051, in run\n    yielded = self.gen.throw(*exc_info)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/types.py\", line 217, in throw\n    return self.__wrapped.throw(tp, *rest)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/r2e_tests/test_1.py\", line 86, in do_test_connect\n    stream = yield self.client.connect(host, port,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/gen.py\", line 1045, in run\n    value = future.result()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/concurrent.py\", line 237, in result\n    raise_exc_info(self._exc_info)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/gen.py\", line 290, in wrapper\n    result = func(*args, **kwargs)\nTypeError: connect() got an unexpected keyword argument 'source_ip'\n__________ TCPClientTest.test_source_port_fail __________\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_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/testing.py\", line 136, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/r2e_tests/test_1.py\", line 151, in test_source_port_fail\n    self.assertRaises(socket.error,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 739, in assertRaises\n    return context.handle('assertRaises', args, kwargs)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 201, in handle\n    callable_obj(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/testing.py\", line 527, in post_coroutine\n    return self.io_loop.run_sync(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/ioloop.py\", line 458, in run_sync\n    return future_cell[0].result()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/concurrent.py\", line 237, in result\n    raise_exc_info(self._exc_info)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/gen.py\", line 1051, in run\n    yielded = self.gen.throw(*exc_info)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/types.py\", line 217, in throw\n    return self.__wrapped.throw(tp, *rest)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/r2e_tests/test_1.py\", line 86, in do_test_connect\n    stream = yield self.client.connect(host, port,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/gen.py\", line 1045, in run\n    value = future.result()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/concurrent.py\", line 237, in result\n    raise_exc_info(self._exc_info)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e704489dd1a897ca66c8a7becb963556929cfef6/tornado/gen.py\", line 290, in wrapper\n    result = func(*args, **kwargs)\nTypeError: connect() got an unexpected keyword argument 'source_ip'\n\n==================== short test summary info ====================\nPASSED r2e_tests.test_1::ConnectorTest::test_all_fail\nPASSED r2e_tests.test_1::ConnectorTest::test_immediate_failure\nPASSED r2e_tests.test_1::ConnectorTest::test_immediate_success\nPASSED r2e_tests.test_1::ConnectorTest::test_one_family_second_try\nPASSED r2e_tests.test_1::ConnectorTest::test_one_family_second_try_failure\nPASSED r2e_tests.test_1::ConnectorTest::test_one_family_second_try_timeout\nPASSED r2e_tests.test_1::ConnectorTest::test_success_after_timeout\nPASSED r2e_tests.test_1::ConnectorTest::test_two_families_immediate_failure\nPASSED r2e_tests.test_1::ConnectorTest::test_two_families_timeout\nERROR r2e_tests.test_1::TCPClientTest::test_connect_ipv4_dual\nERROR r2e_tests.test_1::TCPClientTest::test_connect_ipv4_ipv4\nSKIPPED r2e_tests.test_1::TCPClientTest::test_connect_ipv6_dual\nSKIPPED r2e_tests.test_1::TCPClientTest::test_connect_ipv6_ipv6\nERROR r2e_tests.test_1::TCPClientTest::test_connect_unspec_dual\nERROR r2e_tests.test_1::TCPClientTest::test_connect_unspec_ipv4\nSKIPPED r2e_tests.test_1::TCPClientTest::test_connect_unspec_ipv6\nPASSED r2e_tests.test_1::TCPClientTest::test_refused_ipv4\nERROR r2e_tests.test_1::TCPClientTest::test_source_ip_fail\nERROR r2e_tests.test_1::TCPClientTest::test_source_ip_success\nERROR r2e_tests.test_1::TCPClientTest::test_source_port_fail\nPASSED r2e_tests.test_1::TestConnectorSplit::test_mixed\nPASSED r2e_tests.test_1::TestConnectorSplit::test_one_family\n=================== 7 errors, 12 passed, 3 skipped in 0.01s ===================\n",
    "old_commit_res_stderr": ""
}
tornado/tcpclient.py tornado/test/tcpclient_test.py
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ISSUE]
**Title:** `TCPClient.connect()` Raises TypeError When Using `source_ip` and `source_port`

**Description:**
When attempting to establish a TCP connection using `TCPClient.connect()` with the `source_ip` and `source_port` keyword arguments, a `TypeError` is raised indicating that these arguments are unexpected.

**Example Code:**
```python
import tornado.tcpclient

client = tornado.tcpclient.TCPClient()
client.connect('127.0.0.1', 8080, source_ip='192.168.1.100', source_port=5000)
```

**Expected Behavior:**
The client should successfully initiate a connection using the specified source IP address and port without raising any errors.

**Actual Behavior:**
A `TypeError` is raised:
```
TypeError: connect() got an unexpected keyword argument 'source_ip'
```
[/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/tcpclient.py
#!/usr/bin/env python
#
# Copyright 2014 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.

"""A non-blocking TCP connection factory.
"""
from __future__ import absolute_import, division, print_function, with_statement

import functools
import socket

from tornado.concurrent import Future
from tornado.ioloop import IOLoop
from tornado.iostream import IOStream
from tornado import gen
from tornado.netutil import Resolver

_INITIAL_CONNECT_TIMEOUT = 0.3


class _Connector(object):
    """A stateless implementation of the "Happy Eyeballs" algorithm.

    "Happy Eyeballs" is documented in RFC6555 as the recommended practice
    for when both IPv4 and IPv6 addresses are available.

    In this implementation, we partition the addresses by family, and
    make the first connection attempt to whichever address was
    returned first by ``getaddrinfo``.  If that connection fails or
    times out, we begin a connection in parallel to the first address
    of the other family.  If there are additional failures we retry
    with other addresses, keeping one connection attempt per family
    in flight at a time.

    http://tools.ietf.org/html/rfc6555

    """
    def __init__(self, addrinfo, io_loop, connect):
        self.io_loop = io_loop
        self.connect = connect

        self.future = Future()
        self.timeout = None
        self.last_error = None
        self.remaining = len(addrinfo)
        self.primary_addrs, self.secondary_addrs = self.split(addrinfo)

    @staticmethod
    def split(addrinfo):
        """Partition the ``addrinfo`` list by address family.

        Returns two lists.  The first list contains the first entry from
        ``addrinfo`` and all others with the same family, and the
        second list contains all other addresses (normally one list will
        be AF_INET and the other AF_INET6, although non-standard resolvers
        may return additional families).
        """
        primary = []
        secondary = []
        primary_af = addrinfo[0][0]
        for af, addr in addrinfo:
            if af == primary_af:
                primary.append((af, addr))
            else:
                secondary.append((af, addr))
        return primary, secondary

    def start(self, timeout=_INITIAL_CONNECT_TIMEOUT):
        self.try_connect(iter(self.primary_addrs))
        self.set_timout(timeout)
        return self.future

    def try_connect(self, addrs):
        try:
            af, addr = next(addrs)
        except StopIteration:
            # We've reached the end of our queue, but the other queue
            # might still be working.  Send a final error on the future
            # only when both queues are finished.
            if self.remaining == 0 and not self.future.done():
                self.future.set_exception(self.last_error or
                                          IOError("connection failed"))
            return
        future = self.connect(af, addr)
        future.add_done_callback(functools.partial(self.on_connect_done,
                                                   addrs, af, addr))

    def on_connect_done(self, addrs, af, addr, future):
        self.remaining -= 1
        try:
            stream = future.result()
        except Exception as e:
            if self.future.done():
                return
            # Error: try again (but remember what happened so we have an
            # error to raise in the end)
            self.last_error = e
            self.try_connect(addrs)
            if self.timeout is not None:
                # If the first attempt failed, don't wait for the
                # timeout to try an address from the secondary queue.
                self.io_loop.remove_timeout(self.timeout)
                self.on_timeout()
            return
        self.clear_timeout()
        if self.future.done():
            # This is a late arrival; just drop it.
            stream.close()
        else:
            self.future.set_result((af, addr, stream))

    def set_timout(self, timeout):
        self.timeout = self.io_loop.add_timeout(self.io_loop.time() + timeout,
                                                self.on_timeout)

    def on_timeout(self):
        self.timeout = None
        self.try_connect(iter(self.secondary_addrs))

    def clear_timeout(self):
        if self.timeout is not None:
            self.io_loop.remove_timeout(self.timeout)


class TCPClient(object):
    """A non-blocking TCP connection factory.

    .. versionchanged:: 4.1
       The ``io_loop`` argument is deprecated.
    """
    def __init__(self, resolver=None, io_loop=None):
        self.io_loop = io_loop or IOLoop.current()
        if resolver is not None:
            self.resolver = resolver
            self._own_resolver = False
        else:
            self.resolver = Resolver(io_loop=io_loop)
            self._own_resolver = True

    def close(self):
        if self._own_resolver:
            self.resolver.close()

    @gen.coroutine
    def connect(self, host, port, af=socket.AF_UNSPEC, ssl_options=None,
                max_buffer_size=None):
        """Connect to the given host and port.

        Asynchronously returns an `.IOStream` (or `.SSLIOStream` if
        ``ssl_options`` is not None).
        """
        addrinfo = yield self.resolver.resolve(host, port, af)
        connector = _Connector(
            addrinfo, self.io_loop,
            functools.partial(self._create_stream, max_buffer_size))
        af, addr, stream = yield connector.start()
        # TODO: For better performance we could cache the (af, addr)
        # information here and re-use it on subsequent connections to
        # the same host. (http://tools.ietf.org/html/rfc6555#section-4.2)
        if ssl_options is not None:
            stream = yield stream.start_tls(False, ssl_options=ssl_options,
                                            server_hostname=host)
        raise gen.Return(stream)

    def _create_stream(self, max_buffer_size, af, addr):
        # Always connect in plaintext; we'll convert to ssl if necessary
        # after one connection has completed.
        try:
            stream = IOStream(socket.socket(af),
                            io_loop=self.io_loop,
                            max_buffer_size=max_buffer_size)
        except socket.error as e:
            fu = Future()
            fu.set_exception(e)
            return fu
        else:
            return stream.connect(addr)

```
--- END FILE ---

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

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

Here is an example:

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

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

**Description:**
When attempting to establish a TCP connection using `TCPClient.connect()` with the `source_ip` and `source_port` keyword arguments, a `TypeError` is raised indicating that these arguments are unexpected.

**Example Code:**
```python
import tornado.tcpclient

client = tornado.tcpclient.TCPClient()
client.connect('127.0.0.1', 8080, source_ip='192.168.1.100', source_port=5000)
```

**Expected Behavior:**
The client should successfully initiate a connection using the specified source IP address and port without raising any errors.

**Actual Behavior:**
A `TypeError` is raised:
```
TypeError: connect() got an unexpected keyword argument 'source_ip'
```
[/ISSUE]
{
    "ConnectorTest.test_all_fail": "PASSED",
    "ConnectorTest.test_immediate_failure": "PASSED",
    "ConnectorTest.test_immediate_success": "PASSED",
    "ConnectorTest.test_one_family_second_try": "PASSED",
    "ConnectorTest.test_one_family_second_try_failure": "PASSED",
    "ConnectorTest.test_one_family_second_try_timeout": "PASSED",
    "ConnectorTest.test_success_after_timeout": "PASSED",
    "ConnectorTest.test_two_families_immediate_failure": "PASSED",
    "ConnectorTest.test_two_families_timeout": "PASSED",
    "TCPClientTest.test_connect_ipv4_dual": "PASSED",
    "TCPClientTest.test_connect_ipv4_ipv4": "PASSED",
    "TCPClientTest.test_connect_ipv6_dual": "PASSED",
    "TCPClientTest.test_connect_ipv6_ipv6": "PASSED",
    "TCPClientTest.test_connect_unspec_dual": "PASSED",
    "TCPClientTest.test_connect_unspec_ipv4": "PASSED",
    "TCPClientTest.test_connect_unspec_ipv6": "PASSED",
    "TCPClientTest.test_refused_ipv4": "PASSED",
    "TCPClientTest.test_source_ip_fail": "PASSED",
    "TCPClientTest.test_source_ip_success": "PASSED",
    "TCPClientTest.test_source_port_fail": "FAILED",
    "TestConnectorSplit.test_mixed": "PASSED",
    "TestConnectorSplit.test_one_family": "PASSED"
}
diff --git a/tornado/tcpclient.py b/tornado/tcpclient.py
index 11146860..1e289174 100644
--- a/tornado/tcpclient.py
+++ b/tornado/tcpclient.py
@@ -155,16 +155,27 @@ class TCPClient(object):
 
     @gen.coroutine
     def connect(self, host, port, af=socket.AF_UNSPEC, ssl_options=None,
-                max_buffer_size=None):
+                max_buffer_size=None, source_ip=None, source_port=None):
         """Connect to the given host and port.
 
         Asynchronously returns an `.IOStream` (or `.SSLIOStream` if
         ``ssl_options`` is not None).
+
+        Using the ``source_ip`` kwarg, one can specify the source
+        IP address to use when establishing the connection.
+        In case the user needs to resolve and
+        use a specific interface, it has to be handled outside
+        of Tornado as this depends very much on the platform.
+
+        Similarly, when the user requires a certain source port, it can
+        be specified using the ``source_port`` arg.
         """
         addrinfo = yield self.resolver.resolve(host, port, af)
         connector = _Connector(
             addrinfo, self.io_loop,
-            functools.partial(self._create_stream, max_buffer_size))
+            functools.partial(self._create_stream, max_buffer_size,
+                              source_ip=source_ip, source_port=source_port)
+        )
         af, addr, stream = yield connector.start()
         # TODO: For better performance we could cache the (af, addr)
         # information here and re-use it on subsequent connections to
@@ -174,13 +185,28 @@ class TCPClient(object):
                                             server_hostname=host)
         raise gen.Return(stream)
 
-    def _create_stream(self, max_buffer_size, af, addr):
+    def _create_stream(self, max_buffer_size, af, addr, source_ip=None,
+                       source_port=None):
         # Always connect in plaintext; we'll convert to ssl if necessary
         # after one connection has completed.
+        source_port_bind = source_port if isinstance(source_port, int) else 0
+        source_ip_bind = source_ip
+        if source_port_bind and not source_ip:
+            # User required a specific port, but did not specify
+            # a certain source IP, will bind to the default loopback.
+            source_ip_bind = '::1' if af == socket.AF_INET6 else '127.0.0.1'
+            # Trying to use the same address family as the requested af socket:
+            # - 127.0.0.1 for IPv4
+            # - ::1 for IPv6
+        socket_obj = socket.socket(af)
+        if source_port_bind or source_ip_bind:
+            # If the user requires binding also to a specific IP/port.
+            socket_obj.bind((source_ip_bind, source_port_bind))
+            # Fail loudly if unable to use the IP/port.
         try:
-            stream = IOStream(socket.socket(af),
-                            io_loop=self.io_loop,
-                            max_buffer_size=max_buffer_size)
+            stream = IOStream(socket_obj,
+                              io_loop=self.io_loop,
+                              max_buffer_size=max_buffer_size)
         except socket.error as e:
             fu = Future()
             fu.set_exception(e)

{"tornado/tcpclient.py": "#!/usr/bin/env python\n#\n# Copyright 2014 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\"\"\"A non-blocking TCP connection factory.\n\"\"\"\nfrom __future__ import absolute_import, division, print_function, with_statement\n\nimport functools\nimport socket\n\nfrom tornado.concurrent import Future\nfrom tornado.ioloop import IOLoop\nfrom tornado.iostream import IOStream\nfrom tornado import gen\nfrom tornado.netutil import Resolver\n\n_INITIAL_CONNECT_TIMEOUT = 0.3\n\n\nclass _Connector(object):\n    \"\"\"A stateless implementation of the \"Happy Eyeballs\" algorithm.\n\n    \"Happy Eyeballs\" is documented in RFC6555 as the recommended practice\n    for when both IPv4 and IPv6 addresses are available.\n\n    In this implementation, we partition the addresses by family, and\n    make the first connection attempt to whichever address was\n    returned first by ``getaddrinfo``.  If that connection fails or\n    times out, we begin a connection in parallel to the first address\n    of the other family.  If there are additional failures we retry\n    with other addresses, keeping one connection attempt per family\n    in flight at a time.\n\n    http://tools.ietf.org/html/rfc6555\n\n    \"\"\"\n    def __init__(self, addrinfo, io_loop, connect):\n        self.io_loop = io_loop\n        self.connect = connect\n\n        self.future = Future()\n        self.timeout = None\n        self.last_error = None\n        self.remaining = len(addrinfo)\n        self.primary_addrs, self.secondary_addrs = self.split(addrinfo)\n\n    @staticmethod\n    def split(addrinfo):\n        \"\"\"Partition the ``addrinfo`` list by address family.\n\n        Returns two lists.  The first list contains the first entry from\n        ``addrinfo`` and all others with the same family, and the\n        second list contains all other addresses (normally one list will\n        be AF_INET and the other AF_INET6, although non-standard resolvers\n        may return additional families).\n        \"\"\"\n        primary = []\n        secondary = []\n        primary_af = addrinfo[0][0]\n        for af, addr in addrinfo:\n            if af == primary_af:\n                primary.append((af, addr))\n            else:\n                secondary.append((af, addr))\n        return primary, secondary\n\n    def start(self, timeout=_INITIAL_CONNECT_TIMEOUT):\n        self.try_connect(iter(self.primary_addrs))\n        self.set_timout(timeout)\n        return self.future\n\n    def try_connect(self, addrs):\n        try:\n            af, addr = next(addrs)\n        except StopIteration:\n            # We've reached the end of our queue, but the other queue\n            # might still be working.  Send a final error on the future\n            # only when both queues are finished.\n            if self.remaining == 0 and not self.future.done():\n                self.future.set_exception(self.last_error or\n                                          IOError(\"connection failed\"))\n            return\n        future = self.connect(af, addr)\n        future.add_done_callback(functools.partial(self.on_connect_done,\n                                                   addrs, af, addr))\n\n    def on_connect_done(self, addrs, af, addr, future):\n        self.remaining -= 1\n        try:\n            stream = future.result()\n        except Exception as e:\n            if self.future.done():\n                return\n            # Error: try again (but remember what happened so we have an\n            # error to raise in the end)\n            self.last_error = e\n            self.try_connect(addrs)\n            if self.timeout is not None:\n                # If the first attempt failed, don't wait for the\n                # timeout to try an address from the secondary queue.\n                self.io_loop.remove_timeout(self.timeout)\n                self.on_timeout()\n            return\n        self.clear_timeout()\n        if self.future.done():\n            # This is a late arrival; just drop it.\n            stream.close()\n        else:\n            self.future.set_result((af, addr, stream))\n\n    def set_timout(self, timeout):\n        self.timeout = self.io_loop.add_timeout(self.io_loop.time() + timeout,\n                                                self.on_timeout)\n\n    def on_timeout(self):\n        self.timeout = None\n        self.try_connect(iter(self.secondary_addrs))\n\n    def clear_timeout(self):\n        if self.timeout is not None:\n            self.io_loop.remove_timeout(self.timeout)\n\n\nclass TCPClient(object):\n    \"\"\"A non-blocking TCP connection factory.\n\n    .. versionchanged:: 4.1\n       The ``io_loop`` argument is deprecated.\n    \"\"\"\n    def __init__(self, resolver=None, io_loop=None):\n        self.io_loop = io_loop or IOLoop.current()\n        if resolver is not None:\n            self.resolver = resolver\n            self._own_resolver = False\n        else:\n            self.resolver = Resolver(io_loop=io_loop)\n            self._own_resolver = True\n\n    def close(self):\n        if self._own_resolver:\n            self.resolver.close()\n\n    @gen.coroutine\n    def connect(self, host, port, af=socket.AF_UNSPEC, ssl_options=None,\n                max_buffer_size=None):\n        \"\"\"Connect to the given host and port.\n\n        Asynchronously returns an `.IOStream` (or `.SSLIOStream` if\n        ``ssl_options`` is not None).\n        \"\"\"\n        addrinfo = yield self.resolver.resolve(host, port, af)\n        connector = _Connector(\n            addrinfo, self.io_loop,\n            functools.partial(self._create_stream, max_buffer_size))\n        af, addr, stream = yield connector.start()\n        # TODO: For better performance we could cache the (af, addr)\n        # information here and re-use it on subsequent connections to\n        # the same host. (http://tools.ietf.org/html/rfc6555#section-4.2)\n        if ssl_options is not None:\n            stream = yield stream.start_tls(False, ssl_options=ssl_options,\n                                            server_hostname=host)\n        raise gen.Return(stream)\n\n    def _create_stream(self, max_buffer_size, af, addr):\n        # Always connect in plaintext; we'll convert to ssl if necessary\n        # after one connection has completed.\n        try:\n            stream = IOStream(socket.socket(af),\n                            io_loop=self.io_loop,\n                            max_buffer_size=max_buffer_size)\n        except socket.error as e:\n            fu = Future()\n            fu.set_exception(e)\n            return fu\n        else:\n            return stream.connect(addr)\n"}
A user will ask you to solve a task. You should first draft your thinking process (inner monologue). Then, generate the solution.

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

**Description:**
When attempting to establish a TCP connection using `TCPClient.connect()` with the `source_ip` and `source_port` keyword arguments, a `TypeError` is raised indicating that these arguments are unexpected.

**Example Code:**
```python
import tornado.tcpclient

client = tornado.tcpclient.TCPClient()
client.connect('127.0.0.1', 8080, source_ip='192.168.1.100', source_port=5000)
```

**Expected Behavior:**
The client should successfully initiate a connection using the specified source IP address and port without raising any errors.

**Actual Behavior:**
A `TypeError` is raised:
```
TypeError: connect() got an unexpected keyword argument 'source_ip'
```
[/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/tcpclient.py
#!/usr/bin/env python
#
# Copyright 2014 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.

"""A non-blocking TCP connection factory.
"""
from __future__ import absolute_import, division, print_function, with_statement

import functools
import socket

from tornado.concurrent import Future
from tornado.ioloop import IOLoop
from tornado.iostream import IOStream
from tornado import gen
from tornado.netutil import Resolver

_INITIAL_CONNECT_TIMEOUT = 0.3


class _Connector(object):
    """A stateless implementation of the "Happy Eyeballs" algorithm.

    "Happy Eyeballs" is documented in RFC6555 as the recommended practice
    for when both IPv4 and IPv6 addresses are available.

    In this implementation, we partition the addresses by family, and
    make the first connection attempt to whichever address was
    returned first by ``getaddrinfo``.  If that connection fails or
    times out, we begin a connection in parallel to the first address
    of the other family.  If there are additional failures we retry
    with other addresses, keeping one connection attempt per family
    in flight at a time.

    http://tools.ietf.org/html/rfc6555

    """
    def __init__(self, addrinfo, io_loop, connect):
        self.io_loop = io_loop
        self.connect = connect

        self.future = Future()
        self.timeout = None
        self.last_error = None
        self.remaining = len(addrinfo)
        self.primary_addrs, self.secondary_addrs = self.split(addrinfo)

    @staticmethod
    def split(addrinfo):
        """Partition the ``addrinfo`` list by address family.

        Returns two lists.  The first list contains the first entry from
        ``addrinfo`` and all others with the same family, and the
        second list contains all other addresses (normally one list will
        be AF_INET and the other AF_INET6, although non-standard resolvers
        may return additional families).
        """
        primary = []
        secondary = []
        primary_af = addrinfo[0][0]
        for af, addr in addrinfo:
            if af == primary_af:
                primary.append((af, addr))
            else:
                secondary.append((af, addr))
        return primary, secondary

    def start(self, timeout=_INITIAL_CONNECT_TIMEOUT):
        self.try_connect(iter(self.primary_addrs))
        self.set_timout(timeout)
        return self.future

    def try_connect(self, addrs):
        try:
            af, addr = next(addrs)
        except StopIteration:
            # We've reached the end of our queue, but the other queue
            # might still be working.  Send a final error on the future
            # only when both queues are finished.
            if self.remaining == 0 and not self.future.done():
                self.future.set_exception(self.last_error or
                                          IOError("connection failed"))
            return
        future = self.connect(af, addr)
        future.add_done_callback(functools.partial(self.on_connect_done,
                                                   addrs, af, addr))

    def on_connect_done(self, addrs, af, addr, future):
        self.remaining -= 1
        try:
            stream = future.result()
        except Exception as e:
            if self.future.done():
                return
            # Error: try again (but remember what happened so we have an
            # error to raise in the end)
            self.last_error = e
            self.try_connect(addrs)
            if self.timeout is not None:
                # If the first attempt failed, don't wait for the
                # timeout to try an address from the secondary queue.
                self.io_loop.remove_timeout(self.timeout)
                self.on_timeout()
            return
        self.clear_timeout()
        if self.future.done():
            # This is a late arrival; just drop it.
            stream.close()
        else:
            self.future.set_result((af, addr, stream))

    def set_timout(self, timeout):
        self.timeout = self.io_loop.add_timeout(self.io_loop.time() + timeout,
                                                self.on_timeout)

    def on_timeout(self):
        self.timeout = None
        self.try_connect(iter(self.secondary_addrs))

    def clear_timeout(self):
        if self.timeout is not None:
            self.io_loop.remove_timeout(self.timeout)


class TCPClient(object):
    """A non-blocking TCP connection factory.

    .. versionchanged:: 4.1
       The ``io_loop`` argument is deprecated.
    """
    def __init__(self, resolver=None, io_loop=None):
        self.io_loop = io_loop or IOLoop.current()
        if resolver is not None:
            self.resolver = resolver
            self._own_resolver = False
        else:
            self.resolver = Resolver(io_loop=io_loop)
            self._own_resolver = True

    def close(self):
        if self._own_resolver:
            self.resolver.close()

    @gen.coroutine
    def connect(self, host, port, af=socket.AF_UNSPEC, ssl_options=None,
                max_buffer_size=None):
        """Connect to the given host and port.

        Asynchronously returns an `.IOStream` (or `.SSLIOStream` if
        ``ssl_options`` is not None).
        """
        addrinfo = yield self.resolver.resolve(host, port, af)
        connector = _Connector(
            addrinfo, self.io_loop,
            functools.partial(self._create_stream, max_buffer_size))
        af, addr, stream = yield connector.start()
        # TODO: For better performance we could cache the (af, addr)
        # information here and re-use it on subsequent connections to
        # the same host. (http://tools.ietf.org/html/rfc6555#section-4.2)
        if ssl_options is not None:
            stream = yield stream.start_tls(False, ssl_options=ssl_options,
                                            server_hostname=host)
        raise gen.Return(stream)

    def _create_stream(self, max_buffer_size, af, addr):
        # Always connect in plaintext; we'll convert to ssl if necessary
        # after one connection has completed.
        try:
            stream = IOStream(socket.socket(af),
                            io_loop=self.io_loop,
                            max_buffer_size=max_buffer_size)
        except socket.error as e:
            fu = Future()
            fu.set_exception(e)
            return fu
        else:
            return stream.connect(addr)

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