{
    "file_diffs": [
        {
            "old_file_content": "# Author: Ovidiu Predescu\n# Date: July 2011\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# Note:  This module's docs are not currently extracted automatically,\n# so changes must be made manually to twisted.rst\n# TODO: refactor doc build process to use an appropriate virtualenv\n\"\"\"Bridges between the Twisted reactor and Tornado IOLoop.\n\nThis module lets you run applications and libraries written for\nTwisted in a Tornado application.  It can be used in two modes,\ndepending on which library's underlying event loop you want to use.\n\nThis module has been tested with Twisted versions 11.0.0 and newer.\n\nTwisted on Tornado\n------------------\n\n`TornadoReactor` implements the Twisted reactor interface on top of\nthe Tornado IOLoop.  To use it, simply call `install` at the beginning\nof the application::\n\n    import tornado.platform.twisted\n    tornado.platform.twisted.install()\n    from twisted.internet import reactor\n\nWhen the app is ready to start, call `IOLoop.instance().start()`\ninstead of `reactor.run()`.\n\nIt is also possible to create a non-global reactor by calling\n`tornado.platform.twisted.TornadoReactor(io_loop)`.  However, if\nthe `IOLoop` and reactor are to be short-lived (such as those used in\nunit tests), additional cleanup may be required.  Specifically, it is\nrecommended to call::\n\n    reactor.fireSystemEvent('shutdown')\n    reactor.disconnectAll()\n\nbefore closing the `IOLoop`.\n\nTornado on Twisted\n------------------\n\n`TwistedIOLoop` implements the Tornado IOLoop interface on top of the Twisted\nreactor.  Recommended usage::\n\n    from tornado.platform.twisted import TwistedIOLoop\n    from twisted.internet import reactor\n    TwistedIOLoop().install()\n    # Set up your tornado application as usual using `IOLoop.instance`\n    reactor.run()\n\n`TwistedIOLoop` always uses the global Twisted reactor.\n\"\"\"\n\nfrom __future__ import absolute_import, division, print_function, with_statement\n\nimport datetime\nimport functools\nimport socket\n\nimport twisted.internet.abstract\nfrom twisted.internet.posixbase import PosixReactorBase\nfrom twisted.internet.interfaces import \\\n    IReactorFDSet, IDelayedCall, IReactorTime, IReadDescriptor, IWriteDescriptor\nfrom twisted.python import failure, log\nfrom twisted.internet import error\nimport twisted.names.cache\nimport twisted.names.client\nimport twisted.names.hosts\nimport twisted.names.resolve\n\nfrom zope.interface import implementer\n\nfrom tornado.escape import utf8\nfrom tornado import gen\nimport tornado.ioloop\nfrom tornado.log import app_log\nfrom tornado.netutil import Resolver\nfrom tornado.stack_context import NullContext, wrap\nfrom tornado.ioloop import IOLoop\n\n\n@implementer(IDelayedCall)\nclass TornadoDelayedCall(object):\n    \"\"\"DelayedCall object for Tornado.\"\"\"\n    def __init__(self, reactor, seconds, f, *args, **kw):\n        self._reactor = reactor\n        self._func = functools.partial(f, *args, **kw)\n        self._time = self._reactor.seconds() + seconds\n        self._timeout = self._reactor._io_loop.add_timeout(self._time,\n                                                           self._called)\n        self._active = True\n\n    def _called(self):\n        self._active = False\n        self._reactor._removeDelayedCall(self)\n        try:\n            self._func()\n        except:\n            app_log.error(\"_called caught exception\", exc_info=True)\n\n    def getTime(self):\n        return self._time\n\n    def cancel(self):\n        self._active = False\n        self._reactor._io_loop.remove_timeout(self._timeout)\n        self._reactor._removeDelayedCall(self)\n\n    def delay(self, seconds):\n        self._reactor._io_loop.remove_timeout(self._timeout)\n        self._time += seconds\n        self._timeout = self._reactor._io_loop.add_timeout(self._time,\n                                                           self._called)\n\n    def reset(self, seconds):\n        self._reactor._io_loop.remove_timeout(self._timeout)\n        self._time = self._reactor.seconds() + seconds\n        self._timeout = self._reactor._io_loop.add_timeout(self._time,\n                                                           self._called)\n\n    def active(self):\n        return self._active\n\n\n@implementer(IReactorTime, IReactorFDSet)\nclass TornadoReactor(PosixReactorBase):\n    \"\"\"Twisted reactor built on the Tornado IOLoop.\n\n    Since it is intented to be used in applications where the top-level\n    event loop is ``io_loop.start()`` rather than ``reactor.run()``,\n    it is implemented a little differently than other Twisted reactors.\n    We override `mainLoop` instead of `doIteration` and must implement\n    timed call functionality on top of `IOLoop.add_timeout` rather than\n    using the implementation in `PosixReactorBase`.\n    \"\"\"\n    def __init__(self, io_loop=None):\n        if not io_loop:\n            io_loop = tornado.ioloop.IOLoop.current()\n        self._io_loop = io_loop\n        self._readers = {}  # map of reader objects to fd\n        self._writers = {}  # map of writer objects to fd\n        self._fds = {}  # a map of fd to a (reader, writer) tuple\n        self._delayedCalls = {}\n        PosixReactorBase.__init__(self)\n        self.addSystemEventTrigger('during', 'shutdown', self.crash)\n\n        # IOLoop.start() bypasses some of the reactor initialization.\n        # Fire off the necessary events if they weren't already triggered\n        # by reactor.run().\n        def start_if_necessary():\n            if not self._started:\n                self.fireSystemEvent('startup')\n        self._io_loop.add_callback(start_if_necessary)\n\n    # IReactorTime\n    def seconds(self):\n        return self._io_loop.time()\n\n    def callLater(self, seconds, f, *args, **kw):\n        dc = TornadoDelayedCall(self, seconds, f, *args, **kw)\n        self._delayedCalls[dc] = True\n        return dc\n\n    def getDelayedCalls(self):\n        return [x for x in self._delayedCalls if x._active]\n\n    def _removeDelayedCall(self, dc):\n        if dc in self._delayedCalls:\n            del self._delayedCalls[dc]\n\n    # IReactorThreads\n    def callFromThread(self, f, *args, **kw):\n        \"\"\"See `twisted.internet.interfaces.IReactorThreads.callFromThread`\"\"\"\n        assert callable(f), \"%s is not callable\" % f\n        with NullContext():\n            # This NullContext is mainly for an edge case when running\n            # TwistedIOLoop on top of a TornadoReactor.\n            # TwistedIOLoop.add_callback uses reactor.callFromThread and\n            # should not pick up additional StackContexts along the way.\n            self._io_loop.add_callback(f, *args, **kw)\n\n    # We don't need the waker code from the super class, Tornado uses\n    # its own waker.\n    def installWaker(self):\n        pass\n\n    def wakeUp(self):\n        pass\n\n    # IReactorFDSet\n    def _invoke_callback(self, fd, events):\n        if fd not in self._fds:\n            return\n        (reader, writer) = self._fds[fd]\n        if reader:\n            err = None\n            if reader.fileno() == -1:\n                err = error.ConnectionLost()\n            elif events & IOLoop.READ:\n                err = log.callWithLogger(reader, reader.doRead)\n            if err is None and events & IOLoop.ERROR:\n                err = error.ConnectionLost()\n            if err is not None:\n                self.removeReader(reader)\n                reader.readConnectionLost(failure.Failure(err))\n        if writer:\n            err = None\n            if writer.fileno() == -1:\n                err = error.ConnectionLost()\n            elif events & IOLoop.WRITE:\n                err = log.callWithLogger(writer, writer.doWrite)\n            if err is None and events & IOLoop.ERROR:\n                err = error.ConnectionLost()\n            if err is not None:\n                self.removeWriter(writer)\n                writer.writeConnectionLost(failure.Failure(err))\n\n    def addReader(self, reader):\n        \"\"\"Add a FileDescriptor for notification of data available to read.\"\"\"\n        if reader in self._readers:\n            # Don't add the reader if it's already there\n            return\n        fd = reader.fileno()\n        self._readers[reader] = fd\n        if fd in self._fds:\n            (_, writer) = self._fds[fd]\n            self._fds[fd] = (reader, writer)\n            if writer:\n                # We already registered this fd for write events,\n                # update it for read events as well.\n                self._io_loop.update_handler(fd, IOLoop.READ | IOLoop.WRITE)\n        else:\n            with NullContext():\n                self._fds[fd] = (reader, None)\n                self._io_loop.add_handler(fd, self._invoke_callback,\n                                          IOLoop.READ)\n\n    def addWriter(self, writer):\n        \"\"\"Add a FileDescriptor for notification of data available to write.\"\"\"\n        if writer in self._writers:\n            return\n        fd = writer.fileno()\n        self._writers[writer] = fd\n        if fd in self._fds:\n            (reader, _) = self._fds[fd]\n            self._fds[fd] = (reader, writer)\n            if reader:\n                # We already registered this fd for read events,\n                # update it for write events as well.\n                self._io_loop.update_handler(fd, IOLoop.READ | IOLoop.WRITE)\n        else:\n            with NullContext():\n                self._fds[fd] = (None, writer)\n                self._io_loop.add_handler(fd, self._invoke_callback,\n                                          IOLoop.WRITE)\n\n    def removeReader(self, reader):\n        \"\"\"Remove a Selectable for notification of data available to read.\"\"\"\n        if reader in self._readers:\n            fd = self._readers.pop(reader)\n            (_, writer) = self._fds[fd]\n            if writer:\n                # We have a writer so we need to update the IOLoop for\n                # write events only.\n                self._fds[fd] = (None, writer)\n                self._io_loop.update_handler(fd, IOLoop.WRITE)\n            else:\n                # Since we have no writer registered, we remove the\n                # entry from _fds and unregister the handler from the\n                # IOLoop\n                del self._fds[fd]\n                self._io_loop.remove_handler(fd)\n\n    def removeWriter(self, writer):\n        \"\"\"Remove a Selectable for notification of data available to write.\"\"\"\n        if writer in self._writers:\n            fd = self._writers.pop(writer)\n            (reader, _) = self._fds[fd]\n            if reader:\n                # We have a reader so we need to update the IOLoop for\n                # read events only.\n                self._fds[fd] = (reader, None)\n                self._io_loop.update_handler(fd, IOLoop.READ)\n            else:\n                # Since we have no reader registered, we remove the\n                # entry from the _fds and unregister the handler from\n                # the IOLoop.\n                del self._fds[fd]\n                self._io_loop.remove_handler(fd)\n\n    def removeAll(self):\n        return self._removeAll(self._readers, self._writers)\n\n    def getReaders(self):\n        return self._readers.keys()\n\n    def getWriters(self):\n        return self._writers.keys()\n\n    # The following functions are mainly used in twisted-style test cases;\n    # it is expected that most users of the TornadoReactor will call\n    # IOLoop.start() instead of Reactor.run().\n    def stop(self):\n        PosixReactorBase.stop(self)\n        fire_shutdown = functools.partial(self.fireSystemEvent, \"shutdown\")\n        self._io_loop.add_callback(fire_shutdown)\n\n    def crash(self):\n        PosixReactorBase.crash(self)\n        self._io_loop.stop()\n\n    def doIteration(self, delay):\n        raise NotImplementedError(\"doIteration\")\n\n    def mainLoop(self):\n        self._io_loop.start()\n\n\nclass _TestReactor(TornadoReactor):\n    \"\"\"Subclass of TornadoReactor for use in unittests.\n\n    This can't go in the test.py file because of import-order dependencies\n    with the Twisted reactor test builder.\n    \"\"\"\n    def __init__(self):\n        # always use a new ioloop\n        super(_TestReactor, self).__init__(IOLoop())\n\n    def listenTCP(self, port, factory, backlog=50, interface=''):\n        # default to localhost to avoid firewall prompts on the mac\n        if not interface:\n            interface = '127.0.0.1'\n        return super(_TestReactor, self).listenTCP(\n            port, factory, backlog=backlog, interface=interface)\n\n    def listenUDP(self, port, protocol, interface='', maxPacketSize=8192):\n        if not interface:\n            interface = '127.0.0.1'\n        return super(_TestReactor, self).listenUDP(\n            port, protocol, interface=interface, maxPacketSize=maxPacketSize)\n\n\ndef install(io_loop=None):\n    \"\"\"Install this package as the default Twisted reactor.\"\"\"\n    if not io_loop:\n        io_loop = tornado.ioloop.IOLoop.current()\n    reactor = TornadoReactor(io_loop)\n    from twisted.internet.main import installReactor\n    installReactor(reactor)\n    return reactor\n\n\n@implementer(IReadDescriptor, IWriteDescriptor)\nclass _FD(object):\n    def __init__(self, fd, handler):\n        self.fd = fd\n        self.handler = handler\n        self.reading = False\n        self.writing = False\n        self.lost = False\n\n    def fileno(self):\n        return self.fd\n\n    def doRead(self):\n        if not self.lost:\n            self.handler(self.fd, tornado.ioloop.IOLoop.READ)\n\n    def doWrite(self):\n        if not self.lost:\n            self.handler(self.fd, tornado.ioloop.IOLoop.WRITE)\n\n    def connectionLost(self, reason):\n        if not self.lost:\n            self.handler(self.fd, tornado.ioloop.IOLoop.ERROR)\n            self.lost = True\n\n    def logPrefix(self):\n        return ''\n\n\nclass TwistedIOLoop(tornado.ioloop.IOLoop):\n    \"\"\"IOLoop implementation that runs on Twisted.\n\n    Uses the global Twisted reactor by default.  To create multiple\n    `TwistedIOLoops` in the same process, you must pass a unique reactor\n    when constructing each one.\n\n    Not compatible with `tornado.process.Subprocess.set_exit_callback`\n    because the ``SIGCHLD`` handlers used by Tornado and Twisted conflict\n    with each other.\n    \"\"\"\n    def initialize(self, reactor=None):\n        if reactor is None:\n            import twisted.internet.reactor\n            reactor = twisted.internet.reactor\n        self.reactor = reactor\n        self.fds = {}\n        self.reactor.callWhenRunning(self.make_current)\n\n    def close(self, all_fds=False):\n        self.reactor.removeAll()\n        for c in self.reactor.getDelayedCalls():\n            c.cancel()\n\n    def add_handler(self, fd, handler, events):\n        if fd in self.fds:\n            raise ValueError('fd %d added twice' % fd)\n        self.fds[fd] = _FD(fd, wrap(handler))\n        if events & tornado.ioloop.IOLoop.READ:\n            self.fds[fd].reading = True\n            self.reactor.addReader(self.fds[fd])\n        if events & tornado.ioloop.IOLoop.WRITE:\n            self.fds[fd].writing = True\n            self.reactor.addWriter(self.fds[fd])\n\n    def update_handler(self, fd, events):\n        if events & tornado.ioloop.IOLoop.READ:\n            if not self.fds[fd].reading:\n                self.fds[fd].reading = True\n                self.reactor.addReader(self.fds[fd])\n        else:\n            if self.fds[fd].reading:\n                self.fds[fd].reading = False\n                self.reactor.removeReader(self.fds[fd])\n        if events & tornado.ioloop.IOLoop.WRITE:\n            if not self.fds[fd].writing:\n                self.fds[fd].writing = True\n                self.reactor.addWriter(self.fds[fd])\n        else:\n            if self.fds[fd].writing:\n                self.fds[fd].writing = False\n                self.reactor.removeWriter(self.fds[fd])\n\n    def remove_handler(self, fd):\n        if fd not in self.fds:\n            return\n        self.fds[fd].lost = True\n        if self.fds[fd].reading:\n            self.reactor.removeReader(self.fds[fd])\n        if self.fds[fd].writing:\n            self.reactor.removeWriter(self.fds[fd])\n        del self.fds[fd]\n\n    def start(self):\n        self.reactor.run()\n\n    def stop(self):\n        self.reactor.crash()\n\n    def _run_callback(self, callback, *args, **kwargs):\n        try:\n            callback(*args, **kwargs)\n        except Exception:\n            self.handle_callback_exception(callback)\n\n    def add_timeout(self, deadline, callback):\n        if isinstance(deadline, (int, long, float)):\n            delay = max(deadline - self.time(), 0)\n        elif isinstance(deadline, datetime.timedelta):\n            delay = tornado.ioloop._Timeout.timedelta_to_seconds(deadline)\n        else:\n            raise TypeError(\"Unsupported deadline %r\")\n        return self.reactor.callLater(delay, self._run_callback, wrap(callback))\n\n    def remove_timeout(self, timeout):\n        if timeout.active():\n            timeout.cancel()\n\n    def add_callback(self, callback, *args, **kwargs):\n        self.reactor.callFromThread(self._run_callback,\n                                    wrap(callback), *args, **kwargs)\n\n    def add_callback_from_signal(self, callback, *args, **kwargs):\n        self.add_callback(callback, *args, **kwargs)\n\n\nclass TwistedResolver(Resolver):\n    \"\"\"Twisted-based asynchronous resolver.\n\n    This is a non-blocking and non-threaded resolver.  It is\n    recommended only when threads cannot be used, since it has\n    limitations compared to the standard ``getaddrinfo``-based\n    `~tornado.netutil.Resolver` and\n    `~tornado.netutil.ThreadedResolver`.  Specifically, it returns at\n    most one result, and arguments other than ``host`` and ``family``\n    are ignored.  It may fail to resolve when ``family`` is not\n    ``socket.AF_UNSPEC``.\n\n    Requires Twisted 12.1 or newer.\n    \"\"\"\n    def initialize(self, io_loop=None):\n        self.io_loop = io_loop or IOLoop.current()\n        # partial copy of twisted.names.client.createResolver, which doesn't\n        # allow for a reactor to be passed in.\n        self.reactor = tornado.platform.twisted.TornadoReactor(io_loop)\n\n        host_resolver = twisted.names.hosts.Resolver('/etc/hosts')\n        cache_resolver = twisted.names.cache.CacheResolver(reactor=self.reactor)\n        real_resolver = twisted.names.client.Resolver('/etc/resolv.conf',\n                                                      reactor=self.reactor)\n        self.resolver = twisted.names.resolve.ResolverChain(\n            [host_resolver, cache_resolver, real_resolver])\n\n    @gen.coroutine\n    def resolve(self, host, port, family=0):\n        # getHostByName doesn't accept IP addresses, so if the input\n        # looks like an IP address just return it immediately.\n        if twisted.internet.abstract.isIPAddress(host):\n            resolved = host\n            resolved_family = socket.AF_INET\n        elif twisted.internet.abstract.isIPv6Address(host):\n            resolved = host\n            resolved_family = socket.AF_INET6\n        else:\n            deferred = self.resolver.getHostByName(utf8(host))\n            resolved = yield gen.Task(deferred.addCallback)\n            if twisted.internet.abstract.isIPAddress(resolved):\n                resolved_family = socket.AF_INET\n            elif twisted.internet.abstract.isIPv6Address(resolved):\n                resolved_family = socket.AF_INET6\n            else:\n                resolved_family = socket.AF_UNSPEC\n        if family != socket.AF_UNSPEC and family != resolved_family:\n            raise Exception('Requested socket family %d but got %d' %\n                            (family, resolved_family))\n        result = [\n            (resolved_family, (resolved, port)),\n        ]\n        raise gen.Return(result)\n",
            "new_file_content": "# Author: Ovidiu Predescu\n# Date: July 2011\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# Note:  This module's docs are not currently extracted automatically,\n# so changes must be made manually to twisted.rst\n# TODO: refactor doc build process to use an appropriate virtualenv\n\"\"\"Bridges between the Twisted reactor and Tornado IOLoop.\n\nThis module lets you run applications and libraries written for\nTwisted in a Tornado application.  It can be used in two modes,\ndepending on which library's underlying event loop you want to use.\n\nThis module has been tested with Twisted versions 11.0.0 and newer.\n\nTwisted on Tornado\n------------------\n\n`TornadoReactor` implements the Twisted reactor interface on top of\nthe Tornado IOLoop.  To use it, simply call `install` at the beginning\nof the application::\n\n    import tornado.platform.twisted\n    tornado.platform.twisted.install()\n    from twisted.internet import reactor\n\nWhen the app is ready to start, call `IOLoop.instance().start()`\ninstead of `reactor.run()`.\n\nIt is also possible to create a non-global reactor by calling\n`tornado.platform.twisted.TornadoReactor(io_loop)`.  However, if\nthe `IOLoop` and reactor are to be short-lived (such as those used in\nunit tests), additional cleanup may be required.  Specifically, it is\nrecommended to call::\n\n    reactor.fireSystemEvent('shutdown')\n    reactor.disconnectAll()\n\nbefore closing the `IOLoop`.\n\nTornado on Twisted\n------------------\n\n`TwistedIOLoop` implements the Tornado IOLoop interface on top of the Twisted\nreactor.  Recommended usage::\n\n    from tornado.platform.twisted import TwistedIOLoop\n    from twisted.internet import reactor\n    TwistedIOLoop().install()\n    # Set up your tornado application as usual using `IOLoop.instance`\n    reactor.run()\n\n`TwistedIOLoop` always uses the global Twisted reactor.\n\"\"\"\n\nfrom __future__ import absolute_import, division, print_function, with_statement\n\nimport datetime\nimport functools\nimport socket\n\nimport twisted.internet.abstract\nfrom twisted.internet.posixbase import PosixReactorBase\nfrom twisted.internet.interfaces import \\\n    IReactorFDSet, IDelayedCall, IReactorTime, IReadDescriptor, IWriteDescriptor\nfrom twisted.python import failure, log\nfrom twisted.internet import error\nimport twisted.names.cache\nimport twisted.names.client\nimport twisted.names.hosts\nimport twisted.names.resolve\n\nfrom zope.interface import implementer\n\nfrom tornado.escape import utf8\nfrom tornado import gen\nimport tornado.ioloop\nfrom tornado.log import app_log\nfrom tornado.netutil import Resolver\nfrom tornado.stack_context import NullContext, wrap\nfrom tornado.ioloop import IOLoop\n\n\n@implementer(IDelayedCall)\nclass TornadoDelayedCall(object):\n    \"\"\"DelayedCall object for Tornado.\"\"\"\n    def __init__(self, reactor, seconds, f, *args, **kw):\n        self._reactor = reactor\n        self._func = functools.partial(f, *args, **kw)\n        self._time = self._reactor.seconds() + seconds\n        self._timeout = self._reactor._io_loop.add_timeout(self._time,\n                                                           self._called)\n        self._active = True\n\n    def _called(self):\n        self._active = False\n        self._reactor._removeDelayedCall(self)\n        try:\n            self._func()\n        except:\n            app_log.error(\"_called caught exception\", exc_info=True)\n\n    def getTime(self):\n        return self._time\n\n    def cancel(self):\n        self._active = False\n        self._reactor._io_loop.remove_timeout(self._timeout)\n        self._reactor._removeDelayedCall(self)\n\n    def delay(self, seconds):\n        self._reactor._io_loop.remove_timeout(self._timeout)\n        self._time += seconds\n        self._timeout = self._reactor._io_loop.add_timeout(self._time,\n                                                           self._called)\n\n    def reset(self, seconds):\n        self._reactor._io_loop.remove_timeout(self._timeout)\n        self._time = self._reactor.seconds() + seconds\n        self._timeout = self._reactor._io_loop.add_timeout(self._time,\n                                                           self._called)\n\n    def active(self):\n        return self._active\n\n\n@implementer(IReactorTime, IReactorFDSet)\nclass TornadoReactor(PosixReactorBase):\n    \"\"\"Twisted reactor built on the Tornado IOLoop.\n\n    Since it is intented to be used in applications where the top-level\n    event loop is ``io_loop.start()`` rather than ``reactor.run()``,\n    it is implemented a little differently than other Twisted reactors.\n    We override `mainLoop` instead of `doIteration` and must implement\n    timed call functionality on top of `IOLoop.add_timeout` rather than\n    using the implementation in `PosixReactorBase`.\n    \"\"\"\n    def __init__(self, io_loop=None):\n        if not io_loop:\n            io_loop = tornado.ioloop.IOLoop.current()\n        self._io_loop = io_loop\n        self._readers = {}  # map of reader objects to fd\n        self._writers = {}  # map of writer objects to fd\n        self._fds = {}  # a map of fd to a (reader, writer) tuple\n        self._delayedCalls = {}\n        PosixReactorBase.__init__(self)\n        self.addSystemEventTrigger('during', 'shutdown', self.crash)\n\n        # IOLoop.start() bypasses some of the reactor initialization.\n        # Fire off the necessary events if they weren't already triggered\n        # by reactor.run().\n        def start_if_necessary():\n            if not self._started:\n                self.fireSystemEvent('startup')\n        self._io_loop.add_callback(start_if_necessary)\n\n    # IReactorTime\n    def seconds(self):\n        return self._io_loop.time()\n\n    def callLater(self, seconds, f, *args, **kw):\n        dc = TornadoDelayedCall(self, seconds, f, *args, **kw)\n        self._delayedCalls[dc] = True\n        return dc\n\n    def getDelayedCalls(self):\n        return [x for x in self._delayedCalls if x._active]\n\n    def _removeDelayedCall(self, dc):\n        if dc in self._delayedCalls:\n            del self._delayedCalls[dc]\n\n    # IReactorThreads\n    def callFromThread(self, f, *args, **kw):\n        \"\"\"See `twisted.internet.interfaces.IReactorThreads.callFromThread`\"\"\"\n        assert callable(f), \"%s is not callable\" % f\n        with NullContext():\n            # This NullContext is mainly for an edge case when running\n            # TwistedIOLoop on top of a TornadoReactor.\n            # TwistedIOLoop.add_callback uses reactor.callFromThread and\n            # should not pick up additional StackContexts along the way.\n            self._io_loop.add_callback(f, *args, **kw)\n\n    # We don't need the waker code from the super class, Tornado uses\n    # its own waker.\n    def installWaker(self):\n        pass\n\n    def wakeUp(self):\n        pass\n\n    # IReactorFDSet\n    def _invoke_callback(self, fd, events):\n        if fd not in self._fds:\n            return\n        (reader, writer) = self._fds[fd]\n        if reader:\n            err = None\n            if reader.fileno() == -1:\n                err = error.ConnectionLost()\n            elif events & IOLoop.READ:\n                err = log.callWithLogger(reader, reader.doRead)\n            if err is None and events & IOLoop.ERROR:\n                err = error.ConnectionLost()\n            if err is not None:\n                self.removeReader(reader)\n                reader.readConnectionLost(failure.Failure(err))\n        if writer:\n            err = None\n            if writer.fileno() == -1:\n                err = error.ConnectionLost()\n            elif events & IOLoop.WRITE:\n                err = log.callWithLogger(writer, writer.doWrite)\n            if err is None and events & IOLoop.ERROR:\n                err = error.ConnectionLost()\n            if err is not None:\n                self.removeWriter(writer)\n                writer.writeConnectionLost(failure.Failure(err))\n\n    def addReader(self, reader):\n        \"\"\"Add a FileDescriptor for notification of data available to read.\"\"\"\n        if reader in self._readers:\n            # Don't add the reader if it's already there\n            return\n        fd = reader.fileno()\n        self._readers[reader] = fd\n        if fd in self._fds:\n            (_, writer) = self._fds[fd]\n            self._fds[fd] = (reader, writer)\n            if writer:\n                # We already registered this fd for write events,\n                # update it for read events as well.\n                self._io_loop.update_handler(fd, IOLoop.READ | IOLoop.WRITE)\n        else:\n            with NullContext():\n                self._fds[fd] = (reader, None)\n                self._io_loop.add_handler(fd, self._invoke_callback,\n                                          IOLoop.READ)\n\n    def addWriter(self, writer):\n        \"\"\"Add a FileDescriptor for notification of data available to write.\"\"\"\n        if writer in self._writers:\n            return\n        fd = writer.fileno()\n        self._writers[writer] = fd\n        if fd in self._fds:\n            (reader, _) = self._fds[fd]\n            self._fds[fd] = (reader, writer)\n            if reader:\n                # We already registered this fd for read events,\n                # update it for write events as well.\n                self._io_loop.update_handler(fd, IOLoop.READ | IOLoop.WRITE)\n        else:\n            with NullContext():\n                self._fds[fd] = (None, writer)\n                self._io_loop.add_handler(fd, self._invoke_callback,\n                                          IOLoop.WRITE)\n\n    def removeReader(self, reader):\n        \"\"\"Remove a Selectable for notification of data available to read.\"\"\"\n        if reader in self._readers:\n            fd = self._readers.pop(reader)\n            (_, writer) = self._fds[fd]\n            if writer:\n                # We have a writer so we need to update the IOLoop for\n                # write events only.\n                self._fds[fd] = (None, writer)\n                self._io_loop.update_handler(fd, IOLoop.WRITE)\n            else:\n                # Since we have no writer registered, we remove the\n                # entry from _fds and unregister the handler from the\n                # IOLoop\n                del self._fds[fd]\n                self._io_loop.remove_handler(fd)\n\n    def removeWriter(self, writer):\n        \"\"\"Remove a Selectable for notification of data available to write.\"\"\"\n        if writer in self._writers:\n            fd = self._writers.pop(writer)\n            (reader, _) = self._fds[fd]\n            if reader:\n                # We have a reader so we need to update the IOLoop for\n                # read events only.\n                self._fds[fd] = (reader, None)\n                self._io_loop.update_handler(fd, IOLoop.READ)\n            else:\n                # Since we have no reader registered, we remove the\n                # entry from the _fds and unregister the handler from\n                # the IOLoop.\n                del self._fds[fd]\n                self._io_loop.remove_handler(fd)\n\n    def removeAll(self):\n        return self._removeAll(self._readers, self._writers)\n\n    def getReaders(self):\n        return self._readers.keys()\n\n    def getWriters(self):\n        return self._writers.keys()\n\n    # The following functions are mainly used in twisted-style test cases;\n    # it is expected that most users of the TornadoReactor will call\n    # IOLoop.start() instead of Reactor.run().\n    def stop(self):\n        PosixReactorBase.stop(self)\n        fire_shutdown = functools.partial(self.fireSystemEvent, \"shutdown\")\n        self._io_loop.add_callback(fire_shutdown)\n\n    def crash(self):\n        PosixReactorBase.crash(self)\n        self._io_loop.stop()\n\n    def doIteration(self, delay):\n        raise NotImplementedError(\"doIteration\")\n\n    def mainLoop(self):\n        self._io_loop.start()\n\n\nclass _TestReactor(TornadoReactor):\n    \"\"\"Subclass of TornadoReactor for use in unittests.\n\n    This can't go in the test.py file because of import-order dependencies\n    with the Twisted reactor test builder.\n    \"\"\"\n    def __init__(self):\n        # always use a new ioloop\n        super(_TestReactor, self).__init__(IOLoop())\n\n    def listenTCP(self, port, factory, backlog=50, interface=''):\n        # default to localhost to avoid firewall prompts on the mac\n        if not interface:\n            interface = '127.0.0.1'\n        return super(_TestReactor, self).listenTCP(\n            port, factory, backlog=backlog, interface=interface)\n\n    def listenUDP(self, port, protocol, interface='', maxPacketSize=8192):\n        if not interface:\n            interface = '127.0.0.1'\n        return super(_TestReactor, self).listenUDP(\n            port, protocol, interface=interface, maxPacketSize=maxPacketSize)\n\n\ndef install(io_loop=None):\n    \"\"\"Install this package as the default Twisted reactor.\"\"\"\n    if not io_loop:\n        io_loop = tornado.ioloop.IOLoop.current()\n    reactor = TornadoReactor(io_loop)\n    from twisted.internet.main import installReactor\n    installReactor(reactor)\n    return reactor\n\n\n@implementer(IReadDescriptor, IWriteDescriptor)\nclass _FD(object):\n    def __init__(self, fd, handler):\n        self.fd = fd\n        self.handler = handler\n        self.reading = False\n        self.writing = False\n        self.lost = False\n\n    def fileno(self):\n        return self.fd\n\n    def doRead(self):\n        if not self.lost:\n            self.handler(self.fd, tornado.ioloop.IOLoop.READ)\n\n    def doWrite(self):\n        if not self.lost:\n            self.handler(self.fd, tornado.ioloop.IOLoop.WRITE)\n\n    def connectionLost(self, reason):\n        if not self.lost:\n            self.handler(self.fd, tornado.ioloop.IOLoop.ERROR)\n            self.lost = True\n\n    def logPrefix(self):\n        return ''\n\n\nclass TwistedIOLoop(tornado.ioloop.IOLoop):\n    \"\"\"IOLoop implementation that runs on Twisted.\n\n    Uses the global Twisted reactor by default.  To create multiple\n    `TwistedIOLoops` in the same process, you must pass a unique reactor\n    when constructing each one.\n\n    Not compatible with `tornado.process.Subprocess.set_exit_callback`\n    because the ``SIGCHLD`` handlers used by Tornado and Twisted conflict\n    with each other.\n    \"\"\"\n    def initialize(self, reactor=None):\n        if reactor is None:\n            import twisted.internet.reactor\n            reactor = twisted.internet.reactor\n        self.reactor = reactor\n        self.fds = {}\n        self.reactor.callWhenRunning(self.make_current)\n\n    def close(self, all_fds=False):\n        self.reactor.removeAll()\n        for c in self.reactor.getDelayedCalls():\n            c.cancel()\n\n    def add_handler(self, fd, handler, events):\n        if fd in self.fds:\n            raise ValueError('fd %d added twice' % fd)\n        self.fds[fd] = _FD(fd, wrap(handler))\n        if events & tornado.ioloop.IOLoop.READ:\n            self.fds[fd].reading = True\n            self.reactor.addReader(self.fds[fd])\n        if events & tornado.ioloop.IOLoop.WRITE:\n            self.fds[fd].writing = True\n            self.reactor.addWriter(self.fds[fd])\n\n    def update_handler(self, fd, events):\n        if events & tornado.ioloop.IOLoop.READ:\n            if not self.fds[fd].reading:\n                self.fds[fd].reading = True\n                self.reactor.addReader(self.fds[fd])\n        else:\n            if self.fds[fd].reading:\n                self.fds[fd].reading = False\n                self.reactor.removeReader(self.fds[fd])\n        if events & tornado.ioloop.IOLoop.WRITE:\n            if not self.fds[fd].writing:\n                self.fds[fd].writing = True\n                self.reactor.addWriter(self.fds[fd])\n        else:\n            if self.fds[fd].writing:\n                self.fds[fd].writing = False\n                self.reactor.removeWriter(self.fds[fd])\n\n    def remove_handler(self, fd):\n        if fd not in self.fds:\n            return\n        self.fds[fd].lost = True\n        if self.fds[fd].reading:\n            self.reactor.removeReader(self.fds[fd])\n        if self.fds[fd].writing:\n            self.reactor.removeWriter(self.fds[fd])\n        del self.fds[fd]\n\n    def start(self):\n        self.reactor.run()\n\n    def stop(self):\n        self.reactor.crash()\n\n    def _run_callback(self, callback, *args, **kwargs):\n        try:\n            callback(*args, **kwargs)\n        except Exception:\n            self.handle_callback_exception(callback)\n\n    def add_timeout(self, deadline, callback):\n        if isinstance(deadline, (int, long, float)):\n            delay = max(deadline - self.time(), 0)\n        elif isinstance(deadline, datetime.timedelta):\n            delay = tornado.ioloop._Timeout.timedelta_to_seconds(deadline)\n        else:\n            raise TypeError(\"Unsupported deadline %r\")\n        return self.reactor.callLater(delay, self._run_callback, wrap(callback))\n\n    def remove_timeout(self, timeout):\n        if timeout.active():\n            timeout.cancel()\n\n    def add_callback(self, callback, *args, **kwargs):\n        self.reactor.callFromThread(self._run_callback,\n                                    wrap(callback), *args, **kwargs)\n\n    def add_callback_from_signal(self, callback, *args, **kwargs):\n        self.add_callback(callback, *args, **kwargs)\n\n\nclass TwistedResolver(Resolver):\n    \"\"\"Twisted-based asynchronous resolver.\n\n    This is a non-blocking and non-threaded resolver.  It is\n    recommended only when threads cannot be used, since it has\n    limitations compared to the standard ``getaddrinfo``-based\n    `~tornado.netutil.Resolver` and\n    `~tornado.netutil.ThreadedResolver`.  Specifically, it returns at\n    most one result, and arguments other than ``host`` and ``family``\n    are ignored.  It may fail to resolve when ``family`` is not\n    ``socket.AF_UNSPEC``.\n\n    Requires Twisted 12.1 or newer.\n    \"\"\"\n    def initialize(self, io_loop=None):\n        self.io_loop = io_loop or IOLoop.current()\n        # partial copy of twisted.names.client.createResolver, which doesn't\n        # allow for a reactor to be passed in.\n        self.reactor = tornado.platform.twisted.TornadoReactor(io_loop)\n\n        host_resolver = twisted.names.hosts.Resolver('/etc/hosts')\n        cache_resolver = twisted.names.cache.CacheResolver(reactor=self.reactor)\n        real_resolver = twisted.names.client.Resolver('/etc/resolv.conf',\n                                                      reactor=self.reactor)\n        self.resolver = twisted.names.resolve.ResolverChain(\n            [host_resolver, cache_resolver, real_resolver])\n\n    @gen.coroutine\n    def resolve(self, host, port, family=0):\n        # getHostByName doesn't accept IP addresses, so if the input\n        # looks like an IP address just return it immediately.\n        if twisted.internet.abstract.isIPAddress(host):\n            resolved = host\n            resolved_family = socket.AF_INET\n        elif twisted.internet.abstract.isIPv6Address(host):\n            resolved = host\n            resolved_family = socket.AF_INET6\n        else:\n            deferred = self.resolver.getHostByName(utf8(host))\n            resolved = yield gen.Task(deferred.addBoth)\n            if isinstance(resolved, failure.Failure):\n                resolved.raiseException()\n            elif twisted.internet.abstract.isIPAddress(resolved):\n                resolved_family = socket.AF_INET\n            elif twisted.internet.abstract.isIPv6Address(resolved):\n                resolved_family = socket.AF_INET6\n            else:\n                resolved_family = socket.AF_UNSPEC\n        if family != socket.AF_UNSPEC and family != resolved_family:\n            raise Exception('Requested socket family %d but got %d' %\n                            (family, resolved_family))\n        result = [\n            (resolved_family, (resolved, port)),\n        ]\n        raise gen.Return(result)\n",
            "header": {
                "file": {
                    "path": "tornado/platform/twisted.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "c0ee5957",
                "new_commit_hash": "86ef71b9",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/tornado/platform/twisted.py"
            },
            "plus_file": {
                "path": "b/tornado/platform/twisted.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 527,
                            "length": 8
                        },
                        "new_range": {
                            "start": 527,
                            "length": 10
                        },
                        "section": "class TwistedResolver(Resolver):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "            resolved_family = socket.AF_INET6",
                                "type": "context"
                            },
                            {
                                "content": "        else:",
                                "type": "context"
                            },
                            {
                                "content": "            deferred = self.resolver.getHostByName(utf8(host))",
                                "type": "context"
                            },
                            {
                                "content": "            resolved = yield gen.Task(deferred.addCallback)",
                                "type": "deleted"
                            },
                            {
                                "content": "            if twisted.internet.abstract.isIPAddress(resolved):",
                                "type": "deleted"
                            },
                            {
                                "content": "            resolved = yield gen.Task(deferred.addBoth)",
                                "type": "added"
                            },
                            {
                                "content": "            if isinstance(resolved, failure.Failure):",
                                "type": "added"
                            },
                            {
                                "content": "                resolved.raiseException()",
                                "type": "added"
                            },
                            {
                                "content": "            elif twisted.internet.abstract.isIPAddress(resolved):",
                                "type": "added"
                            },
                            {
                                "content": "                resolved_family = socket.AF_INET",
                                "type": "context"
                            },
                            {
                                "content": "            elif twisted.internet.abstract.isIPv6Address(resolved):",
                                "type": "context"
                            },
                            {
                                "content": "                resolved_family = socket.AF_INET6",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/platform/twisted.py",
                            "type": "class",
                            "name": "TwistedResolver",
                            "content": "class TwistedResolver(Resolver):\n    \"\"\"Twisted-based asynchronous resolver.\n\n    This is a non-blocking and non-threaded resolver.  It is\n    recommended only when threads cannot be used, since it has\n    limitations compared to the standard ``getaddrinfo``-based\n    `~tornado.netutil.Resolver` and\n    `~tornado.netutil.ThreadedResolver`.  Specifically, it returns at\n    most one result, and arguments other than ``host`` and ``family``\n    are ignored.  It may fail to resolve when ``family`` is not\n    ``socket.AF_UNSPEC``.\n\n    Requires Twisted 12.1 or newer.\n    \"\"\"\n    def initialize(self, io_loop=None):\n        self.io_loop = io_loop or IOLoop.current()\n        # partial copy of twisted.names.client.createResolver, which doesn't\n        # allow for a reactor to be passed in.\n        self.reactor = tornado.platform.twisted.TornadoReactor(io_loop)\n\n        host_resolver = twisted.names.hosts.Resolver('/etc/hosts')\n        cache_resolver = twisted.names.cache.CacheResolver(reactor=self.reactor)\n        real_resolver = twisted.names.client.Resolver('/etc/resolv.conf',\n                                                      reactor=self.reactor)\n        self.resolver = twisted.names.resolve.ResolverChain(\n            [host_resolver, cache_resolver, real_resolver])\n\n    @gen.coroutine\n    def resolve(self, host, port, family=0):\n        # getHostByName doesn't accept IP addresses, so if the input\n        # looks like an IP address just return it immediately.\n        if twisted.internet.abstract.isIPAddress(host):\n            resolved = host\n            resolved_family = socket.AF_INET\n        elif twisted.internet.abstract.isIPv6Address(host):\n            resolved = host\n            resolved_family = socket.AF_INET6\n        else:\n            deferred = self.resolver.getHostByName(utf8(host))\n            resolved = yield gen.Task(deferred.addCallback)\n            if twisted.internet.abstract.isIPAddress(resolved):\n                resolved_family = socket.AF_INET\n            elif twisted.internet.abstract.isIPv6Address(resolved):\n                resolved_family = socket.AF_INET6\n            else:\n                resolved_family = socket.AF_UNSPEC\n        if family != socket.AF_UNSPEC and family != resolved_family:\n            raise Exception('Requested socket family %d but got %d' %\n                            (family, resolved_family))\n        result = [\n            (resolved_family, (resolved, port)),\n        ]\n        raise gen.Return(result)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 491,
                            "end_lineno": 543,
                            "parent": null
                        },
                        {
                            "file_name": "tornado/platform/twisted.py",
                            "type": "method",
                            "name": "TwistedResolver.resolve",
                            "content": "class TwistedResolver(Resolver):\n    \"\"\"Twisted-based asynchronous resolver.\n\n    This is a non-blocking and non-threaded resolver.  It is\n    recommended only when threads cannot be used, since it has\n    limitations compared to the standard ``getaddrinfo``-based\n    `~tornado.netutil.Resolver` and\n    `~tornado.netutil.ThreadedResolver`.  Specifically, it returns at\n    most one result, and arguments other than ``host`` and ``family``\n    are ignored.  It may fail to resolve when ``family`` is not\n    ``socket.AF_UNSPEC``.\n\n    Requires Twisted 12.1 or newer.\n    \"\"\"\n    def initialize(self, io_loop=None):\n        self.io_loop = io_loop or IOLoop.current()\n        # partial copy of twisted.names.client.createResolver, which doesn't\n        # allow for a reactor to be passed in.\n        self.reactor = tornado.platform.twisted.TornadoReactor(io_loop)\n\n        host_resolver = twisted.names.hosts.Resolver('/etc/hosts')\n        cache_resolver = twisted.names.cache.CacheResolver(reactor=self.reactor)\n        real_resolver = twisted.names.client.Resolver('/etc/resolv.conf',\n                                                      reactor=self.reactor)\n        self.resolver = twisted.names.resolve.ResolverChain(\n            [host_resolver, cache_resolver, real_resolver])\n\n    @gen.coroutine\n    def resolve(self, host, port, family=0):\n        # getHostByName doesn't accept IP addresses, so if the input\n        # looks like an IP address just return it immediately.\n        if twisted.internet.abstract.isIPAddress(host):\n            resolved = host\n            resolved_family = socket.AF_INET\n        elif twisted.internet.abstract.isIPv6Address(host):\n            resolved = host\n            resolved_family = socket.AF_INET6\n        else:\n            deferred = self.resolver.getHostByName(utf8(host))\n            resolved = yield gen.Task(deferred.addCallback)\n            if twisted.internet.abstract.isIPAddress(resolved):\n                resolved_family = socket.AF_INET\n            elif twisted.internet.abstract.isIPv6Address(resolved):\n                resolved_family = socket.AF_INET6\n            else:\n                resolved_family = socket.AF_UNSPEC\n        if family != socket.AF_UNSPEC and family != resolved_family:\n            raise Exception('Requested socket family %d but got %d' %\n                            (family, resolved_family))\n        result = [\n            (resolved_family, (resolved, port)),\n        ]\n        raise gen.Return(result)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 519,
                            "end_lineno": 543,
                            "parent": {
                                "file_name": "tornado/platform/twisted.py",
                                "type": "class",
                                "name": "TwistedResolver",
                                "content": "class TwistedResolver(Resolver):\n    \"\"\"Twisted-based asynchronous resolver.\n\n    This is a non-blocking and non-threaded resolver.  It is\n    recommended only when threads cannot be used, since it has\n    limitations compared to the standard ``getaddrinfo``-based\n    `~tornado.netutil.Resolver` and\n    `~tornado.netutil.ThreadedResolver`.  Specifically, it returns at\n    most one result, and arguments other than ``host`` and ``family``\n    are ignored.  It may fail to resolve when ``family`` is not\n    ``socket.AF_UNSPEC``.\n\n    Requires Twisted 12.1 or newer.\n    \"\"\"\n    def initialize(self, io_loop=None):\n        self.io_loop = io_loop or IOLoop.current()\n        # partial copy of twisted.names.client.createResolver, which doesn't\n        # allow for a reactor to be passed in.\n        self.reactor = tornado.platform.twisted.TornadoReactor(io_loop)\n\n        host_resolver = twisted.names.hosts.Resolver('/etc/hosts')\n        cache_resolver = twisted.names.cache.CacheResolver(reactor=self.reactor)\n        real_resolver = twisted.names.client.Resolver('/etc/resolv.conf',\n                                                      reactor=self.reactor)\n        self.resolver = twisted.names.resolve.ResolverChain(\n            [host_resolver, cache_resolver, real_resolver])\n\n    @gen.coroutine\n    def resolve(self, host, port, family=0):\n        # getHostByName doesn't accept IP addresses, so if the input\n        # looks like an IP address just return it immediately.\n        if twisted.internet.abstract.isIPAddress(host):\n            resolved = host\n            resolved_family = socket.AF_INET\n        elif twisted.internet.abstract.isIPv6Address(host):\n            resolved = host\n            resolved_family = socket.AF_INET6\n        else:\n            deferred = self.resolver.getHostByName(utf8(host))\n            resolved = yield gen.Task(deferred.addCallback)\n            if twisted.internet.abstract.isIPAddress(resolved):\n                resolved_family = socket.AF_INET\n            elif twisted.internet.abstract.isIPv6Address(resolved):\n                resolved_family = socket.AF_INET6\n            else:\n                resolved_family = socket.AF_UNSPEC\n        if family != socket.AF_UNSPEC and family != resolved_family:\n            raise Exception('Requested socket family %d but got %d' %\n                            (family, resolved_family))\n        result = [\n            (resolved_family, (resolved, port)),\n        ]\n        raise gen.Return(result)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 491,
                                "end_lineno": 543,
                                "parent": null
                            }
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        },
        {
            "old_file_content": "from __future__ import absolute_import, division, print_function, with_statement\n\nimport signal\nimport socket\nfrom subprocess import Popen\nimport sys\nimport time\n\nfrom tornado.netutil import BlockingResolver, ThreadedResolver, is_valid_ip\nfrom tornado.testing import AsyncTestCase, gen_test\nfrom tornado.test.util import unittest\n\ntry:\n    from concurrent import futures\nexcept ImportError:\n    futures = None\n\ntry:\n    import pycares\nexcept ImportError:\n    pycares = None\nelse:\n    from tornado.platform.caresresolver import CaresResolver\n\ntry:\n    import twisted\nexcept ImportError:\n    twisted = None\nelse:\n    from tornado.platform.twisted import TwistedResolver\n\n\nclass _ResolverTestMixin(object):\n    def test_localhost(self):\n        self.resolver.resolve('localhost', 80, callback=self.stop)\n        result = self.wait()\n        self.assertIn((socket.AF_INET, ('127.0.0.1', 80)), result)\n\n    @gen_test\n    def test_future_interface(self):\n        addrinfo = yield self.resolver.resolve('localhost', 80,\n                                               socket.AF_UNSPEC)\n        self.assertIn((socket.AF_INET, ('127.0.0.1', 80)),\n                      addrinfo)\n\n\nclass BlockingResolverTest(AsyncTestCase, _ResolverTestMixin):\n    def setUp(self):\n        super(BlockingResolverTest, self).setUp()\n        self.resolver = BlockingResolver(io_loop=self.io_loop)\n\n\n@unittest.skipIf(futures is None, \"futures module not present\")\nclass ThreadedResolverTest(AsyncTestCase, _ResolverTestMixin):\n    def setUp(self):\n        super(ThreadedResolverTest, self).setUp()\n        self.resolver = ThreadedResolver(io_loop=self.io_loop)\n\n    def tearDown(self):\n        self.resolver.close()\n        super(ThreadedResolverTest, self).tearDown()\n\n\n@unittest.skipIf(futures is None, \"futures module not present\")\nclass ThreadedResolverImportTest(unittest.TestCase):\n    def test_import(self):\n        TIMEOUT = 5\n\n        # Test for a deadlock when importing a module that runs the\n        # ThreadedResolver at import-time. See resolve_test.py for\n        # full explanation.\n        command = [\n            sys.executable,\n            '-c',\n            'import tornado.test.resolve_test_helper']\n\n        start = time.time()\n        popen = Popen(command, preexec_fn=lambda: signal.alarm(TIMEOUT))\n        while time.time() - start < TIMEOUT:\n            return_code = popen.poll()\n            if return_code is not None:\n                self.assertEqual(0, return_code)\n                return  # Success.\n            time.sleep(0.05)\n\n        self.fail(\"import timed out\")\n\n\n@unittest.skipIf(pycares is None, \"pycares module not present\")\nclass CaresResolverTest(AsyncTestCase, _ResolverTestMixin):\n    def setUp(self):\n        super(CaresResolverTest, self).setUp()\n        self.resolver = CaresResolver(io_loop=self.io_loop)\n\n\n@unittest.skipIf(twisted is None, \"twisted module not present\")\n@unittest.skipIf(getattr(twisted, '__version__', '0.0') < \"12.1\", \"old version of twisted\")\nclass TwistedResolverTest(AsyncTestCase, _ResolverTestMixin):\n    def setUp(self):\n        super(TwistedResolverTest, self).setUp()\n        self.resolver = TwistedResolver(io_loop=self.io_loop)\n\n\nclass IsValidIPTest(unittest.TestCase):\n    def test_is_valid_ip(self):\n        self.assertTrue(is_valid_ip('127.0.0.1'))\n        self.assertTrue(is_valid_ip('4.4.4.4'))\n        self.assertTrue(is_valid_ip('::1'))\n        self.assertTrue(is_valid_ip('2620:0:1cfe:face:b00c::3'))\n        self.assertTrue(not is_valid_ip('www.google.com'))\n        self.assertTrue(not is_valid_ip('localhost'))\n        self.assertTrue(not is_valid_ip('4.4.4.4<'))\n        self.assertTrue(not is_valid_ip(' 127.0.0.1'))\n        self.assertTrue(not is_valid_ip(''))\n        self.assertTrue(not is_valid_ip(' '))\n        self.assertTrue(not is_valid_ip('\\n'))\n        self.assertTrue(not is_valid_ip('\\x00'))\n",
            "new_file_content": "from __future__ import absolute_import, division, print_function, with_statement\n\nimport signal\nimport socket\nfrom subprocess import Popen\nimport sys\nimport time\n\nfrom tornado.netutil import BlockingResolver, ThreadedResolver, is_valid_ip\nfrom tornado.stack_context import ExceptionStackContext\nfrom tornado.testing import AsyncTestCase, gen_test\nfrom tornado.test.util import unittest\n\ntry:\n    from concurrent import futures\nexcept ImportError:\n    futures = None\n\ntry:\n    import pycares\nexcept ImportError:\n    pycares = None\nelse:\n    from tornado.platform.caresresolver import CaresResolver\n\ntry:\n    import twisted\nexcept ImportError:\n    twisted = None\nelse:\n    from tornado.platform.twisted import TwistedResolver\n\n\nclass _ResolverTestMixin(object):\n    def test_localhost(self):\n        self.resolver.resolve('localhost', 80, callback=self.stop)\n        result = self.wait()\n        self.assertIn((socket.AF_INET, ('127.0.0.1', 80)), result)\n\n    @gen_test\n    def test_future_interface(self):\n        addrinfo = yield self.resolver.resolve('localhost', 80,\n                                               socket.AF_UNSPEC)\n        self.assertIn((socket.AF_INET, ('127.0.0.1', 80)),\n                      addrinfo)\n\n    def test_bad_host(self):\n        def handler(exc_typ, exc_val, exc_tb):\n            self.stop(exc_val)\n            return True  # Halt propagation.\n\n        with ExceptionStackContext(handler):\n            self.resolver.resolve('doesntexist', 80, callback=self.stop)\n\n        result = self.wait()\n        self.assertIsInstance(result, Exception)\n\n    @gen_test\n    def test_future_interface_bad_host(self):\n        with self.assertRaises(Exception):\n            yield self.resolver.resolve('doesntexist', 80,\n                                        socket.AF_UNSPEC)\n\n\nclass BlockingResolverTest(AsyncTestCase, _ResolverTestMixin):\n    def setUp(self):\n        super(BlockingResolverTest, self).setUp()\n        self.resolver = BlockingResolver(io_loop=self.io_loop)\n\n\n@unittest.skipIf(futures is None, \"futures module not present\")\nclass ThreadedResolverTest(AsyncTestCase, _ResolverTestMixin):\n    def setUp(self):\n        super(ThreadedResolverTest, self).setUp()\n        self.resolver = ThreadedResolver(io_loop=self.io_loop)\n\n    def tearDown(self):\n        self.resolver.close()\n        super(ThreadedResolverTest, self).tearDown()\n\n\n@unittest.skipIf(futures is None, \"futures module not present\")\nclass ThreadedResolverImportTest(unittest.TestCase):\n    def test_import(self):\n        TIMEOUT = 5\n\n        # Test for a deadlock when importing a module that runs the\n        # ThreadedResolver at import-time. See resolve_test.py for\n        # full explanation.\n        command = [\n            sys.executable,\n            '-c',\n            'import tornado.test.resolve_test_helper']\n\n        start = time.time()\n        popen = Popen(command, preexec_fn=lambda: signal.alarm(TIMEOUT))\n        while time.time() - start < TIMEOUT:\n            return_code = popen.poll()\n            if return_code is not None:\n                self.assertEqual(0, return_code)\n                return  # Success.\n            time.sleep(0.05)\n\n        self.fail(\"import timed out\")\n\n\n@unittest.skipIf(pycares is None, \"pycares module not present\")\nclass CaresResolverTest(AsyncTestCase, _ResolverTestMixin):\n    def setUp(self):\n        super(CaresResolverTest, self).setUp()\n        self.resolver = CaresResolver(io_loop=self.io_loop)\n\n\n@unittest.skipIf(twisted is None, \"twisted module not present\")\n@unittest.skipIf(getattr(twisted, '__version__', '0.0') < \"12.1\", \"old version of twisted\")\nclass TwistedResolverTest(AsyncTestCase, _ResolverTestMixin):\n    def setUp(self):\n        super(TwistedResolverTest, self).setUp()\n        self.resolver = TwistedResolver(io_loop=self.io_loop)\n\n\nclass IsValidIPTest(unittest.TestCase):\n    def test_is_valid_ip(self):\n        self.assertTrue(is_valid_ip('127.0.0.1'))\n        self.assertTrue(is_valid_ip('4.4.4.4'))\n        self.assertTrue(is_valid_ip('::1'))\n        self.assertTrue(is_valid_ip('2620:0:1cfe:face:b00c::3'))\n        self.assertTrue(not is_valid_ip('www.google.com'))\n        self.assertTrue(not is_valid_ip('localhost'))\n        self.assertTrue(not is_valid_ip('4.4.4.4<'))\n        self.assertTrue(not is_valid_ip(' 127.0.0.1'))\n        self.assertTrue(not is_valid_ip(''))\n        self.assertTrue(not is_valid_ip(' '))\n        self.assertTrue(not is_valid_ip('\\n'))\n        self.assertTrue(not is_valid_ip('\\x00'))\n",
            "header": {
                "file": {
                    "path": "tornado/test/netutil_test.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "d99e524c",
                "new_commit_hash": "777fb425",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/tornado/test/netutil_test.py"
            },
            "plus_file": {
                "path": "b/tornado/test/netutil_test.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 7,
                            "length": 6
                        },
                        "new_range": {
                            "start": 7,
                            "length": 7
                        },
                        "section": "import sys"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "import time",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "from tornado.netutil import BlockingResolver, ThreadedResolver, is_valid_ip",
                                "type": "context"
                            },
                            {
                                "content": "from tornado.stack_context import ExceptionStackContext",
                                "type": "added"
                            },
                            {
                                "content": "from tornado.testing import AsyncTestCase, gen_test",
                                "type": "context"
                            },
                            {
                                "content": "from tornado.test.util import unittest",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [],
                    "added_entities": [
                        {
                            "file_name": "tornado/test/netutil_test.py",
                            "type": "statement",
                            "name": "",
                            "content": "from tornado.stack_context import ExceptionStackContext",
                            "ast_type_str": "ImportFrom",
                            "start_lineno": 10,
                            "end_lineno": 10,
                            "parent": null
                        }
                    ],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 43,
                            "length": 6
                        },
                        "new_range": {
                            "start": 44,
                            "length": 23
                        },
                        "section": "class _ResolverTestMixin(object):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        self.assertIn((socket.AF_INET, ('127.0.0.1', 80)),",
                                "type": "context"
                            },
                            {
                                "content": "                      addrinfo)",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def test_bad_host(self):",
                                "type": "added"
                            },
                            {
                                "content": "        def handler(exc_typ, exc_val, exc_tb):",
                                "type": "added"
                            },
                            {
                                "content": "            self.stop(exc_val)",
                                "type": "added"
                            },
                            {
                                "content": "            return True  # Halt propagation.",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        with ExceptionStackContext(handler):",
                                "type": "added"
                            },
                            {
                                "content": "            self.resolver.resolve('doesntexist', 80, callback=self.stop)",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        result = self.wait()",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertIsInstance(result, Exception)",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    @gen_test",
                                "type": "added"
                            },
                            {
                                "content": "    def test_future_interface_bad_host(self):",
                                "type": "added"
                            },
                            {
                                "content": "        with self.assertRaises(Exception):",
                                "type": "added"
                            },
                            {
                                "content": "            yield self.resolver.resolve('doesntexist', 80,",
                                "type": "added"
                            },
                            {
                                "content": "                                        socket.AF_UNSPEC)",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "class BlockingResolverTest(AsyncTestCase, _ResolverTestMixin):",
                                "type": "context"
                            },
                            {
                                "content": "    def setUp(self):",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/test/netutil_test.py",
                            "type": "class",
                            "name": "_ResolverTestMixin",
                            "content": "class _ResolverTestMixin(object):\n    def test_localhost(self):\n        self.resolver.resolve('localhost', 80, callback=self.stop)\n        result = self.wait()\n        self.assertIn((socket.AF_INET, ('127.0.0.1', 80)), result)\n\n    @gen_test\n    def test_future_interface(self):\n        addrinfo = yield self.resolver.resolve('localhost', 80,\n                                               socket.AF_UNSPEC)\n        self.assertIn((socket.AF_INET, ('127.0.0.1', 80)),\n                      addrinfo)\n\n    def test_bad_host(self):\n        def handler(exc_typ, exc_val, exc_tb):\n            self.stop(exc_val)\n            return True  # Halt propagation.\n\n        with ExceptionStackContext(handler):\n            self.resolver.resolve('doesntexist', 80, callback=self.stop)\n\n        result = self.wait()\n        self.assertIsInstance(result, Exception)\n\n    @gen_test\n    def test_future_interface_bad_host(self):\n        with self.assertRaises(Exception):\n            yield self.resolver.resolve('doesntexist', 80,\n                                        socket.AF_UNSPEC)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 34,
                            "end_lineno": 62,
                            "parent": null
                        }
                    ],
                    "added_entities": [
                        {
                            "file_name": "tornado/test/netutil_test.py",
                            "type": "method",
                            "name": "_ResolverTestMixin.test_bad_host",
                            "content": "class _ResolverTestMixin(object):\n    def test_localhost(self):\n        self.resolver.resolve('localhost', 80, callback=self.stop)\n        result = self.wait()\n        self.assertIn((socket.AF_INET, ('127.0.0.1', 80)), result)\n\n    @gen_test\n    def test_future_interface(self):\n        addrinfo = yield self.resolver.resolve('localhost', 80,\n                                               socket.AF_UNSPEC)\n        self.assertIn((socket.AF_INET, ('127.0.0.1', 80)),\n                      addrinfo)\n\n    def test_bad_host(self):\n        def handler(exc_typ, exc_val, exc_tb):\n            self.stop(exc_val)\n            return True  # Halt propagation.\n\n        with ExceptionStackContext(handler):\n            self.resolver.resolve('doesntexist', 80, callback=self.stop)\n\n        result = self.wait()\n        self.assertIsInstance(result, Exception)\n\n    @gen_test\n    def test_future_interface_bad_host(self):\n        with self.assertRaises(Exception):\n            yield self.resolver.resolve('doesntexist', 80,\n                                        socket.AF_UNSPEC)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 47,
                            "end_lineno": 56,
                            "parent": {
                                "file_name": "tornado/test/netutil_test.py",
                                "type": "class",
                                "name": "_ResolverTestMixin",
                                "content": "class _ResolverTestMixin(object):\n    def test_localhost(self):\n        self.resolver.resolve('localhost', 80, callback=self.stop)\n        result = self.wait()\n        self.assertIn((socket.AF_INET, ('127.0.0.1', 80)), result)\n\n    @gen_test\n    def test_future_interface(self):\n        addrinfo = yield self.resolver.resolve('localhost', 80,\n                                               socket.AF_UNSPEC)\n        self.assertIn((socket.AF_INET, ('127.0.0.1', 80)),\n                      addrinfo)\n\n    def test_bad_host(self):\n        def handler(exc_typ, exc_val, exc_tb):\n            self.stop(exc_val)\n            return True  # Halt propagation.\n\n        with ExceptionStackContext(handler):\n            self.resolver.resolve('doesntexist', 80, callback=self.stop)\n\n        result = self.wait()\n        self.assertIsInstance(result, Exception)\n\n    @gen_test\n    def test_future_interface_bad_host(self):\n        with self.assertRaises(Exception):\n            yield self.resolver.resolve('doesntexist', 80,\n                                        socket.AF_UNSPEC)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 34,
                                "end_lineno": 62,
                                "parent": null
                            }
                        },
                        {
                            "file_name": "tornado/test/netutil_test.py",
                            "type": "method",
                            "name": "_ResolverTestMixin.test_future_interface_bad_host",
                            "content": "class _ResolverTestMixin(object):\n    def test_localhost(self):\n        self.resolver.resolve('localhost', 80, callback=self.stop)\n        result = self.wait()\n        self.assertIn((socket.AF_INET, ('127.0.0.1', 80)), result)\n\n    @gen_test\n    def test_future_interface(self):\n        addrinfo = yield self.resolver.resolve('localhost', 80,\n                                               socket.AF_UNSPEC)\n        self.assertIn((socket.AF_INET, ('127.0.0.1', 80)),\n                      addrinfo)\n\n    def test_bad_host(self):\n        def handler(exc_typ, exc_val, exc_tb):\n            self.stop(exc_val)\n            return True  # Halt propagation.\n\n        with ExceptionStackContext(handler):\n            self.resolver.resolve('doesntexist', 80, callback=self.stop)\n\n        result = self.wait()\n        self.assertIsInstance(result, Exception)\n\n    @gen_test\n    def test_future_interface_bad_host(self):\n        with self.assertRaises(Exception):\n            yield self.resolver.resolve('doesntexist', 80,\n                                        socket.AF_UNSPEC)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 59,
                            "end_lineno": 62,
                            "parent": {
                                "file_name": "tornado/test/netutil_test.py",
                                "type": "class",
                                "name": "_ResolverTestMixin",
                                "content": "class _ResolverTestMixin(object):\n    def test_localhost(self):\n        self.resolver.resolve('localhost', 80, callback=self.stop)\n        result = self.wait()\n        self.assertIn((socket.AF_INET, ('127.0.0.1', 80)), result)\n\n    @gen_test\n    def test_future_interface(self):\n        addrinfo = yield self.resolver.resolve('localhost', 80,\n                                               socket.AF_UNSPEC)\n        self.assertIn((socket.AF_INET, ('127.0.0.1', 80)),\n                      addrinfo)\n\n    def test_bad_host(self):\n        def handler(exc_typ, exc_val, exc_tb):\n            self.stop(exc_val)\n            return True  # Halt propagation.\n\n        with ExceptionStackContext(handler):\n            self.resolver.resolve('doesntexist', 80, callback=self.stop)\n\n        result = self.wait()\n        self.assertIsInstance(result, Exception)\n\n    @gen_test\n    def test_future_interface_bad_host(self):\n        with self.assertRaises(Exception):\n            yield self.resolver.resolve('doesntexist', 80,\n                                        socket.AF_UNSPEC)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 34,
                                "end_lineno": 62,
                                "parent": null
                            }
                        }
                    ],
                    "deleted_entities": []
                }
            ]
        }
    ],
    "old_commit_hash": "de39a398fb556c8c30b4c431b16974e0ca35e22d^",
    "new_commit_hash": "de39a398fb556c8c30b4c431b16974e0ca35e22d",
    "commit_message": "Merge pull request #965 from ajdavis/twisted-resolver-err\n\nError handling in TwistedResolver",
    "commit_date": "2013-12-28T16:44:20-08:00",
    "metadata": {}
}
{
    "repo_name": "tornado",
    "new_commit_hash": "de39a398fb556c8c30b4c431b16974e0ca35e22d",
    "test_file_codes": [
        "from __future__ import absolute_import, division, print_function, with_statement\n\nimport signal\nimport socket\nfrom subprocess import Popen\nimport sys\nimport time\n\nfrom tornado.netutil import BlockingResolver, ThreadedResolver, is_valid_ip\nfrom tornado.stack_context import ExceptionStackContext\nfrom tornado.testing import AsyncTestCase, gen_test\nfrom tornado.test.util import unittest\n\ntry:\n    from concurrent import futures\nexcept ImportError:\n    futures = None\n\ntry:\n    import pycares\nexcept ImportError:\n    pycares = None\nelse:\n    from tornado.platform.caresresolver import CaresResolver\n\ntry:\n    import twisted\nexcept ImportError:\n    twisted = None\nelse:\n    from tornado.platform.twisted import TwistedResolver\n\n\nclass _ResolverTestMixin(object):\n    def test_localhost(self):\n        self.resolver.resolve('localhost', 80, callback=self.stop)\n        result = self.wait()\n        self.assertIn((socket.AF_INET, ('127.0.0.1', 80)), result)\n\n    @gen_test\n    def test_future_interface(self):\n        addrinfo = yield self.resolver.resolve('localhost', 80,\n                                               socket.AF_UNSPEC)\n        self.assertIn((socket.AF_INET, ('127.0.0.1', 80)),\n                      addrinfo)\n\n    def test_bad_host(self):\n        def handler(exc_typ, exc_val, exc_tb):\n            self.stop(exc_val)\n            return True  # Halt propagation.\n\n        with ExceptionStackContext(handler):\n            self.resolver.resolve('doesntexist', 80, callback=self.stop)\n\n        result = self.wait()\n        self.assertIsInstance(result, Exception)\n\n    @gen_test\n    def test_future_interface_bad_host(self):\n        with self.assertRaises(Exception):\n            yield self.resolver.resolve('doesntexist', 80,\n                                        socket.AF_UNSPEC)\n\n\nclass BlockingResolverTest(AsyncTestCase, _ResolverTestMixin):\n    def setUp(self):\n        super(BlockingResolverTest, self).setUp()\n        self.resolver = BlockingResolver(io_loop=self.io_loop)\n\n\n@unittest.skipIf(futures is None, \"futures module not present\")\nclass ThreadedResolverTest(AsyncTestCase, _ResolverTestMixin):\n    def setUp(self):\n        super(ThreadedResolverTest, self).setUp()\n        self.resolver = ThreadedResolver(io_loop=self.io_loop)\n\n    def tearDown(self):\n        self.resolver.close()\n        super(ThreadedResolverTest, self).tearDown()\n\n\n@unittest.skipIf(futures is None, \"futures module not present\")\nclass ThreadedResolverImportTest(unittest.TestCase):\n    def test_import(self):\n        TIMEOUT = 5\n\n        # Test for a deadlock when importing a module that runs the\n        # ThreadedResolver at import-time. See resolve_test.py for\n        # full explanation.\n        command = [\n            sys.executable,\n            '-c',\n            'import tornado.test.resolve_test_helper']\n\n        start = time.time()\n        popen = Popen(command, preexec_fn=lambda: signal.alarm(TIMEOUT))\n        while time.time() - start < TIMEOUT:\n            return_code = popen.poll()\n            if return_code is not None:\n                self.assertEqual(0, return_code)\n                return  # Success.\n            time.sleep(0.05)\n\n        self.fail(\"import timed out\")\n\n\n@unittest.skipIf(pycares is None, \"pycares module not present\")\nclass CaresResolverTest(AsyncTestCase, _ResolverTestMixin):\n    def setUp(self):\n        super(CaresResolverTest, self).setUp()\n        self.resolver = CaresResolver(io_loop=self.io_loop)\n\n\n@unittest.skipIf(twisted is None, \"twisted module not present\")\n@unittest.skipIf(getattr(twisted, '__version__', '0.0') < \"12.1\", \"old version of twisted\")\nclass TwistedResolverTest(AsyncTestCase, _ResolverTestMixin):\n    def setUp(self):\n        super(TwistedResolverTest, self).setUp()\n        self.resolver = TwistedResolver(io_loop=self.io_loop)\n\n\nclass IsValidIPTest(unittest.TestCase):\n    def test_is_valid_ip(self):\n        self.assertTrue(is_valid_ip('127.0.0.1'))\n        self.assertTrue(is_valid_ip('4.4.4.4'))\n        self.assertTrue(is_valid_ip('::1'))\n        self.assertTrue(is_valid_ip('2620:0:1cfe:face:b00c::3'))\n        self.assertTrue(not is_valid_ip('www.google.com'))\n        self.assertTrue(not is_valid_ip('localhost'))\n        self.assertTrue(not is_valid_ip('4.4.4.4<'))\n        self.assertTrue(not is_valid_ip(' 127.0.0.1'))\n        self.assertTrue(not is_valid_ip(''))\n        self.assertTrue(not is_valid_ip(' '))\n        self.assertTrue(not is_valid_ip('\\n'))\n        self.assertTrue(not is_valid_ip('\\x00'))\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 718ms\nPrepared 1 package in 1.03s\nInstalled 1 package in 0.77ms\n + tornado==3.2.dev2 (from file:///home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_de39a398fb556c8c30b4c431b16974e0ca35e22d)\nResolved 29 packages in 13ms\nInstalled 29 packages in 73ms\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_de39a398fb556c8c30b4c431b16974e0ca35e22d\n..................\ncollected 18 items\n\n==================== short test summary info ====================\nPASSED r2e_tests.test_1::BlockingResolverTest::test_bad_host\nPASSED r2e_tests.test_1::BlockingResolverTest::test_future_interface\nPASSED r2e_tests.test_1::BlockingResolverTest::test_future_interface_bad_host\nPASSED r2e_tests.test_1::BlockingResolverTest::test_localhost\nPASSED r2e_tests.test_1::CaresResolverTest::test_bad_host\nPASSED r2e_tests.test_1::CaresResolverTest::test_future_interface\nPASSED r2e_tests.test_1::CaresResolverTest::test_future_interface_bad_host\nPASSED r2e_tests.test_1::CaresResolverTest::test_localhost\nPASSED r2e_tests.test_1::IsValidIPTest::test_is_valid_ip\nPASSED r2e_tests.test_1::ThreadedResolverImportTest::test_import\nPASSED r2e_tests.test_1::ThreadedResolverTest::test_bad_host\nPASSED r2e_tests.test_1::ThreadedResolverTest::test_future_interface\nPASSED r2e_tests.test_1::ThreadedResolverTest::test_future_interface_bad_host\nPASSED r2e_tests.test_1::ThreadedResolverTest::test_localhost\nPASSED r2e_tests.test_1::TwistedResolverTest::test_bad_host\nPASSED r2e_tests.test_1::TwistedResolverTest::test_future_interface\nPASSED r2e_tests.test_1::TwistedResolverTest::test_future_interface_bad_host\nPASSED r2e_tests.test_1::TwistedResolverTest::test_localhost\n=================== 18 passed in 0.22s ===================\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_de39a398fb556c8c30b4c431b16974e0ca35e22d\n..................\ncollected 18 items\n\n=================================== FAILURES ===================================\n__________ TwistedResolverTest.test_bad_host __________\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_de39a398fb556c8c30b4c431b16974e0ca35e22d/r2e_tests/test_1.py\", line 55, in test_bad_host\n    result = self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_de39a398fb556c8c30b4c431b16974e0ca35e22d/tornado/testing.py\", line 269, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_de39a398fb556c8c30b4c431b16974e0ca35e22d/tornado/testing.py\", line 205, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_de39a398fb556c8c30b4c431b16974e0ca35e22d/tornado/testing.py\", line 251, in timeout_func\n    raise self.failureException(\nAssertionError: Async operation timed out after 5 seconds\n\n=================================== ERRORS =====================================\n__________ TwistedResolverTest.test_future_interface_bad_host __________\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_de39a398fb556c8c30b4c431b16974e0ca35e22d/tornado/testing.py\", line 426, in wrapper\n    return self.io_loop.run_sync(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_de39a398fb556c8c30b4c431b16974e0ca35e22d/tornado/ioloop.py\", line 372, in run_sync\n    raise TimeoutError('Operation timed out after %s seconds' % timeout)\ntornado.ioloop.TimeoutError: Operation timed out after 5 seconds\n\n==================== short test summary info ====================\nPASSED r2e_tests.test_1::BlockingResolverTest::test_bad_host\nPASSED r2e_tests.test_1::BlockingResolverTest::test_future_interface\nPASSED r2e_tests.test_1::BlockingResolverTest::test_future_interface_bad_host\nPASSED r2e_tests.test_1::BlockingResolverTest::test_localhost\nPASSED r2e_tests.test_1::CaresResolverTest::test_bad_host\nPASSED r2e_tests.test_1::CaresResolverTest::test_future_interface\nPASSED r2e_tests.test_1::CaresResolverTest::test_future_interface_bad_host\nPASSED r2e_tests.test_1::CaresResolverTest::test_localhost\nPASSED r2e_tests.test_1::IsValidIPTest::test_is_valid_ip\nPASSED r2e_tests.test_1::ThreadedResolverImportTest::test_import\nPASSED r2e_tests.test_1::ThreadedResolverTest::test_bad_host\nPASSED r2e_tests.test_1::ThreadedResolverTest::test_future_interface\nPASSED r2e_tests.test_1::ThreadedResolverTest::test_future_interface_bad_host\nPASSED r2e_tests.test_1::ThreadedResolverTest::test_localhost\nFAILED r2e_tests.test_1::TwistedResolverTest::test_bad_host\nPASSED r2e_tests.test_1::TwistedResolverTest::test_future_interface\nERROR r2e_tests.test_1::TwistedResolverTest::test_future_interface_bad_host\nPASSED r2e_tests.test_1::TwistedResolverTest::test_localhost\n=================== 1 failed, 1 error, 16 passed in 10.20s ===================\n",
    "old_commit_res_stderr": "Unhandled error in Deferred:\n\nTraceback (most recent call last):\nFailure: twisted.names.error.DNSNameError: <Message id=48383 rCode=3 maxSize=0 flags=answer,recDes,recAv queries=[Query(b'doesntexist', 255, 1)] authority=[<RR name= type=SOA class=IN ttl=86394s auth=False>]>\n\nUnhandled error in Deferred:\n\nTraceback (most recent call last):\nFailure: twisted.names.error.DNSNameError: <Message id=32427 rCode=3 maxSize=0 flags=answer,recDes,recAv queries=[Query(b'doesntexist', 255, 1)] authority=[<RR name= type=SOA class=IN ttl=86399s auth=False>]>\n\n"
}
tornado/platform/twisted.py tornado/test/netutil_test.py
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ISSUE]

**Title: TwistedResolver Fails to Raise Exceptions for Invalid Hostnames, Causing Timeouts**

**Description:**

When attempting to resolve a hostname that does not exist, the `TwistedResolver` fails to properly handle the error. Instead of raising an exception, the resolver operation times out after 5 seconds. This prevents the application from gracefully handling the failure and can lead to unresponsive behavior.

**Example Code:**

```python
def handler(exc_typ, exc_val, exc_tb):
    stop(exc_val)
    return True  # Halt propagation.

with ExceptionStackContext(handler):
    resolver.resolve('doesntexist', 80, callback=stop)

result = wait()
```

**Expected Behavior:**

Resolving a nonexistent hostname should immediately raise an exception indicating that the host could not be found. This allows the application to handle the error appropriately without waiting for a timeout.

**Actual Behavior:**

The resolver operation does not raise an exception and instead times out after 5 seconds, leading to an `AssertionError` or `TimeoutError`. This behavior hinders proper error handling and can affect the stability of the application.

[/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/platform/twisted.py
# Author: Ovidiu Predescu
# Date: July 2011
#
# 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.

# Note:  This module's docs are not currently extracted automatically,
# so changes must be made manually to twisted.rst
# TODO: refactor doc build process to use an appropriate virtualenv
"""Bridges between the Twisted reactor and Tornado IOLoop.

This module lets you run applications and libraries written for
Twisted in a Tornado application.  It can be used in two modes,
depending on which library's underlying event loop you want to use.

This module has been tested with Twisted versions 11.0.0 and newer.

Twisted on Tornado
------------------

`TornadoReactor` implements the Twisted reactor interface on top of
the Tornado IOLoop.  To use it, simply call `install` at the beginning
of the application::

    import tornado.platform.twisted
    tornado.platform.twisted.install()
    from twisted.internet import reactor

When the app is ready to start, call `IOLoop.instance().start()`
instead of `reactor.run()`.

It is also possible to create a non-global reactor by calling
`tornado.platform.twisted.TornadoReactor(io_loop)`.  However, if
the `IOLoop` and reactor are to be short-lived (such as those used in
unit tests), additional cleanup may be required.  Specifically, it is
recommended to call::

    reactor.fireSystemEvent('shutdown')
    reactor.disconnectAll()

before closing the `IOLoop`.

Tornado on Twisted
------------------

`TwistedIOLoop` implements the Tornado IOLoop interface on top of the Twisted
reactor.  Recommended usage::

    from tornado.platform.twisted import TwistedIOLoop
    from twisted.internet import reactor
    TwistedIOLoop().install()
    # Set up your tornado application as usual using `IOLoop.instance`
    reactor.run()

`TwistedIOLoop` always uses the global Twisted reactor.
"""

from __future__ import absolute_import, division, print_function, with_statement

import datetime
import functools
import socket

import twisted.internet.abstract
from twisted.internet.posixbase import PosixReactorBase
from twisted.internet.interfaces import \
    IReactorFDSet, IDelayedCall, IReactorTime, IReadDescriptor, IWriteDescriptor
from twisted.python import failure, log
from twisted.internet import error
import twisted.names.cache
import twisted.names.client
import twisted.names.hosts
import twisted.names.resolve

from zope.interface import implementer

from tornado.escape import utf8
from tornado import gen
import tornado.ioloop
from tornado.log import app_log
from tornado.netutil import Resolver
from tornado.stack_context import NullContext, wrap
from tornado.ioloop import IOLoop


@implementer(IDelayedCall)
class TornadoDelayedCall(object):
    """DelayedCall object for Tornado."""
    def __init__(self, reactor, seconds, f, *args, **kw):
        self._reactor = reactor
        self._func = functools.partial(f, *args, **kw)
        self._time = self._reactor.seconds() + seconds
        self._timeout = self._reactor._io_loop.add_timeout(self._time,
                                                           self._called)
        self._active = True

    def _called(self):
        self._active = False
        self._reactor._removeDelayedCall(self)
        try:
            self._func()
        except:
            app_log.error("_called caught exception", exc_info=True)

    def getTime(self):
        return self._time

    def cancel(self):
        self._active = False
        self._reactor._io_loop.remove_timeout(self._timeout)
        self._reactor._removeDelayedCall(self)

    def delay(self, seconds):
        self._reactor._io_loop.remove_timeout(self._timeout)
        self._time += seconds
        self._timeout = self._reactor._io_loop.add_timeout(self._time,
                                                           self._called)

    def reset(self, seconds):
        self._reactor._io_loop.remove_timeout(self._timeout)
        self._time = self._reactor.seconds() + seconds
        self._timeout = self._reactor._io_loop.add_timeout(self._time,
                                                           self._called)

    def active(self):
        return self._active


@implementer(IReactorTime, IReactorFDSet)
class TornadoReactor(PosixReactorBase):
    """Twisted reactor built on the Tornado IOLoop.

    Since it is intented to be used in applications where the top-level
    event loop is ``io_loop.start()`` rather than ``reactor.run()``,
    it is implemented a little differently than other Twisted reactors.
    We override `mainLoop` instead of `doIteration` and must implement
    timed call functionality on top of `IOLoop.add_timeout` rather than
    using the implementation in `PosixReactorBase`.
    """
    def __init__(self, io_loop=None):
        if not io_loop:
            io_loop = tornado.ioloop.IOLoop.current()
        self._io_loop = io_loop
        self._readers = {}  # map of reader objects to fd
        self._writers = {}  # map of writer objects to fd
        self._fds = {}  # a map of fd to a (reader, writer) tuple
        self._delayedCalls = {}
        PosixReactorBase.__init__(self)
        self.addSystemEventTrigger('during', 'shutdown', self.crash)

        # IOLoop.start() bypasses some of the reactor initialization.
        # Fire off the necessary events if they weren't already triggered
        # by reactor.run().
        def start_if_necessary():
            if not self._started:
                self.fireSystemEvent('startup')
        self._io_loop.add_callback(start_if_necessary)

    # IReactorTime
    def seconds(self):
        return self._io_loop.time()

    def callLater(self, seconds, f, *args, **kw):
        dc = TornadoDelayedCall(self, seconds, f, *args, **kw)
        self._delayedCalls[dc] = True
        return dc

    def getDelayedCalls(self):
        return [x for x in self._delayedCalls if x._active]

    def _removeDelayedCall(self, dc):
        if dc in self._delayedCalls:
            del self._delayedCalls[dc]

    # IReactorThreads
    def callFromThread(self, f, *args, **kw):
        """See `twisted.internet.interfaces.IReactorThreads.callFromThread`"""
        assert callable(f), "%s is not callable" % f
        with NullContext():
            # This NullContext is mainly for an edge case when running
            # TwistedIOLoop on top of a TornadoReactor.
            # TwistedIOLoop.add_callback uses reactor.callFromThread and
            # should not pick up additional StackContexts along the way.
            self._io_loop.add_callback(f, *args, **kw)

    # We don't need the waker code from the super class, Tornado uses
    # its own waker.
    def installWaker(self):
        pass

    def wakeUp(self):
        pass

    # IReactorFDSet
    def _invoke_callback(self, fd, events):
        if fd not in self._fds:
            return
        (reader, writer) = self._fds[fd]
        if reader:
            err = None
            if reader.fileno() == -1:
                err = error.ConnectionLost()
            elif events & IOLoop.READ:
                err = log.callWithLogger(reader, reader.doRead)
            if err is None and events & IOLoop.ERROR:
                err = error.ConnectionLost()
            if err is not None:
                self.removeReader(reader)
                reader.readConnectionLost(failure.Failure(err))
        if writer:
            err = None
            if writer.fileno() == -1:
                err = error.ConnectionLost()
            elif events & IOLoop.WRITE:
                err = log.callWithLogger(writer, writer.doWrite)
            if err is None and events & IOLoop.ERROR:
                err = error.ConnectionLost()
            if err is not None:
                self.removeWriter(writer)
                writer.writeConnectionLost(failure.Failure(err))

    def addReader(self, reader):
        """Add a FileDescriptor for notification of data available to read."""
        if reader in self._readers:
            # Don't add the reader if it's already there
            return
        fd = reader.fileno()
        self._readers[reader] = fd
        if fd in self._fds:
            (_, writer) = self._fds[fd]
            self._fds[fd] = (reader, writer)
            if writer:
                # We already registered this fd for write events,
                # update it for read events as well.
                self._io_loop.update_handler(fd, IOLoop.READ | IOLoop.WRITE)
        else:
            with NullContext():
                self._fds[fd] = (reader, None)
                self._io_loop.add_handler(fd, self._invoke_callback,
                                          IOLoop.READ)

    def addWriter(self, writer):
        """Add a FileDescriptor for notification of data available to write."""
        if writer in self._writers:
            return
        fd = writer.fileno()
        self._writers[writer] = fd
        if fd in self._fds:
            (reader, _) = self._fds[fd]
            self._fds[fd] = (reader, writer)
            if reader:
                # We already registered this fd for read events,
                # update it for write events as well.
                self._io_loop.update_handler(fd, IOLoop.READ | IOLoop.WRITE)
        else:
            with NullContext():
                self._fds[fd] = (None, writer)
                self._io_loop.add_handler(fd, self._invoke_callback,
                                          IOLoop.WRITE)

    def removeReader(self, reader):
        """Remove a Selectable for notification of data available to read."""
        if reader in self._readers:
            fd = self._readers.pop(reader)
            (_, writer) = self._fds[fd]
            if writer:
                # We have a writer so we need to update the IOLoop for
                # write events only.
                self._fds[fd] = (None, writer)
                self._io_loop.update_handler(fd, IOLoop.WRITE)
            else:
                # Since we have no writer registered, we remove the
                # entry from _fds and unregister the handler from the
                # IOLoop
                del self._fds[fd]
                self._io_loop.remove_handler(fd)

    def removeWriter(self, writer):
        """Remove a Selectable for notification of data available to write."""
        if writer in self._writers:
            fd = self._writers.pop(writer)
            (reader, _) = self._fds[fd]
            if reader:
                # We have a reader so we need to update the IOLoop for
                # read events only.
                self._fds[fd] = (reader, None)
                self._io_loop.update_handler(fd, IOLoop.READ)
            else:
                # Since we have no reader registered, we remove the
                # entry from the _fds and unregister the handler from
                # the IOLoop.
                del self._fds[fd]
                self._io_loop.remove_handler(fd)

    def removeAll(self):
        return self._removeAll(self._readers, self._writers)

    def getReaders(self):
        return self._readers.keys()

    def getWriters(self):
        return self._writers.keys()

    # The following functions are mainly used in twisted-style test cases;
    # it is expected that most users of the TornadoReactor will call
    # IOLoop.start() instead of Reactor.run().
    def stop(self):
        PosixReactorBase.stop(self)
        fire_shutdown = functools.partial(self.fireSystemEvent, "shutdown")
        self._io_loop.add_callback(fire_shutdown)

    def crash(self):
        PosixReactorBase.crash(self)
        self._io_loop.stop()

    def doIteration(self, delay):
        raise NotImplementedError("doIteration")

    def mainLoop(self):
        self._io_loop.start()


class _TestReactor(TornadoReactor):
    """Subclass of TornadoReactor for use in unittests.

    This can't go in the test.py file because of import-order dependencies
    with the Twisted reactor test builder.
    """
    def __init__(self):
        # always use a new ioloop
        super(_TestReactor, self).__init__(IOLoop())

    def listenTCP(self, port, factory, backlog=50, interface=''):
        # default to localhost to avoid firewall prompts on the mac
        if not interface:
            interface = '127.0.0.1'
        return super(_TestReactor, self).listenTCP(
            port, factory, backlog=backlog, interface=interface)

    def listenUDP(self, port, protocol, interface='', maxPacketSize=8192):
        if not interface:
            interface = '127.0.0.1'
        return super(_TestReactor, self).listenUDP(
            port, protocol, interface=interface, maxPacketSize=maxPacketSize)


def install(io_loop=None):
    """Install this package as the default Twisted reactor."""
    if not io_loop:
        io_loop = tornado.ioloop.IOLoop.current()
    reactor = TornadoReactor(io_loop)
    from twisted.internet.main import installReactor
    installReactor(reactor)
    return reactor


@implementer(IReadDescriptor, IWriteDescriptor)
class _FD(object):
    def __init__(self, fd, handler):
        self.fd = fd
        self.handler = handler
        self.reading = False
        self.writing = False
        self.lost = False

    def fileno(self):
        return self.fd

    def doRead(self):
        if not self.lost:
            self.handler(self.fd, tornado.ioloop.IOLoop.READ)

    def doWrite(self):
        if not self.lost:
            self.handler(self.fd, tornado.ioloop.IOLoop.WRITE)

    def connectionLost(self, reason):
        if not self.lost:
            self.handler(self.fd, tornado.ioloop.IOLoop.ERROR)
            self.lost = True

    def logPrefix(self):
        return ''


class TwistedIOLoop(tornado.ioloop.IOLoop):
    """IOLoop implementation that runs on Twisted.

    Uses the global Twisted reactor by default.  To create multiple
    `TwistedIOLoops` in the same process, you must pass a unique reactor
    when constructing each one.

    Not compatible with `tornado.process.Subprocess.set_exit_callback`
    because the ``SIGCHLD`` handlers used by Tornado and Twisted conflict
    with each other.
    """
    def initialize(self, reactor=None):
        if reactor is None:
            import twisted.internet.reactor
            reactor = twisted.internet.reactor
        self.reactor = reactor
        self.fds = {}
        self.reactor.callWhenRunning(self.make_current)

    def close(self, all_fds=False):
        self.reactor.removeAll()
        for c in self.reactor.getDelayedCalls():
            c.cancel()

    def add_handler(self, fd, handler, events):
        if fd in self.fds:
            raise ValueError('fd %d added twice' % fd)
        self.fds[fd] = _FD(fd, wrap(handler))
        if events & tornado.ioloop.IOLoop.READ:
            self.fds[fd].reading = True
            self.reactor.addReader(self.fds[fd])
        if events & tornado.ioloop.IOLoop.WRITE:
            self.fds[fd].writing = True
            self.reactor.addWriter(self.fds[fd])

    def update_handler(self, fd, events):
        if events & tornado.ioloop.IOLoop.READ:
            if not self.fds[fd].reading:
                self.fds[fd].reading = True
                self.reactor.addReader(self.fds[fd])
        else:
            if self.fds[fd].reading:
                self.fds[fd].reading = False
                self.reactor.removeReader(self.fds[fd])
        if events & tornado.ioloop.IOLoop.WRITE:
            if not self.fds[fd].writing:
                self.fds[fd].writing = True
                self.reactor.addWriter(self.fds[fd])
        else:
            if self.fds[fd].writing:
                self.fds[fd].writing = False
                self.reactor.removeWriter(self.fds[fd])

    def remove_handler(self, fd):
        if fd not in self.fds:
            return
        self.fds[fd].lost = True
        if self.fds[fd].reading:
            self.reactor.removeReader(self.fds[fd])
        if self.fds[fd].writing:
            self.reactor.removeWriter(self.fds[fd])
        del self.fds[fd]

    def start(self):
        self.reactor.run()

    def stop(self):
        self.reactor.crash()

    def _run_callback(self, callback, *args, **kwargs):
        try:
            callback(*args, **kwargs)
        except Exception:
            self.handle_callback_exception(callback)

    def add_timeout(self, deadline, callback):
        if isinstance(deadline, (int, long, float)):
            delay = max(deadline - self.time(), 0)
        elif isinstance(deadline, datetime.timedelta):
            delay = tornado.ioloop._Timeout.timedelta_to_seconds(deadline)
        else:
            raise TypeError("Unsupported deadline %r")
        return self.reactor.callLater(delay, self._run_callback, wrap(callback))

    def remove_timeout(self, timeout):
        if timeout.active():
            timeout.cancel()

    def add_callback(self, callback, *args, **kwargs):
        self.reactor.callFromThread(self._run_callback,
                                    wrap(callback), *args, **kwargs)

    def add_callback_from_signal(self, callback, *args, **kwargs):
        self.add_callback(callback, *args, **kwargs)


class TwistedResolver(Resolver):
    """Twisted-based asynchronous resolver.

    This is a non-blocking and non-threaded resolver.  It is
    recommended only when threads cannot be used, since it has
    limitations compared to the standard ``getaddrinfo``-based
    `~tornado.netutil.Resolver` and
    `~tornado.netutil.ThreadedResolver`.  Specifically, it returns at
    most one result, and arguments other than ``host`` and ``family``
    are ignored.  It may fail to resolve when ``family`` is not
    ``socket.AF_UNSPEC``.

    Requires Twisted 12.1 or newer.
    """
    def initialize(self, io_loop=None):
        self.io_loop = io_loop or IOLoop.current()
        # partial copy of twisted.names.client.createResolver, which doesn't
        # allow for a reactor to be passed in.
        self.reactor = tornado.platform.twisted.TornadoReactor(io_loop)

        host_resolver = twisted.names.hosts.Resolver('/etc/hosts')
        cache_resolver = twisted.names.cache.CacheResolver(reactor=self.reactor)
        real_resolver = twisted.names.client.Resolver('/etc/resolv.conf',
                                                      reactor=self.reactor)
        self.resolver = twisted.names.resolve.ResolverChain(
            [host_resolver, cache_resolver, real_resolver])

    @gen.coroutine
    def resolve(self, host, port, family=0):
        # getHostByName doesn't accept IP addresses, so if the input
        # looks like an IP address just return it immediately.
        if twisted.internet.abstract.isIPAddress(host):
            resolved = host
            resolved_family = socket.AF_INET
        elif twisted.internet.abstract.isIPv6Address(host):
            resolved = host
            resolved_family = socket.AF_INET6
        else:
            deferred = self.resolver.getHostByName(utf8(host))
            resolved = yield gen.Task(deferred.addCallback)
            if twisted.internet.abstract.isIPAddress(resolved):
                resolved_family = socket.AF_INET
            elif twisted.internet.abstract.isIPv6Address(resolved):
                resolved_family = socket.AF_INET6
            else:
                resolved_family = socket.AF_UNSPEC
        if family != socket.AF_UNSPEC and family != resolved_family:
            raise Exception('Requested socket family %d but got %d' %
                            (family, resolved_family))
        result = [
            (resolved_family, (resolved, port)),
        ]
        raise gen.Return(result)

```
--- 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: TwistedResolver Fails to Raise Exceptions for Invalid Hostnames, Causing Timeouts**

**Description:**

When attempting to resolve a hostname that does not exist, the `TwistedResolver` fails to properly handle the error. Instead of raising an exception, the resolver operation times out after 5 seconds. This prevents the application from gracefully handling the failure and can lead to unresponsive behavior.

**Example Code:**

```python
def handler(exc_typ, exc_val, exc_tb):
    stop(exc_val)
    return True  # Halt propagation.

with ExceptionStackContext(handler):
    resolver.resolve('doesntexist', 80, callback=stop)

result = wait()
```

**Expected Behavior:**

Resolving a nonexistent hostname should immediately raise an exception indicating that the host could not be found. This allows the application to handle the error appropriately without waiting for a timeout.

**Actual Behavior:**

The resolver operation does not raise an exception and instead times out after 5 seconds, leading to an `AssertionError` or `TimeoutError`. This behavior hinders proper error handling and can affect the stability of the application.

[/ISSUE]
{
    "BlockingResolverTest.test_bad_host": "PASSED",
    "BlockingResolverTest.test_future_interface": "PASSED",
    "BlockingResolverTest.test_future_interface_bad_host": "PASSED",
    "BlockingResolverTest.test_localhost": "PASSED",
    "CaresResolverTest.test_bad_host": "PASSED",
    "CaresResolverTest.test_future_interface": "FAILED",
    "CaresResolverTest.test_future_interface_bad_host": "PASSED",
    "CaresResolverTest.test_localhost": "FAILED",
    "IsValidIPTest.test_is_valid_ip": "PASSED",
    "ThreadedResolverImportTest.test_import": "PASSED",
    "ThreadedResolverTest.test_bad_host": "PASSED",
    "ThreadedResolverTest.test_future_interface": "PASSED",
    "ThreadedResolverTest.test_future_interface_bad_host": "PASSED",
    "ThreadedResolverTest.test_localhost": "PASSED",
    "TwistedResolverTest.test_bad_host": "PASSED",
    "TwistedResolverTest.test_future_interface": "PASSED",
    "TwistedResolverTest.test_future_interface_bad_host": "PASSED",
    "TwistedResolverTest.test_localhost": "PASSED"
}
diff --git a/tornado/platform/twisted.py b/tornado/platform/twisted.py
index c0ee5957..86ef71b9 100644
--- a/tornado/platform/twisted.py
+++ b/tornado/platform/twisted.py
@@ -527,8 +527,10 @@ class TwistedResolver(Resolver):
             resolved_family = socket.AF_INET6
         else:
             deferred = self.resolver.getHostByName(utf8(host))
-            resolved = yield gen.Task(deferred.addCallback)
-            if twisted.internet.abstract.isIPAddress(resolved):
+            resolved = yield gen.Task(deferred.addBoth)
+            if isinstance(resolved, failure.Failure):
+                resolved.raiseException()
+            elif twisted.internet.abstract.isIPAddress(resolved):
                 resolved_family = socket.AF_INET
             elif twisted.internet.abstract.isIPv6Address(resolved):
                 resolved_family = socket.AF_INET6

{"tornado/platform/twisted.py": "# Author: Ovidiu Predescu\n# Date: July 2011\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# Note:  This module's docs are not currently extracted automatically,\n# so changes must be made manually to twisted.rst\n# TODO: refactor doc build process to use an appropriate virtualenv\n\"\"\"Bridges between the Twisted reactor and Tornado IOLoop.\n\nThis module lets you run applications and libraries written for\nTwisted in a Tornado application.  It can be used in two modes,\ndepending on which library's underlying event loop you want to use.\n\nThis module has been tested with Twisted versions 11.0.0 and newer.\n\nTwisted on Tornado\n------------------\n\n`TornadoReactor` implements the Twisted reactor interface on top of\nthe Tornado IOLoop.  To use it, simply call `install` at the beginning\nof the application::\n\n    import tornado.platform.twisted\n    tornado.platform.twisted.install()\n    from twisted.internet import reactor\n\nWhen the app is ready to start, call `IOLoop.instance().start()`\ninstead of `reactor.run()`.\n\nIt is also possible to create a non-global reactor by calling\n`tornado.platform.twisted.TornadoReactor(io_loop)`.  However, if\nthe `IOLoop` and reactor are to be short-lived (such as those used in\nunit tests), additional cleanup may be required.  Specifically, it is\nrecommended to call::\n\n    reactor.fireSystemEvent('shutdown')\n    reactor.disconnectAll()\n\nbefore closing the `IOLoop`.\n\nTornado on Twisted\n------------------\n\n`TwistedIOLoop` implements the Tornado IOLoop interface on top of the Twisted\nreactor.  Recommended usage::\n\n    from tornado.platform.twisted import TwistedIOLoop\n    from twisted.internet import reactor\n    TwistedIOLoop().install()\n    # Set up your tornado application as usual using `IOLoop.instance`\n    reactor.run()\n\n`TwistedIOLoop` always uses the global Twisted reactor.\n\"\"\"\n\nfrom __future__ import absolute_import, division, print_function, with_statement\n\nimport datetime\nimport functools\nimport socket\n\nimport twisted.internet.abstract\nfrom twisted.internet.posixbase import PosixReactorBase\nfrom twisted.internet.interfaces import \\\n    IReactorFDSet, IDelayedCall, IReactorTime, IReadDescriptor, IWriteDescriptor\nfrom twisted.python import failure, log\nfrom twisted.internet import error\nimport twisted.names.cache\nimport twisted.names.client\nimport twisted.names.hosts\nimport twisted.names.resolve\n\nfrom zope.interface import implementer\n\nfrom tornado.escape import utf8\nfrom tornado import gen\nimport tornado.ioloop\nfrom tornado.log import app_log\nfrom tornado.netutil import Resolver\nfrom tornado.stack_context import NullContext, wrap\nfrom tornado.ioloop import IOLoop\n\n\n@implementer(IDelayedCall)\nclass TornadoDelayedCall(object):\n    \"\"\"DelayedCall object for Tornado.\"\"\"\n    def __init__(self, reactor, seconds, f, *args, **kw):\n        self._reactor = reactor\n        self._func = functools.partial(f, *args, **kw)\n        self._time = self._reactor.seconds() + seconds\n        self._timeout = self._reactor._io_loop.add_timeout(self._time,\n                                                           self._called)\n        self._active = True\n\n    def _called(self):\n        self._active = False\n        self._reactor._removeDelayedCall(self)\n        try:\n            self._func()\n        except:\n            app_log.error(\"_called caught exception\", exc_info=True)\n\n    def getTime(self):\n        return self._time\n\n    def cancel(self):\n        self._active = False\n        self._reactor._io_loop.remove_timeout(self._timeout)\n        self._reactor._removeDelayedCall(self)\n\n    def delay(self, seconds):\n        self._reactor._io_loop.remove_timeout(self._timeout)\n        self._time += seconds\n        self._timeout = self._reactor._io_loop.add_timeout(self._time,\n                                                           self._called)\n\n    def reset(self, seconds):\n        self._reactor._io_loop.remove_timeout(self._timeout)\n        self._time = self._reactor.seconds() + seconds\n        self._timeout = self._reactor._io_loop.add_timeout(self._time,\n                                                           self._called)\n\n    def active(self):\n        return self._active\n\n\n@implementer(IReactorTime, IReactorFDSet)\nclass TornadoReactor(PosixReactorBase):\n    \"\"\"Twisted reactor built on the Tornado IOLoop.\n\n    Since it is intented to be used in applications where the top-level\n    event loop is ``io_loop.start()`` rather than ``reactor.run()``,\n    it is implemented a little differently than other Twisted reactors.\n    We override `mainLoop` instead of `doIteration` and must implement\n    timed call functionality on top of `IOLoop.add_timeout` rather than\n    using the implementation in `PosixReactorBase`.\n    \"\"\"\n    def __init__(self, io_loop=None):\n        if not io_loop:\n            io_loop = tornado.ioloop.IOLoop.current()\n        self._io_loop = io_loop\n        self._readers = {}  # map of reader objects to fd\n        self._writers = {}  # map of writer objects to fd\n        self._fds = {}  # a map of fd to a (reader, writer) tuple\n        self._delayedCalls = {}\n        PosixReactorBase.__init__(self)\n        self.addSystemEventTrigger('during', 'shutdown', self.crash)\n\n        # IOLoop.start() bypasses some of the reactor initialization.\n        # Fire off the necessary events if they weren't already triggered\n        # by reactor.run().\n        def start_if_necessary():\n            if not self._started:\n                self.fireSystemEvent('startup')\n        self._io_loop.add_callback(start_if_necessary)\n\n    # IReactorTime\n    def seconds(self):\n        return self._io_loop.time()\n\n    def callLater(self, seconds, f, *args, **kw):\n        dc = TornadoDelayedCall(self, seconds, f, *args, **kw)\n        self._delayedCalls[dc] = True\n        return dc\n\n    def getDelayedCalls(self):\n        return [x for x in self._delayedCalls if x._active]\n\n    def _removeDelayedCall(self, dc):\n        if dc in self._delayedCalls:\n            del self._delayedCalls[dc]\n\n    # IReactorThreads\n    def callFromThread(self, f, *args, **kw):\n        \"\"\"See `twisted.internet.interfaces.IReactorThreads.callFromThread`\"\"\"\n        assert callable(f), \"%s is not callable\" % f\n        with NullContext():\n            # This NullContext is mainly for an edge case when running\n            # TwistedIOLoop on top of a TornadoReactor.\n            # TwistedIOLoop.add_callback uses reactor.callFromThread and\n            # should not pick up additional StackContexts along the way.\n            self._io_loop.add_callback(f, *args, **kw)\n\n    # We don't need the waker code from the super class, Tornado uses\n    # its own waker.\n    def installWaker(self):\n        pass\n\n    def wakeUp(self):\n        pass\n\n    # IReactorFDSet\n    def _invoke_callback(self, fd, events):\n        if fd not in self._fds:\n            return\n        (reader, writer) = self._fds[fd]\n        if reader:\n            err = None\n            if reader.fileno() == -1:\n                err = error.ConnectionLost()\n            elif events & IOLoop.READ:\n                err = log.callWithLogger(reader, reader.doRead)\n            if err is None and events & IOLoop.ERROR:\n                err = error.ConnectionLost()\n            if err is not None:\n                self.removeReader(reader)\n                reader.readConnectionLost(failure.Failure(err))\n        if writer:\n            err = None\n            if writer.fileno() == -1:\n                err = error.ConnectionLost()\n            elif events & IOLoop.WRITE:\n                err = log.callWithLogger(writer, writer.doWrite)\n            if err is None and events & IOLoop.ERROR:\n                err = error.ConnectionLost()\n            if err is not None:\n                self.removeWriter(writer)\n                writer.writeConnectionLost(failure.Failure(err))\n\n    def addReader(self, reader):\n        \"\"\"Add a FileDescriptor for notification of data available to read.\"\"\"\n        if reader in self._readers:\n            # Don't add the reader if it's already there\n            return\n        fd = reader.fileno()\n        self._readers[reader] = fd\n        if fd in self._fds:\n            (_, writer) = self._fds[fd]\n            self._fds[fd] = (reader, writer)\n            if writer:\n                # We already registered this fd for write events,\n                # update it for read events as well.\n                self._io_loop.update_handler(fd, IOLoop.READ | IOLoop.WRITE)\n        else:\n            with NullContext():\n                self._fds[fd] = (reader, None)\n                self._io_loop.add_handler(fd, self._invoke_callback,\n                                          IOLoop.READ)\n\n    def addWriter(self, writer):\n        \"\"\"Add a FileDescriptor for notification of data available to write.\"\"\"\n        if writer in self._writers:\n            return\n        fd = writer.fileno()\n        self._writers[writer] = fd\n        if fd in self._fds:\n            (reader, _) = self._fds[fd]\n            self._fds[fd] = (reader, writer)\n            if reader:\n                # We already registered this fd for read events,\n                # update it for write events as well.\n                self._io_loop.update_handler(fd, IOLoop.READ | IOLoop.WRITE)\n        else:\n            with NullContext():\n                self._fds[fd] = (None, writer)\n                self._io_loop.add_handler(fd, self._invoke_callback,\n                                          IOLoop.WRITE)\n\n    def removeReader(self, reader):\n        \"\"\"Remove a Selectable for notification of data available to read.\"\"\"\n        if reader in self._readers:\n            fd = self._readers.pop(reader)\n            (_, writer) = self._fds[fd]\n            if writer:\n                # We have a writer so we need to update the IOLoop for\n                # write events only.\n                self._fds[fd] = (None, writer)\n                self._io_loop.update_handler(fd, IOLoop.WRITE)\n            else:\n                # Since we have no writer registered, we remove the\n                # entry from _fds and unregister the handler from the\n                # IOLoop\n                del self._fds[fd]\n                self._io_loop.remove_handler(fd)\n\n    def removeWriter(self, writer):\n        \"\"\"Remove a Selectable for notification of data available to write.\"\"\"\n        if writer in self._writers:\n            fd = self._writers.pop(writer)\n            (reader, _) = self._fds[fd]\n            if reader:\n                # We have a reader so we need to update the IOLoop for\n                # read events only.\n                self._fds[fd] = (reader, None)\n                self._io_loop.update_handler(fd, IOLoop.READ)\n            else:\n                # Since we have no reader registered, we remove the\n                # entry from the _fds and unregister the handler from\n                # the IOLoop.\n                del self._fds[fd]\n                self._io_loop.remove_handler(fd)\n\n    def removeAll(self):\n        return self._removeAll(self._readers, self._writers)\n\n    def getReaders(self):\n        return self._readers.keys()\n\n    def getWriters(self):\n        return self._writers.keys()\n\n    # The following functions are mainly used in twisted-style test cases;\n    # it is expected that most users of the TornadoReactor will call\n    # IOLoop.start() instead of Reactor.run().\n    def stop(self):\n        PosixReactorBase.stop(self)\n        fire_shutdown = functools.partial(self.fireSystemEvent, \"shutdown\")\n        self._io_loop.add_callback(fire_shutdown)\n\n    def crash(self):\n        PosixReactorBase.crash(self)\n        self._io_loop.stop()\n\n    def doIteration(self, delay):\n        raise NotImplementedError(\"doIteration\")\n\n    def mainLoop(self):\n        self._io_loop.start()\n\n\nclass _TestReactor(TornadoReactor):\n    \"\"\"Subclass of TornadoReactor for use in unittests.\n\n    This can't go in the test.py file because of import-order dependencies\n    with the Twisted reactor test builder.\n    \"\"\"\n    def __init__(self):\n        # always use a new ioloop\n        super(_TestReactor, self).__init__(IOLoop())\n\n    def listenTCP(self, port, factory, backlog=50, interface=''):\n        # default to localhost to avoid firewall prompts on the mac\n        if not interface:\n            interface = '127.0.0.1'\n        return super(_TestReactor, self).listenTCP(\n            port, factory, backlog=backlog, interface=interface)\n\n    def listenUDP(self, port, protocol, interface='', maxPacketSize=8192):\n        if not interface:\n            interface = '127.0.0.1'\n        return super(_TestReactor, self).listenUDP(\n            port, protocol, interface=interface, maxPacketSize=maxPacketSize)\n\n\ndef install(io_loop=None):\n    \"\"\"Install this package as the default Twisted reactor.\"\"\"\n    if not io_loop:\n        io_loop = tornado.ioloop.IOLoop.current()\n    reactor = TornadoReactor(io_loop)\n    from twisted.internet.main import installReactor\n    installReactor(reactor)\n    return reactor\n\n\n@implementer(IReadDescriptor, IWriteDescriptor)\nclass _FD(object):\n    def __init__(self, fd, handler):\n        self.fd = fd\n        self.handler = handler\n        self.reading = False\n        self.writing = False\n        self.lost = False\n\n    def fileno(self):\n        return self.fd\n\n    def doRead(self):\n        if not self.lost:\n            self.handler(self.fd, tornado.ioloop.IOLoop.READ)\n\n    def doWrite(self):\n        if not self.lost:\n            self.handler(self.fd, tornado.ioloop.IOLoop.WRITE)\n\n    def connectionLost(self, reason):\n        if not self.lost:\n            self.handler(self.fd, tornado.ioloop.IOLoop.ERROR)\n            self.lost = True\n\n    def logPrefix(self):\n        return ''\n\n\nclass TwistedIOLoop(tornado.ioloop.IOLoop):\n    \"\"\"IOLoop implementation that runs on Twisted.\n\n    Uses the global Twisted reactor by default.  To create multiple\n    `TwistedIOLoops` in the same process, you must pass a unique reactor\n    when constructing each one.\n\n    Not compatible with `tornado.process.Subprocess.set_exit_callback`\n    because the ``SIGCHLD`` handlers used by Tornado and Twisted conflict\n    with each other.\n    \"\"\"\n    def initialize(self, reactor=None):\n        if reactor is None:\n            import twisted.internet.reactor\n            reactor = twisted.internet.reactor\n        self.reactor = reactor\n        self.fds = {}\n        self.reactor.callWhenRunning(self.make_current)\n\n    def close(self, all_fds=False):\n        self.reactor.removeAll()\n        for c in self.reactor.getDelayedCalls():\n            c.cancel()\n\n    def add_handler(self, fd, handler, events):\n        if fd in self.fds:\n            raise ValueError('fd %d added twice' % fd)\n        self.fds[fd] = _FD(fd, wrap(handler))\n        if events & tornado.ioloop.IOLoop.READ:\n            self.fds[fd].reading = True\n            self.reactor.addReader(self.fds[fd])\n        if events & tornado.ioloop.IOLoop.WRITE:\n            self.fds[fd].writing = True\n            self.reactor.addWriter(self.fds[fd])\n\n    def update_handler(self, fd, events):\n        if events & tornado.ioloop.IOLoop.READ:\n            if not self.fds[fd].reading:\n                self.fds[fd].reading = True\n                self.reactor.addReader(self.fds[fd])\n        else:\n            if self.fds[fd].reading:\n                self.fds[fd].reading = False\n                self.reactor.removeReader(self.fds[fd])\n        if events & tornado.ioloop.IOLoop.WRITE:\n            if not self.fds[fd].writing:\n                self.fds[fd].writing = True\n                self.reactor.addWriter(self.fds[fd])\n        else:\n            if self.fds[fd].writing:\n                self.fds[fd].writing = False\n                self.reactor.removeWriter(self.fds[fd])\n\n    def remove_handler(self, fd):\n        if fd not in self.fds:\n            return\n        self.fds[fd].lost = True\n        if self.fds[fd].reading:\n            self.reactor.removeReader(self.fds[fd])\n        if self.fds[fd].writing:\n            self.reactor.removeWriter(self.fds[fd])\n        del self.fds[fd]\n\n    def start(self):\n        self.reactor.run()\n\n    def stop(self):\n        self.reactor.crash()\n\n    def _run_callback(self, callback, *args, **kwargs):\n        try:\n            callback(*args, **kwargs)\n        except Exception:\n            self.handle_callback_exception(callback)\n\n    def add_timeout(self, deadline, callback):\n        if isinstance(deadline, (int, long, float)):\n            delay = max(deadline - self.time(), 0)\n        elif isinstance(deadline, datetime.timedelta):\n            delay = tornado.ioloop._Timeout.timedelta_to_seconds(deadline)\n        else:\n            raise TypeError(\"Unsupported deadline %r\")\n        return self.reactor.callLater(delay, self._run_callback, wrap(callback))\n\n    def remove_timeout(self, timeout):\n        if timeout.active():\n            timeout.cancel()\n\n    def add_callback(self, callback, *args, **kwargs):\n        self.reactor.callFromThread(self._run_callback,\n                                    wrap(callback), *args, **kwargs)\n\n    def add_callback_from_signal(self, callback, *args, **kwargs):\n        self.add_callback(callback, *args, **kwargs)\n\n\nclass TwistedResolver(Resolver):\n    \"\"\"Twisted-based asynchronous resolver.\n\n    This is a non-blocking and non-threaded resolver.  It is\n    recommended only when threads cannot be used, since it has\n    limitations compared to the standard ``getaddrinfo``-based\n    `~tornado.netutil.Resolver` and\n    `~tornado.netutil.ThreadedResolver`.  Specifically, it returns at\n    most one result, and arguments other than ``host`` and ``family``\n    are ignored.  It may fail to resolve when ``family`` is not\n    ``socket.AF_UNSPEC``.\n\n    Requires Twisted 12.1 or newer.\n    \"\"\"\n    def initialize(self, io_loop=None):\n        self.io_loop = io_loop or IOLoop.current()\n        # partial copy of twisted.names.client.createResolver, which doesn't\n        # allow for a reactor to be passed in.\n        self.reactor = tornado.platform.twisted.TornadoReactor(io_loop)\n\n        host_resolver = twisted.names.hosts.Resolver('/etc/hosts')\n        cache_resolver = twisted.names.cache.CacheResolver(reactor=self.reactor)\n        real_resolver = twisted.names.client.Resolver('/etc/resolv.conf',\n                                                      reactor=self.reactor)\n        self.resolver = twisted.names.resolve.ResolverChain(\n            [host_resolver, cache_resolver, real_resolver])\n\n    @gen.coroutine\n    def resolve(self, host, port, family=0):\n        # getHostByName doesn't accept IP addresses, so if the input\n        # looks like an IP address just return it immediately.\n        if twisted.internet.abstract.isIPAddress(host):\n            resolved = host\n            resolved_family = socket.AF_INET\n        elif twisted.internet.abstract.isIPv6Address(host):\n            resolved = host\n            resolved_family = socket.AF_INET6\n        else:\n            deferred = self.resolver.getHostByName(utf8(host))\n            resolved = yield gen.Task(deferred.addCallback)\n            if twisted.internet.abstract.isIPAddress(resolved):\n                resolved_family = socket.AF_INET\n            elif twisted.internet.abstract.isIPv6Address(resolved):\n                resolved_family = socket.AF_INET6\n            else:\n                resolved_family = socket.AF_UNSPEC\n        if family != socket.AF_UNSPEC and family != resolved_family:\n            raise Exception('Requested socket family %d but got %d' %\n                            (family, resolved_family))\n        result = [\n            (resolved_family, (resolved, port)),\n        ]\n        raise gen.Return(result)\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: TwistedResolver Fails to Raise Exceptions for Invalid Hostnames, Causing Timeouts**

**Description:**

When attempting to resolve a hostname that does not exist, the `TwistedResolver` fails to properly handle the error. Instead of raising an exception, the resolver operation times out after 5 seconds. This prevents the application from gracefully handling the failure and can lead to unresponsive behavior.

**Example Code:**

```python
def handler(exc_typ, exc_val, exc_tb):
    stop(exc_val)
    return True  # Halt propagation.

with ExceptionStackContext(handler):
    resolver.resolve('doesntexist', 80, callback=stop)

result = wait()
```

**Expected Behavior:**

Resolving a nonexistent hostname should immediately raise an exception indicating that the host could not be found. This allows the application to handle the error appropriately without waiting for a timeout.

**Actual Behavior:**

The resolver operation does not raise an exception and instead times out after 5 seconds, leading to an `AssertionError` or `TimeoutError`. This behavior hinders proper error handling and can affect the stability of the application.

[/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/platform/twisted.py
# Author: Ovidiu Predescu
# Date: July 2011
#
# 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.

# Note:  This module's docs are not currently extracted automatically,
# so changes must be made manually to twisted.rst
# TODO: refactor doc build process to use an appropriate virtualenv
"""Bridges between the Twisted reactor and Tornado IOLoop.

This module lets you run applications and libraries written for
Twisted in a Tornado application.  It can be used in two modes,
depending on which library's underlying event loop you want to use.

This module has been tested with Twisted versions 11.0.0 and newer.

Twisted on Tornado
------------------

`TornadoReactor` implements the Twisted reactor interface on top of
the Tornado IOLoop.  To use it, simply call `install` at the beginning
of the application::

    import tornado.platform.twisted
    tornado.platform.twisted.install()
    from twisted.internet import reactor

When the app is ready to start, call `IOLoop.instance().start()`
instead of `reactor.run()`.

It is also possible to create a non-global reactor by calling
`tornado.platform.twisted.TornadoReactor(io_loop)`.  However, if
the `IOLoop` and reactor are to be short-lived (such as those used in
unit tests), additional cleanup may be required.  Specifically, it is
recommended to call::

    reactor.fireSystemEvent('shutdown')
    reactor.disconnectAll()

before closing the `IOLoop`.

Tornado on Twisted
------------------

`TwistedIOLoop` implements the Tornado IOLoop interface on top of the Twisted
reactor.  Recommended usage::

    from tornado.platform.twisted import TwistedIOLoop
    from twisted.internet import reactor
    TwistedIOLoop().install()
    # Set up your tornado application as usual using `IOLoop.instance`
    reactor.run()

`TwistedIOLoop` always uses the global Twisted reactor.
"""

from __future__ import absolute_import, division, print_function, with_statement

import datetime
import functools
import socket

import twisted.internet.abstract
from twisted.internet.posixbase import PosixReactorBase
from twisted.internet.interfaces import \
    IReactorFDSet, IDelayedCall, IReactorTime, IReadDescriptor, IWriteDescriptor
from twisted.python import failure, log
from twisted.internet import error
import twisted.names.cache
import twisted.names.client
import twisted.names.hosts
import twisted.names.resolve

from zope.interface import implementer

from tornado.escape import utf8
from tornado import gen
import tornado.ioloop
from tornado.log import app_log
from tornado.netutil import Resolver
from tornado.stack_context import NullContext, wrap
from tornado.ioloop import IOLoop


@implementer(IDelayedCall)
class TornadoDelayedCall(object):
    """DelayedCall object for Tornado."""
    def __init__(self, reactor, seconds, f, *args, **kw):
        self._reactor = reactor
        self._func = functools.partial(f, *args, **kw)
        self._time = self._reactor.seconds() + seconds
        self._timeout = self._reactor._io_loop.add_timeout(self._time,
                                                           self._called)
        self._active = True

    def _called(self):
        self._active = False
        self._reactor._removeDelayedCall(self)
        try:
            self._func()
        except:
            app_log.error("_called caught exception", exc_info=True)

    def getTime(self):
        return self._time

    def cancel(self):
        self._active = False
        self._reactor._io_loop.remove_timeout(self._timeout)
        self._reactor._removeDelayedCall(self)

    def delay(self, seconds):
        self._reactor._io_loop.remove_timeout(self._timeout)
        self._time += seconds
        self._timeout = self._reactor._io_loop.add_timeout(self._time,
                                                           self._called)

    def reset(self, seconds):
        self._reactor._io_loop.remove_timeout(self._timeout)
        self._time = self._reactor.seconds() + seconds
        self._timeout = self._reactor._io_loop.add_timeout(self._time,
                                                           self._called)

    def active(self):
        return self._active


@implementer(IReactorTime, IReactorFDSet)
class TornadoReactor(PosixReactorBase):
    """Twisted reactor built on the Tornado IOLoop.

    Since it is intented to be used in applications where the top-level
    event loop is ``io_loop.start()`` rather than ``reactor.run()``,
    it is implemented a little differently than other Twisted reactors.
    We override `mainLoop` instead of `doIteration` and must implement
    timed call functionality on top of `IOLoop.add_timeout` rather than
    using the implementation in `PosixReactorBase`.
    """
    def __init__(self, io_loop=None):
        if not io_loop:
            io_loop = tornado.ioloop.IOLoop.current()
        self._io_loop = io_loop
        self._readers = {}  # map of reader objects to fd
        self._writers = {}  # map of writer objects to fd
        self._fds = {}  # a map of fd to a (reader, writer) tuple
        self._delayedCalls = {}
        PosixReactorBase.__init__(self)
        self.addSystemEventTrigger('during', 'shutdown', self.crash)

        # IOLoop.start() bypasses some of the reactor initialization.
        # Fire off the necessary events if they weren't already triggered
        # by reactor.run().
        def start_if_necessary():
            if not self._started:
                self.fireSystemEvent('startup')
        self._io_loop.add_callback(start_if_necessary)

    # IReactorTime
    def seconds(self):
        return self._io_loop.time()

    def callLater(self, seconds, f, *args, **kw):
        dc = TornadoDelayedCall(self, seconds, f, *args, **kw)
        self._delayedCalls[dc] = True
        return dc

    def getDelayedCalls(self):
        return [x for x in self._delayedCalls if x._active]

    def _removeDelayedCall(self, dc):
        if dc in self._delayedCalls:
            del self._delayedCalls[dc]

    # IReactorThreads
    def callFromThread(self, f, *args, **kw):
        """See `twisted.internet.interfaces.IReactorThreads.callFromThread`"""
        assert callable(f), "%s is not callable" % f
        with NullContext():
            # This NullContext is mainly for an edge case when running
            # TwistedIOLoop on top of a TornadoReactor.
            # TwistedIOLoop.add_callback uses reactor.callFromThread and
            # should not pick up additional StackContexts along the way.
            self._io_loop.add_callback(f, *args, **kw)

    # We don't need the waker code from the super class, Tornado uses
    # its own waker.
    def installWaker(self):
        pass

    def wakeUp(self):
        pass

    # IReactorFDSet
    def _invoke_callback(self, fd, events):
        if fd not in self._fds:
            return
        (reader, writer) = self._fds[fd]
        if reader:
            err = None
            if reader.fileno() == -1:
                err = error.ConnectionLost()
            elif events & IOLoop.READ:
                err = log.callWithLogger(reader, reader.doRead)
            if err is None and events & IOLoop.ERROR:
                err = error.ConnectionLost()
            if err is not None:
                self.removeReader(reader)
                reader.readConnectionLost(failure.Failure(err))
        if writer:
            err = None
            if writer.fileno() == -1:
                err = error.ConnectionLost()
            elif events & IOLoop.WRITE:
                err = log.callWithLogger(writer, writer.doWrite)
            if err is None and events & IOLoop.ERROR:
                err = error.ConnectionLost()
            if err is not None:
                self.removeWriter(writer)
                writer.writeConnectionLost(failure.Failure(err))

    def addReader(self, reader):
        """Add a FileDescriptor for notification of data available to read."""
        if reader in self._readers:
            # Don't add the reader if it's already there
            return
        fd = reader.fileno()
        self._readers[reader] = fd
        if fd in self._fds:
            (_, writer) = self._fds[fd]
            self._fds[fd] = (reader, writer)
            if writer:
                # We already registered this fd for write events,
                # update it for read events as well.
                self._io_loop.update_handler(fd, IOLoop.READ | IOLoop.WRITE)
        else:
            with NullContext():
                self._fds[fd] = (reader, None)
                self._io_loop.add_handler(fd, self._invoke_callback,
                                          IOLoop.READ)

    def addWriter(self, writer):
        """Add a FileDescriptor for notification of data available to write."""
        if writer in self._writers:
            return
        fd = writer.fileno()
        self._writers[writer] = fd
        if fd in self._fds:
            (reader, _) = self._fds[fd]
            self._fds[fd] = (reader, writer)
            if reader:
                # We already registered this fd for read events,
                # update it for write events as well.
                self._io_loop.update_handler(fd, IOLoop.READ | IOLoop.WRITE)
        else:
            with NullContext():
                self._fds[fd] = (None, writer)
                self._io_loop.add_handler(fd, self._invoke_callback,
                                          IOLoop.WRITE)

    def removeReader(self, reader):
        """Remove a Selectable for notification of data available to read."""
        if reader in self._readers:
            fd = self._readers.pop(reader)
            (_, writer) = self._fds[fd]
            if writer:
                # We have a writer so we need to update the IOLoop for
                # write events only.
                self._fds[fd] = (None, writer)
                self._io_loop.update_handler(fd, IOLoop.WRITE)
            else:
                # Since we have no writer registered, we remove the
                # entry from _fds and unregister the handler from the
                # IOLoop
                del self._fds[fd]
                self._io_loop.remove_handler(fd)

    def removeWriter(self, writer):
        """Remove a Selectable for notification of data available to write."""
        if writer in self._writers:
            fd = self._writers.pop(writer)
            (reader, _) = self._fds[fd]
            if reader:
                # We have a reader so we need to update the IOLoop for
                # read events only.
                self._fds[fd] = (reader, None)
                self._io_loop.update_handler(fd, IOLoop.READ)
            else:
                # Since we have no reader registered, we remove the
                # entry from the _fds and unregister the handler from
                # the IOLoop.
                del self._fds[fd]
                self._io_loop.remove_handler(fd)

    def removeAll(self):
        return self._removeAll(self._readers, self._writers)

    def getReaders(self):
        return self._readers.keys()

    def getWriters(self):
        return self._writers.keys()

    # The following functions are mainly used in twisted-style test cases;
    # it is expected that most users of the TornadoReactor will call
    # IOLoop.start() instead of Reactor.run().
    def stop(self):
        PosixReactorBase.stop(self)
        fire_shutdown = functools.partial(self.fireSystemEvent, "shutdown")
        self._io_loop.add_callback(fire_shutdown)

    def crash(self):
        PosixReactorBase.crash(self)
        self._io_loop.stop()

    def doIteration(self, delay):
        raise NotImplementedError("doIteration")

    def mainLoop(self):
        self._io_loop.start()


class _TestReactor(TornadoReactor):
    """Subclass of TornadoReactor for use in unittests.

    This can't go in the test.py file because of import-order dependencies
    with the Twisted reactor test builder.
    """
    def __init__(self):
        # always use a new ioloop
        super(_TestReactor, self).__init__(IOLoop())

    def listenTCP(self, port, factory, backlog=50, interface=''):
        # default to localhost to avoid firewall prompts on the mac
        if not interface:
            interface = '127.0.0.1'
        return super(_TestReactor, self).listenTCP(
            port, factory, backlog=backlog, interface=interface)

    def listenUDP(self, port, protocol, interface='', maxPacketSize=8192):
        if not interface:
            interface = '127.0.0.1'
        return super(_TestReactor, self).listenUDP(
            port, protocol, interface=interface, maxPacketSize=maxPacketSize)


def install(io_loop=None):
    """Install this package as the default Twisted reactor."""
    if not io_loop:
        io_loop = tornado.ioloop.IOLoop.current()
    reactor = TornadoReactor(io_loop)
    from twisted.internet.main import installReactor
    installReactor(reactor)
    return reactor


@implementer(IReadDescriptor, IWriteDescriptor)
class _FD(object):
    def __init__(self, fd, handler):
        self.fd = fd
        self.handler = handler
        self.reading = False
        self.writing = False
        self.lost = False

    def fileno(self):
        return self.fd

    def doRead(self):
        if not self.lost:
            self.handler(self.fd, tornado.ioloop.IOLoop.READ)

    def doWrite(self):
        if not self.lost:
            self.handler(self.fd, tornado.ioloop.IOLoop.WRITE)

    def connectionLost(self, reason):
        if not self.lost:
            self.handler(self.fd, tornado.ioloop.IOLoop.ERROR)
            self.lost = True

    def logPrefix(self):
        return ''


class TwistedIOLoop(tornado.ioloop.IOLoop):
    """IOLoop implementation that runs on Twisted.

    Uses the global Twisted reactor by default.  To create multiple
    `TwistedIOLoops` in the same process, you must pass a unique reactor
    when constructing each one.

    Not compatible with `tornado.process.Subprocess.set_exit_callback`
    because the ``SIGCHLD`` handlers used by Tornado and Twisted conflict
    with each other.
    """
    def initialize(self, reactor=None):
        if reactor is None:
            import twisted.internet.reactor
            reactor = twisted.internet.reactor
        self.reactor = reactor
        self.fds = {}
        self.reactor.callWhenRunning(self.make_current)

    def close(self, all_fds=False):
        self.reactor.removeAll()
        for c in self.reactor.getDelayedCalls():
            c.cancel()

    def add_handler(self, fd, handler, events):
        if fd in self.fds:
            raise ValueError('fd %d added twice' % fd)
        self.fds[fd] = _FD(fd, wrap(handler))
        if events & tornado.ioloop.IOLoop.READ:
            self.fds[fd].reading = True
            self.reactor.addReader(self.fds[fd])
        if events & tornado.ioloop.IOLoop.WRITE:
            self.fds[fd].writing = True
            self.reactor.addWriter(self.fds[fd])

    def update_handler(self, fd, events):
        if events & tornado.ioloop.IOLoop.READ:
            if not self.fds[fd].reading:
                self.fds[fd].reading = True
                self.reactor.addReader(self.fds[fd])
        else:
            if self.fds[fd].reading:
                self.fds[fd].reading = False
                self.reactor.removeReader(self.fds[fd])
        if events & tornado.ioloop.IOLoop.WRITE:
            if not self.fds[fd].writing:
                self.fds[fd].writing = True
                self.reactor.addWriter(self.fds[fd])
        else:
            if self.fds[fd].writing:
                self.fds[fd].writing = False
                self.reactor.removeWriter(self.fds[fd])

    def remove_handler(self, fd):
        if fd not in self.fds:
            return
        self.fds[fd].lost = True
        if self.fds[fd].reading:
            self.reactor.removeReader(self.fds[fd])
        if self.fds[fd].writing:
            self.reactor.removeWriter(self.fds[fd])
        del self.fds[fd]

    def start(self):
        self.reactor.run()

    def stop(self):
        self.reactor.crash()

    def _run_callback(self, callback, *args, **kwargs):
        try:
            callback(*args, **kwargs)
        except Exception:
            self.handle_callback_exception(callback)

    def add_timeout(self, deadline, callback):
        if isinstance(deadline, (int, long, float)):
            delay = max(deadline - self.time(), 0)
        elif isinstance(deadline, datetime.timedelta):
            delay = tornado.ioloop._Timeout.timedelta_to_seconds(deadline)
        else:
            raise TypeError("Unsupported deadline %r")
        return self.reactor.callLater(delay, self._run_callback, wrap(callback))

    def remove_timeout(self, timeout):
        if timeout.active():
            timeout.cancel()

    def add_callback(self, callback, *args, **kwargs):
        self.reactor.callFromThread(self._run_callback,
                                    wrap(callback), *args, **kwargs)

    def add_callback_from_signal(self, callback, *args, **kwargs):
        self.add_callback(callback, *args, **kwargs)


class TwistedResolver(Resolver):
    """Twisted-based asynchronous resolver.

    This is a non-blocking and non-threaded resolver.  It is
    recommended only when threads cannot be used, since it has
    limitations compared to the standard ``getaddrinfo``-based
    `~tornado.netutil.Resolver` and
    `~tornado.netutil.ThreadedResolver`.  Specifically, it returns at
    most one result, and arguments other than ``host`` and ``family``
    are ignored.  It may fail to resolve when ``family`` is not
    ``socket.AF_UNSPEC``.

    Requires Twisted 12.1 or newer.
    """
    def initialize(self, io_loop=None):
        self.io_loop = io_loop or IOLoop.current()
        # partial copy of twisted.names.client.createResolver, which doesn't
        # allow for a reactor to be passed in.
        self.reactor = tornado.platform.twisted.TornadoReactor(io_loop)

        host_resolver = twisted.names.hosts.Resolver('/etc/hosts')
        cache_resolver = twisted.names.cache.CacheResolver(reactor=self.reactor)
        real_resolver = twisted.names.client.Resolver('/etc/resolv.conf',
                                                      reactor=self.reactor)
        self.resolver = twisted.names.resolve.ResolverChain(
            [host_resolver, cache_resolver, real_resolver])

    @gen.coroutine
    def resolve(self, host, port, family=0):
        # getHostByName doesn't accept IP addresses, so if the input
        # looks like an IP address just return it immediately.
        if twisted.internet.abstract.isIPAddress(host):
            resolved = host
            resolved_family = socket.AF_INET
        elif twisted.internet.abstract.isIPv6Address(host):
            resolved = host
            resolved_family = socket.AF_INET6
        else:
            deferred = self.resolver.getHostByName(utf8(host))
            resolved = yield gen.Task(deferred.addCallback)
            if twisted.internet.abstract.isIPAddress(resolved):
                resolved_family = socket.AF_INET
            elif twisted.internet.abstract.isIPv6Address(resolved):
                resolved_family = socket.AF_INET6
            else:
                resolved_family = socket.AF_UNSPEC
        if family != socket.AF_UNSPEC and family != resolved_family:
            raise Exception('Requested socket family %d but got %d' %
                            (family, resolved_family))
        result = [
            (resolved_family, (resolved, port)),
        ]
        raise gen.Return(result)

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