{
    "file_diffs": [
        {
            "old_file_content": "# Copyright 2015 The Tornado Authors\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\"\"\"\n.. testsetup:: *\n\n    from tornado import ioloop, gen, locks\n    io_loop = ioloop.IOLoop.current()\n\"\"\"\n\nfrom __future__ import absolute_import, division, print_function, with_statement\n\n__all__ = ['Condition', 'Event', 'Semaphore', 'BoundedSemaphore', 'Lock']\n\nimport collections\n\nfrom tornado import gen, ioloop\nfrom tornado.concurrent import Future\n\n\nclass _TimeoutGarbageCollector(object):\n    \"\"\"Base class for objects that periodically clean up timed-out waiters.\n\n    Avoids memory leak in a common pattern like:\n\n        while True:\n            yield condition.wait(short_timeout)\n            print('looping....')\n    \"\"\"\n    def __init__(self):\n        self._waiters = collections.deque()  # Futures.\n        self._timeouts = 0\n\n    def _garbage_collect(self):\n        # Occasionally clear timed-out waiters.\n        self._timeouts += 1\n        if self._timeouts > 100:\n            self._timeouts = 0\n            self._waiters = collections.deque(\n                w for w in self._waiters if not w.done())\n\n\nclass Condition(_TimeoutGarbageCollector):\n    \"\"\"A condition allows one or more coroutines to wait until notified.\n\n    Like a standard `threading.Condition`, but does not need an underlying lock\n    that is acquired and released.\n\n    With a `Condition`, coroutines can wait to be notified by other coroutines:\n\n    .. testcode::\n\n        condition = locks.Condition()\n\n        @gen.coroutine\n        def waiter():\n            print(\"I'll wait right here\")\n            yield condition.wait()  # Yield a Future.\n            print(\"I'm done waiting\")\n\n        @gen.coroutine\n        def notifier():\n            print(\"About to notify\")\n            condition.notify()\n            print(\"Done notifying\")\n\n        @gen.coroutine\n        def runner():\n            # Yield two Futures; wait for waiter() and notifier() to finish.\n            yield [waiter(), notifier()]\n\n        io_loop.run_sync(runner)\n\n    .. testoutput::\n\n        I'll wait right here\n        About to notify\n        Done notifying\n        I'm done waiting\n\n    `wait` takes an optional ``timeout`` argument, which is either an absolute\n    timestamp::\n\n        io_loop = ioloop.IOLoop.current()\n\n        # Wait up to 1 second for a notification.\n        yield condition.wait(timeout=io_loop.time() + 1)\n\n    ...or a `datetime.timedelta` for a timeout relative to the current time::\n\n        # Wait up to 1 second.\n        yield condition.wait(timeout=datetime.timedelta(seconds=1))\n\n    The method raises `tornado.gen.TimeoutError` if there's no notification\n    before the deadline.\n    \"\"\"\n\n    def __init__(self):\n        super(Condition, self).__init__()\n        self.io_loop = ioloop.IOLoop.current()\n\n    def __repr__(self):\n        result = '<%s' % (self.__class__.__name__, )\n        if self._waiters:\n            result += ' waiters[%s]' % len(self._waiters)\n        return result + '>'\n\n    def wait(self, timeout=None):\n        \"\"\"Wait for `.notify`.\n\n        Returns a `.Future` that resolves ``True`` if the condition is notified,\n        or ``False`` after a timeout.\n        \"\"\"\n        waiter = Future()\n        self._waiters.append(waiter)\n        if timeout:\n            def on_timeout():\n                waiter.set_result(False)\n                self._garbage_collect()\n            io_loop = ioloop.IOLoop.current()\n            timeout_handle = io_loop.add_timeout(timeout, on_timeout)\n            waiter.add_done_callback(\n                lambda _: io_loop.remove_timeout(timeout_handle))\n        return waiter\n\n    def notify(self, n=1):\n        \"\"\"Wake ``n`` waiters.\"\"\"\n        waiters = []  # Waiters we plan to run right now.\n        while n and self._waiters:\n            waiter = self._waiters.popleft()\n            if not waiter.done():  # Might have timed out.\n                n -= 1\n                waiters.append(waiter)\n\n        for waiter in waiters:\n            waiter.set_result(True)\n\n    def notify_all(self):\n        \"\"\"Wake all waiters.\"\"\"\n        self.notify(len(self._waiters))\n\n\nclass Event(object):\n    \"\"\"An event blocks coroutines until its internal flag is set to True.\n\n    Similar to `threading.Event`.\n\n    A coroutine can wait for an event to be set. Once it is set, calls to\n    ``yield event.wait()`` will not block unless the event has been cleared:\n\n    .. testcode::\n\n        event = locks.Event()\n\n        @gen.coroutine\n        def waiter():\n            print(\"Waiting for event\")\n            yield event.wait()\n            print(\"Not waiting this time\")\n            yield event.wait()\n            print(\"Done\")\n\n        @gen.coroutine\n        def setter():\n            print(\"About to set the event\")\n            event.set()\n\n        @gen.coroutine\n        def runner():\n            yield [waiter(), setter()]\n\n        io_loop.run_sync(runner)\n\n    .. testoutput::\n\n        Waiting for event\n        About to set the event\n        Not waiting this time\n        Done\n    \"\"\"\n    def __init__(self):\n        self._future = Future()\n\n    def __repr__(self):\n        return '<%s %s>' % (\n            self.__class__.__name__, 'set' if self.is_set() else 'clear')\n\n    def is_set(self):\n        \"\"\"Return ``True`` if the internal flag is true.\"\"\"\n        return self._future.done()\n\n    def set(self):\n        \"\"\"Set the internal flag to ``True``. All waiters are awakened.\n\n        Calling `.wait` once the flag is set will not block.\n        \"\"\"\n        if not self._future.done():\n            self._future.set_result(None)\n\n    def clear(self):\n        \"\"\"Reset the internal flag to ``False``.\n        \n        Calls to `.wait` will block until `.set` is called.\n        \"\"\"\n        if self._future.done():\n            self._future = Future()\n\n    def wait(self, timeout=None):\n        \"\"\"Block until the internal flag is true.\n\n        Returns a Future, which raises `tornado.gen.TimeoutError` after a\n        timeout.\n        \"\"\"\n        if timeout is None:\n            return self._future\n        else:\n            return gen.with_timeout(timeout, self._future)\n\n\nclass _ReleasingContextManager(object):\n    \"\"\"Releases a Lock or Semaphore at the end of a \"with\" statement.\n\n        with (yield semaphore.acquire()):\n            pass\n\n        # Now semaphore.release() has been called.\n    \"\"\"\n    def __init__(self, obj):\n        self._obj = obj\n\n    def __enter__(self):\n        pass\n\n    def __exit__(self, exc_type, exc_val, exc_tb):\n        self._obj.release()\n\n\nclass Semaphore(_TimeoutGarbageCollector):\n    \"\"\"A lock that can be acquired a fixed number of times before blocking.\n\n    A Semaphore manages a counter representing the number of `.release` calls\n    minus the number of `.acquire` calls, plus an initial value. The `.acquire`\n    method blocks if necessary until it can return without making the counter\n    negative.\n\n    Semaphores limit access to a shared resource. To allow access for two\n    workers at a time:\n\n    .. testsetup:: semaphore\n\n       from collections import deque\n\n       from tornado import gen, ioloop\n       from tornado.concurrent import Future\n\n       # Ensure reliable doctest output: resolve Futures one at a time.\n       futures_q = deque([Future() for _ in range(3)])\n\n       @gen.coroutine\n       def simulator(futures):\n           for f in futures:\n               yield gen.moment\n               f.set_result(None)\n\n       ioloop.IOLoop.current().add_callback(simulator, list(futures_q))\n\n       def use_some_resource():\n           return futures_q.popleft()\n\n    .. testcode:: semaphore\n\n        sem = locks.Semaphore(2)\n\n        @gen.coroutine\n        def worker(worker_id):\n            yield sem.acquire()\n            try:\n                print(\"Worker %d is working\" % worker_id)\n                yield use_some_resource()\n            finally:\n                print(\"Worker %d is done\" % worker_id)\n                sem.release()\n\n        @gen.coroutine\n        def runner():\n            # Join all workers.\n            yield [worker(i) for i in range(3)]\n\n        io_loop.run_sync(runner)\n\n    .. testoutput:: semaphore\n\n        Worker 0 is working\n        Worker 1 is working\n        Worker 0 is done\n        Worker 2 is working\n        Worker 1 is done\n        Worker 2 is done\n\n    Workers 0 and 1 are allowed to run concurrently, but worker 2 waits until\n    the semaphore has been released once, by worker 0.\n\n    `.acquire` is a context manager, so ``worker`` could be written as::\n\n        @gen.coroutine\n        def worker(worker_id):\n            with (yield sem.acquire()):\n                print(\"Worker %d is working\" % worker_id)\n                yield use_some_resource()\n\n            # Now the semaphore has been released.\n            print(\"Worker %d is done\" % worker_id)\n    \"\"\"\n    def __init__(self, value=1):\n        super(Semaphore, self).__init__()\n        if value < 0:\n            raise ValueError('semaphore initial value must be >= 0')\n\n        self._value = value\n\n    def __repr__(self):\n        res = super(Semaphore, self).__repr__()\n        extra = 'locked' if self._value == 0 else 'unlocked,value:{0}'.format(\n            self._value)\n        if self._waiters:\n            extra = '{0},waiters:{1}'.format(extra, len(self._waiters))\n        return '<{0} [{1}]>'.format(res[1:-1], extra)\n\n    def release(self):\n        \"\"\"Increment the counter and wake one waiter.\"\"\"\n        self._value += 1\n        while self._waiters:\n            waiter = self._waiters.popleft()\n            if not waiter.done():\n                self._value -= 1\n\n                # If the waiter is a coroutine paused at\n                #\n                #     with (yield semaphore.acquire()):\n                #\n                # then the context manager's __exit__ calls release() at the end\n                # of the \"with\" block.\n                waiter.set_result(_ReleasingContextManager(self))\n                break\n\n    def acquire(self, timeout=None):\n        \"\"\"Decrement the counter. Returns a Future.\n\n        Block if the counter is zero and wait for a `.release`. The Future\n        raises `.TimeoutError` after the deadline.\n        \"\"\"\n        waiter = Future()\n        if self._value > 0:\n            self._value -= 1\n            waiter.set_result(_ReleasingContextManager(self))\n        else:\n            self._waiters.append(waiter)\n            if timeout:\n                def on_timeout():\n                    waiter.set_exception(gen.TimeoutError())\n                    self._garbage_collect()\n                io_loop = ioloop.IOLoop.current()\n                timeout_handle = io_loop.add_timeout(timeout, on_timeout)\n                waiter.add_done_callback(\n                    lambda _: io_loop.remove_timeout(timeout_handle))\n        return waiter\n\n    def __enter__(self):\n        raise RuntimeError(\n            \"Use Semaphore like 'with (yield semaphore.acquire())', not like\"\n            \" 'with semaphore'\")\n\n    __exit__ = __enter__\n\n\nclass BoundedSemaphore(Semaphore):\n    \"\"\"A semaphore that prevents release() being called too many times.\n\n    If `.release` would increment the semaphore's value past the initial\n    value, it raises `ValueError`. Semaphores are mostly used to guard\n    resources with limited capacity, so a semaphore released too many times\n    is a sign of a bug.\n    \"\"\"\n    def __init__(self, value=1):\n        super(BoundedSemaphore, self).__init__(value=value)\n        self._initial_value = value\n\n    def release(self):\n        \"\"\"Increment the counter and wake one waiter.\"\"\"\n        if self._value >= self._initial_value:\n            raise ValueError(\"Semaphore released too many times\")\n        super(BoundedSemaphore, self).release()\n\n\nclass Lock(object):\n    \"\"\"A lock for coroutines.\n\n    A Lock begins unlocked, and `acquire` locks it immediately. While it is\n    locked, a coroutine that yields `acquire` waits until another coroutine\n    calls `release`.\n\n    Releasing an unlocked lock raises `RuntimeError`.\n\n    `acquire` supports the context manager protocol:\n\n    >>> from tornado import gen, locks\n    >>> lock = locks.Lock()\n    >>>\n    >>> @gen.coroutine\n    ... def f():\n    ...    with (yield lock.acquire()):\n    ...        # Do something holding the lock.\n    ...        pass\n    ...\n    ...    # Now the lock is released.\n    \"\"\"\n    def __init__(self):\n        self._block = BoundedSemaphore(value=1)\n\n    def __repr__(self):\n        return \"<%s _block=%s>\" % (\n            self.__class__.__name__,\n            self._block)\n\n    def acquire(self, deadline=None):\n        \"\"\"Attempt to lock. Returns a Future.\n\n        Returns a Future, which raises `tornado.gen.TimeoutError` after a\n        timeout.\n        \"\"\"\n        return self._block.acquire(deadline)\n\n    def release(self):\n        \"\"\"Unlock.\n\n        The first coroutine in line waiting for `acquire` gets the lock.\n\n        If not locked, raise a `RuntimeError`.\n        \"\"\"\n        try:\n            self._block.release()\n        except ValueError:\n            raise RuntimeError('release unlocked lock')\n\n    def __enter__(self):\n        raise RuntimeError(\n            \"Use Lock like 'with (yield lock)', not like 'with lock'\")\n\n    __exit__ = __enter__\n",
            "new_file_content": "# Copyright 2015 The Tornado Authors\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\"\"\"\n.. testsetup:: *\n\n    from tornado import ioloop, gen, locks\n    io_loop = ioloop.IOLoop.current()\n\"\"\"\n\nfrom __future__ import absolute_import, division, print_function, with_statement\n\n__all__ = ['Condition', 'Event', 'Semaphore', 'BoundedSemaphore', 'Lock']\n\nimport collections\n\nfrom tornado import gen, ioloop\nfrom tornado.concurrent import Future\n\n\nclass _TimeoutGarbageCollector(object):\n    \"\"\"Base class for objects that periodically clean up timed-out waiters.\n\n    Avoids memory leak in a common pattern like:\n\n        while True:\n            yield condition.wait(short_timeout)\n            print('looping....')\n    \"\"\"\n    def __init__(self):\n        self._waiters = collections.deque()  # Futures.\n        self._timeouts = 0\n\n    def _garbage_collect(self):\n        # Occasionally clear timed-out waiters.\n        self._timeouts += 1\n        if self._timeouts > 100:\n            self._timeouts = 0\n            self._waiters = collections.deque(\n                w for w in self._waiters if not w.done())\n\n\nclass Condition(_TimeoutGarbageCollector):\n    \"\"\"A condition allows one or more coroutines to wait until notified.\n\n    Like a standard `threading.Condition`, but does not need an underlying lock\n    that is acquired and released.\n\n    With a `Condition`, coroutines can wait to be notified by other coroutines:\n\n    .. testcode::\n\n        condition = locks.Condition()\n\n        @gen.coroutine\n        def waiter():\n            print(\"I'll wait right here\")\n            yield condition.wait()  # Yield a Future.\n            print(\"I'm done waiting\")\n\n        @gen.coroutine\n        def notifier():\n            print(\"About to notify\")\n            condition.notify()\n            print(\"Done notifying\")\n\n        @gen.coroutine\n        def runner():\n            # Yield two Futures; wait for waiter() and notifier() to finish.\n            yield [waiter(), notifier()]\n\n        io_loop.run_sync(runner)\n\n    .. testoutput::\n\n        I'll wait right here\n        About to notify\n        Done notifying\n        I'm done waiting\n\n    `wait` takes an optional ``timeout`` argument, which is either an absolute\n    timestamp::\n\n        io_loop = ioloop.IOLoop.current()\n\n        # Wait up to 1 second for a notification.\n        yield condition.wait(timeout=io_loop.time() + 1)\n\n    ...or a `datetime.timedelta` for a timeout relative to the current time::\n\n        # Wait up to 1 second.\n        yield condition.wait(timeout=datetime.timedelta(seconds=1))\n\n    The method raises `tornado.gen.TimeoutError` if there's no notification\n    before the deadline.\n    \"\"\"\n\n    def __init__(self):\n        super(Condition, self).__init__()\n        self.io_loop = ioloop.IOLoop.current()\n\n    def __repr__(self):\n        result = '<%s' % (self.__class__.__name__, )\n        if self._waiters:\n            result += ' waiters[%s]' % len(self._waiters)\n        return result + '>'\n\n    def wait(self, timeout=None):\n        \"\"\"Wait for `.notify`.\n\n        Returns a `.Future` that resolves ``True`` if the condition is notified,\n        or ``False`` after a timeout.\n        \"\"\"\n        waiter = Future()\n        self._waiters.append(waiter)\n        if timeout:\n            def on_timeout():\n                waiter.set_result(False)\n                self._garbage_collect()\n            io_loop = ioloop.IOLoop.current()\n            timeout_handle = io_loop.add_timeout(timeout, on_timeout)\n            waiter.add_done_callback(\n                lambda _: io_loop.remove_timeout(timeout_handle))\n        return waiter\n\n    def notify(self, n=1):\n        \"\"\"Wake ``n`` waiters.\"\"\"\n        waiters = []  # Waiters we plan to run right now.\n        while n and self._waiters:\n            waiter = self._waiters.popleft()\n            if not waiter.done():  # Might have timed out.\n                n -= 1\n                waiters.append(waiter)\n\n        for waiter in waiters:\n            waiter.set_result(True)\n\n    def notify_all(self):\n        \"\"\"Wake all waiters.\"\"\"\n        self.notify(len(self._waiters))\n\n\nclass Event(object):\n    \"\"\"An event blocks coroutines until its internal flag is set to True.\n\n    Similar to `threading.Event`.\n\n    A coroutine can wait for an event to be set. Once it is set, calls to\n    ``yield event.wait()`` will not block unless the event has been cleared:\n\n    .. testcode::\n\n        event = locks.Event()\n\n        @gen.coroutine\n        def waiter():\n            print(\"Waiting for event\")\n            yield event.wait()\n            print(\"Not waiting this time\")\n            yield event.wait()\n            print(\"Done\")\n\n        @gen.coroutine\n        def setter():\n            print(\"About to set the event\")\n            event.set()\n\n        @gen.coroutine\n        def runner():\n            yield [waiter(), setter()]\n\n        io_loop.run_sync(runner)\n\n    .. testoutput::\n\n        Waiting for event\n        About to set the event\n        Not waiting this time\n        Done\n    \"\"\"\n    def __init__(self):\n        self._future = Future()\n\n    def __repr__(self):\n        return '<%s %s>' % (\n            self.__class__.__name__, 'set' if self.is_set() else 'clear')\n\n    def is_set(self):\n        \"\"\"Return ``True`` if the internal flag is true.\"\"\"\n        return self._future.done()\n\n    def set(self):\n        \"\"\"Set the internal flag to ``True``. All waiters are awakened.\n\n        Calling `.wait` once the flag is set will not block.\n        \"\"\"\n        if not self._future.done():\n            self._future.set_result(None)\n\n    def clear(self):\n        \"\"\"Reset the internal flag to ``False``.\n        \n        Calls to `.wait` will block until `.set` is called.\n        \"\"\"\n        if self._future.done():\n            self._future = Future()\n\n    def wait(self, timeout=None):\n        \"\"\"Block until the internal flag is true.\n\n        Returns a Future, which raises `tornado.gen.TimeoutError` after a\n        timeout.\n        \"\"\"\n        if timeout is None:\n            return self._future\n        else:\n            return gen.with_timeout(timeout, self._future)\n\n\nclass _ReleasingContextManager(object):\n    \"\"\"Releases a Lock or Semaphore at the end of a \"with\" statement.\n\n        with (yield semaphore.acquire()):\n            pass\n\n        # Now semaphore.release() has been called.\n    \"\"\"\n    def __init__(self, obj):\n        self._obj = obj\n\n    def __enter__(self):\n        pass\n\n    def __exit__(self, exc_type, exc_val, exc_tb):\n        self._obj.release()\n\n\nclass Semaphore(_TimeoutGarbageCollector):\n    \"\"\"A lock that can be acquired a fixed number of times before blocking.\n\n    A Semaphore manages a counter representing the number of `.release` calls\n    minus the number of `.acquire` calls, plus an initial value. The `.acquire`\n    method blocks if necessary until it can return without making the counter\n    negative.\n\n    Semaphores limit access to a shared resource. To allow access for two\n    workers at a time:\n\n    .. testsetup:: semaphore\n\n       from collections import deque\n\n       from tornado import gen, ioloop\n       from tornado.concurrent import Future\n\n       # Ensure reliable doctest output: resolve Futures one at a time.\n       futures_q = deque([Future() for _ in range(3)])\n\n       @gen.coroutine\n       def simulator(futures):\n           for f in futures:\n               yield gen.moment\n               f.set_result(None)\n\n       ioloop.IOLoop.current().add_callback(simulator, list(futures_q))\n\n       def use_some_resource():\n           return futures_q.popleft()\n\n    .. testcode:: semaphore\n\n        sem = locks.Semaphore(2)\n\n        @gen.coroutine\n        def worker(worker_id):\n            yield sem.acquire()\n            try:\n                print(\"Worker %d is working\" % worker_id)\n                yield use_some_resource()\n            finally:\n                print(\"Worker %d is done\" % worker_id)\n                sem.release()\n\n        @gen.coroutine\n        def runner():\n            # Join all workers.\n            yield [worker(i) for i in range(3)]\n\n        io_loop.run_sync(runner)\n\n    .. testoutput:: semaphore\n\n        Worker 0 is working\n        Worker 1 is working\n        Worker 0 is done\n        Worker 2 is working\n        Worker 1 is done\n        Worker 2 is done\n\n    Workers 0 and 1 are allowed to run concurrently, but worker 2 waits until\n    the semaphore has been released once, by worker 0.\n\n    `.acquire` is a context manager, so ``worker`` could be written as::\n\n        @gen.coroutine\n        def worker(worker_id):\n            with (yield sem.acquire()):\n                print(\"Worker %d is working\" % worker_id)\n                yield use_some_resource()\n\n            # Now the semaphore has been released.\n            print(\"Worker %d is done\" % worker_id)\n    \"\"\"\n    def __init__(self, value=1):\n        super(Semaphore, self).__init__()\n        if value < 0:\n            raise ValueError('semaphore initial value must be >= 0')\n\n        self._value = value\n\n    def __repr__(self):\n        res = super(Semaphore, self).__repr__()\n        extra = 'locked' if self._value == 0 else 'unlocked,value:{0}'.format(\n            self._value)\n        if self._waiters:\n            extra = '{0},waiters:{1}'.format(extra, len(self._waiters))\n        return '<{0} [{1}]>'.format(res[1:-1], extra)\n\n    def release(self):\n        \"\"\"Increment the counter and wake one waiter.\"\"\"\n        self._value += 1\n        while self._waiters:\n            waiter = self._waiters.popleft()\n            if not waiter.done():\n                self._value -= 1\n\n                # If the waiter is a coroutine paused at\n                #\n                #     with (yield semaphore.acquire()):\n                #\n                # then the context manager's __exit__ calls release() at the end\n                # of the \"with\" block.\n                waiter.set_result(_ReleasingContextManager(self))\n                break\n\n    def acquire(self, timeout=None):\n        \"\"\"Decrement the counter. Returns a Future.\n\n        Block if the counter is zero and wait for a `.release`. The Future\n        raises `.TimeoutError` after the deadline.\n        \"\"\"\n        waiter = Future()\n        if self._value > 0:\n            self._value -= 1\n            waiter.set_result(_ReleasingContextManager(self))\n        else:\n            self._waiters.append(waiter)\n            if timeout:\n                def on_timeout():\n                    waiter.set_exception(gen.TimeoutError())\n                    self._garbage_collect()\n                io_loop = ioloop.IOLoop.current()\n                timeout_handle = io_loop.add_timeout(timeout, on_timeout)\n                waiter.add_done_callback(\n                    lambda _: io_loop.remove_timeout(timeout_handle))\n        return waiter\n\n    def __enter__(self):\n        raise RuntimeError(\n            \"Use Semaphore like 'with (yield semaphore.acquire())', not like\"\n            \" 'with semaphore'\")\n\n    __exit__ = __enter__\n\n\nclass BoundedSemaphore(Semaphore):\n    \"\"\"A semaphore that prevents release() being called too many times.\n\n    If `.release` would increment the semaphore's value past the initial\n    value, it raises `ValueError`. Semaphores are mostly used to guard\n    resources with limited capacity, so a semaphore released too many times\n    is a sign of a bug.\n    \"\"\"\n    def __init__(self, value=1):\n        super(BoundedSemaphore, self).__init__(value=value)\n        self._initial_value = value\n\n    def release(self):\n        \"\"\"Increment the counter and wake one waiter.\"\"\"\n        if self._value >= self._initial_value:\n            raise ValueError(\"Semaphore released too many times\")\n        super(BoundedSemaphore, self).release()\n\n\nclass Lock(object):\n    \"\"\"A lock for coroutines.\n\n    A Lock begins unlocked, and `acquire` locks it immediately. While it is\n    locked, a coroutine that yields `acquire` waits until another coroutine\n    calls `release`.\n\n    Releasing an unlocked lock raises `RuntimeError`.\n\n    `acquire` supports the context manager protocol:\n\n    >>> from tornado import gen, locks\n    >>> lock = locks.Lock()\n    >>>\n    >>> @gen.coroutine\n    ... def f():\n    ...    with (yield lock.acquire()):\n    ...        # Do something holding the lock.\n    ...        pass\n    ...\n    ...    # Now the lock is released.\n    \"\"\"\n    def __init__(self):\n        self._block = BoundedSemaphore(value=1)\n\n    def __repr__(self):\n        return \"<%s _block=%s>\" % (\n            self.__class__.__name__,\n            self._block)\n\n    def acquire(self, timeout=None):\n        \"\"\"Attempt to lock. Returns a Future.\n\n        Returns a Future, which raises `tornado.gen.TimeoutError` after a\n        timeout.\n        \"\"\"\n        return self._block.acquire(timeout)\n\n    def release(self):\n        \"\"\"Unlock.\n\n        The first coroutine in line waiting for `acquire` gets the lock.\n\n        If not locked, raise a `RuntimeError`.\n        \"\"\"\n        try:\n            self._block.release()\n        except ValueError:\n            raise RuntimeError('release unlocked lock')\n\n    def __enter__(self):\n        raise RuntimeError(\n            \"Use Lock like 'with (yield lock)', not like 'with lock'\")\n\n    __exit__ = __enter__\n",
            "header": {
                "file": {
                    "path": "tornado/locks.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "77340abc",
                "new_commit_hash": "4b0bdb38",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/tornado/locks.py"
            },
            "plus_file": {
                "path": "b/tornado/locks.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 433,
                            "length": 13
                        },
                        "new_range": {
                            "start": 433,
                            "length": 13
                        },
                        "section": "class Lock(object):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "            self.__class__.__name__,",
                                "type": "context"
                            },
                            {
                                "content": "            self._block)",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def acquire(self, deadline=None):",
                                "type": "deleted"
                            },
                            {
                                "content": "    def acquire(self, timeout=None):",
                                "type": "added"
                            },
                            {
                                "content": "        \"\"\"Attempt to lock. Returns a Future.",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "        Returns a Future, which raises `tornado.gen.TimeoutError` after a",
                                "type": "context"
                            },
                            {
                                "content": "        timeout.",
                                "type": "context"
                            },
                            {
                                "content": "        \"\"\"",
                                "type": "context"
                            },
                            {
                                "content": "        return self._block.acquire(deadline)",
                                "type": "deleted"
                            },
                            {
                                "content": "        return self._block.acquire(timeout)",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def release(self):",
                                "type": "context"
                            },
                            {
                                "content": "        \"\"\"Unlock.",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/locks.py",
                            "type": "class",
                            "name": "Lock",
                            "content": "class Lock(object):\n    \"\"\"A lock for coroutines.\n\n    A Lock begins unlocked, and `acquire` locks it immediately. While it is\n    locked, a coroutine that yields `acquire` waits until another coroutine\n    calls `release`.\n\n    Releasing an unlocked lock raises `RuntimeError`.\n\n    `acquire` supports the context manager protocol:\n\n    >>> from tornado import gen, locks\n    >>> lock = locks.Lock()\n    >>>\n    >>> @gen.coroutine\n    ... def f():\n    ...    with (yield lock.acquire()):\n    ...        # Do something holding the lock.\n    ...        pass\n    ...\n    ...    # Now the lock is released.\n    \"\"\"\n    def __init__(self):\n        self._block = BoundedSemaphore(value=1)\n\n    def __repr__(self):\n        return \"<%s _block=%s>\" % (\n            self.__class__.__name__,\n            self._block)\n\n    def acquire(self, deadline=None):\n        \"\"\"Attempt to lock. Returns a Future.\n\n        Returns a Future, which raises `tornado.gen.TimeoutError` after a\n        timeout.\n        \"\"\"\n        return self._block.acquire(deadline)\n\n    def release(self):\n        \"\"\"Unlock.\n\n        The first coroutine in line waiting for `acquire` gets the lock.\n\n        If not locked, raise a `RuntimeError`.\n        \"\"\"\n        try:\n            self._block.release()\n        except ValueError:\n            raise RuntimeError('release unlocked lock')\n\n    def __enter__(self):\n        raise RuntimeError(\n            \"Use Lock like 'with (yield lock)', not like 'with lock'\")\n\n    __exit__ = __enter__",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 406,
                            "end_lineno": 460,
                            "parent": null
                        },
                        {
                            "file_name": "tornado/locks.py",
                            "type": "method",
                            "name": "Lock.acquire",
                            "content": "class Lock(object):\n    \"\"\"A lock for coroutines.\n\n    A Lock begins unlocked, and `acquire` locks it immediately. While it is\n    locked, a coroutine that yields `acquire` waits until another coroutine\n    calls `release`.\n\n    Releasing an unlocked lock raises `RuntimeError`.\n\n    `acquire` supports the context manager protocol:\n\n    >>> from tornado import gen, locks\n    >>> lock = locks.Lock()\n    >>>\n    >>> @gen.coroutine\n    ... def f():\n    ...    with (yield lock.acquire()):\n    ...        # Do something holding the lock.\n    ...        pass\n    ...\n    ...    # Now the lock is released.\n    \"\"\"\n    def __init__(self):\n        self._block = BoundedSemaphore(value=1)\n\n    def __repr__(self):\n        return \"<%s _block=%s>\" % (\n            self.__class__.__name__,\n            self._block)\n\n    def acquire(self, deadline=None):\n        \"\"\"Attempt to lock. Returns a Future.\n\n        Returns a Future, which raises `tornado.gen.TimeoutError` after a\n        timeout.\n        \"\"\"\n        return self._block.acquire(deadline)\n\n    def release(self):\n        \"\"\"Unlock.\n\n        The first coroutine in line waiting for `acquire` gets the lock.\n\n        If not locked, raise a `RuntimeError`.\n        \"\"\"\n        try:\n            self._block.release()\n        except ValueError:\n            raise RuntimeError('release unlocked lock')\n\n    def __enter__(self):\n        raise RuntimeError(\n            \"Use Lock like 'with (yield lock)', not like 'with lock'\")\n\n    __exit__ = __enter__",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 436,
                            "end_lineno": 442,
                            "parent": {
                                "file_name": "tornado/locks.py",
                                "type": "class",
                                "name": "Lock",
                                "content": "class Lock(object):\n    \"\"\"A lock for coroutines.\n\n    A Lock begins unlocked, and `acquire` locks it immediately. While it is\n    locked, a coroutine that yields `acquire` waits until another coroutine\n    calls `release`.\n\n    Releasing an unlocked lock raises `RuntimeError`.\n\n    `acquire` supports the context manager protocol:\n\n    >>> from tornado import gen, locks\n    >>> lock = locks.Lock()\n    >>>\n    >>> @gen.coroutine\n    ... def f():\n    ...    with (yield lock.acquire()):\n    ...        # Do something holding the lock.\n    ...        pass\n    ...\n    ...    # Now the lock is released.\n    \"\"\"\n    def __init__(self):\n        self._block = BoundedSemaphore(value=1)\n\n    def __repr__(self):\n        return \"<%s _block=%s>\" % (\n            self.__class__.__name__,\n            self._block)\n\n    def acquire(self, deadline=None):\n        \"\"\"Attempt to lock. Returns a Future.\n\n        Returns a Future, which raises `tornado.gen.TimeoutError` after a\n        timeout.\n        \"\"\"\n        return self._block.acquire(deadline)\n\n    def release(self):\n        \"\"\"Unlock.\n\n        The first coroutine in line waiting for `acquire` gets the lock.\n\n        If not locked, raise a `RuntimeError`.\n        \"\"\"\n        try:\n            self._block.release()\n        except ValueError:\n            raise RuntimeError('release unlocked lock')\n\n    def __enter__(self):\n        raise RuntimeError(\n            \"Use Lock like 'with (yield lock)', not like 'with lock'\")\n\n    __exit__ = __enter__",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 406,
                                "end_lineno": 460,
                                "parent": null
                            }
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        },
        {
            "old_file_content": "# Licensed under the Apache License, Version 2.0 (the \"License\"); you may\n# not use this file except in compliance with the License. You may obtain\n# a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n# License for the specific language governing permissions and limitations\n# under the License.\n\nfrom datetime import timedelta\n\nfrom tornado import gen, locks\nfrom tornado.gen import TimeoutError\nfrom tornado.testing import gen_test, AsyncTestCase\nfrom tornado.test.util import unittest\n\n\nclass ConditionTest(AsyncTestCase):\n    def setUp(self):\n        super(ConditionTest, self).setUp()\n        self.history = []\n\n    def record_done(self, future, key):\n        \"\"\"Record the resolution of a Future returned by Condition.wait.\"\"\"\n        def callback(_):\n            if not future.result():\n                # wait() resolved to False, meaning it timed out.\n                self.history.append('timeout')\n            else:\n                self.history.append(key)\n        future.add_done_callback(callback)\n\n    def test_repr(self):\n        c = locks.Condition()\n        self.assertIn('Condition', repr(c))\n        self.assertNotIn('waiters', repr(c))\n        c.wait()\n        self.assertIn('waiters', repr(c))\n\n    @gen_test\n    def test_notify(self):\n        c = locks.Condition()\n        self.io_loop.call_later(0.01, c.notify)\n        yield c.wait()\n\n    def test_notify_1(self):\n        c = locks.Condition()\n        self.record_done(c.wait(), 'wait1')\n        self.record_done(c.wait(), 'wait2')\n        c.notify(1)\n        self.history.append('notify1')\n        c.notify(1)\n        self.history.append('notify2')\n        self.assertEqual(['wait1', 'notify1', 'wait2', 'notify2'],\n                         self.history)\n\n    def test_notify_n(self):\n        c = locks.Condition()\n        for i in range(6):\n            self.record_done(c.wait(), i)\n\n        c.notify(3)\n\n        # Callbacks execute in the order they were registered.\n        self.assertEqual(list(range(3)), self.history)\n        c.notify(1)\n        self.assertEqual(list(range(4)), self.history)\n        c.notify(2)\n        self.assertEqual(list(range(6)), self.history)\n\n    def test_notify_all(self):\n        c = locks.Condition()\n        for i in range(4):\n            self.record_done(c.wait(), i)\n\n        c.notify_all()\n        self.history.append('notify_all')\n\n        # Callbacks execute in the order they were registered.\n        self.assertEqual(\n            list(range(4)) + ['notify_all'],\n            self.history)\n\n    @gen_test\n    def test_wait_timeout(self):\n        c = locks.Condition()\n        wait = c.wait(timedelta(seconds=0.01))\n        self.io_loop.call_later(0.02, c.notify)  # Too late.\n        yield gen.sleep(0.03)\n        self.assertFalse((yield wait))\n\n    @gen_test\n    def test_wait_timeout_preempted(self):\n        c = locks.Condition()\n\n        # This fires before the wait times out.\n        self.io_loop.call_later(0.01, c.notify)\n        wait = c.wait(timedelta(seconds=0.02))\n        yield gen.sleep(0.03)\n        yield wait  # No TimeoutError.\n\n    @gen_test\n    def test_notify_n_with_timeout(self):\n        # Register callbacks 0, 1, 2, and 3. Callback 1 has a timeout.\n        # Wait for that timeout to expire, then do notify(2) and make\n        # sure everyone runs. Verifies that a timed-out callback does\n        # not count against the 'n' argument to notify().\n        c = locks.Condition()\n        self.record_done(c.wait(), 0)\n        self.record_done(c.wait(timedelta(seconds=0.01)), 1)\n        self.record_done(c.wait(), 2)\n        self.record_done(c.wait(), 3)\n\n        # Wait for callback 1 to time out.\n        yield gen.sleep(0.02)\n        self.assertEqual(['timeout'], self.history)\n\n        c.notify(2)\n        yield gen.sleep(0.01)\n        self.assertEqual(['timeout', 0, 2], self.history)\n        self.assertEqual(['timeout', 0, 2], self.history)\n        c.notify()\n        self.assertEqual(['timeout', 0, 2, 3], self.history)\n\n    @gen_test\n    def test_notify_all_with_timeout(self):\n        c = locks.Condition()\n        self.record_done(c.wait(), 0)\n        self.record_done(c.wait(timedelta(seconds=0.01)), 1)\n        self.record_done(c.wait(), 2)\n\n        # Wait for callback 1 to time out.\n        yield gen.sleep(0.02)\n        self.assertEqual(['timeout'], self.history)\n\n        c.notify_all()\n        self.assertEqual(['timeout', 0, 2], self.history)\n\n    @gen_test\n    def test_nested_notify(self):\n        # Ensure no notifications lost, even if notify() is reentered by a\n        # waiter calling notify().\n        c = locks.Condition()\n\n        # Three waiters.\n        futures = [c.wait() for _ in range(3)]\n\n        # First and second futures resolved. Second future reenters notify(),\n        # resolving third future.\n        futures[1].add_done_callback(lambda _: c.notify())\n        c.notify(2)\n        self.assertTrue(all(f.done() for f in futures))\n\n    @gen_test\n    def test_garbage_collection(self):\n        # Test that timed-out waiters are occasionally cleaned from the queue.\n        c = locks.Condition()\n        for _ in range(101):\n            c.wait(timedelta(seconds=0.01))\n\n        future = c.wait()\n        self.assertEqual(102, len(c._waiters))\n\n        # Let first 101 waiters time out, triggering a collection.\n        yield gen.sleep(0.02)\n        self.assertEqual(1, len(c._waiters))\n\n        # Final waiter is still active.\n        self.assertFalse(future.done())\n        c.notify()\n        self.assertTrue(future.done())\n\n\nclass EventTest(AsyncTestCase):\n    def test_repr(self):\n        event = locks.Event()\n        self.assertTrue('clear' in str(event))\n        self.assertFalse('set' in str(event))\n        event.set()\n        self.assertFalse('clear' in str(event))\n        self.assertTrue('set' in str(event))\n\n    def test_event(self):\n        e = locks.Event()\n        future_0 = e.wait()\n        e.set()\n        future_1 = e.wait()\n        e.clear()\n        future_2 = e.wait()\n\n        self.assertTrue(future_0.done())\n        self.assertTrue(future_1.done())\n        self.assertFalse(future_2.done())\n\n    @gen_test\n    def test_event_timeout(self):\n        e = locks.Event()\n        with self.assertRaises(TimeoutError):\n            yield e.wait(timedelta(seconds=0.01))\n\n        # After a timed-out waiter, normal operation works.\n        self.io_loop.add_timeout(timedelta(seconds=0.01), e.set)\n        yield e.wait(timedelta(seconds=1))\n\n    def test_event_set_multiple(self):\n        e = locks.Event()\n        e.set()\n        e.set()\n        self.assertTrue(e.is_set())\n\n    def test_event_wait_clear(self):\n        e = locks.Event()\n        f0 = e.wait()\n        e.clear()\n        f1 = e.wait()\n        e.set()\n        self.assertTrue(f0.done())\n        self.assertTrue(f1.done())\n\n\nclass SemaphoreTest(AsyncTestCase):\n    def test_negative_value(self):\n        self.assertRaises(ValueError, locks.Semaphore, value=-1)\n\n    def test_repr(self):\n        sem = locks.Semaphore()\n        self.assertIn('Semaphore', repr(sem))\n        self.assertIn('unlocked,value:1', repr(sem))\n        sem.acquire()\n        self.assertIn('locked', repr(sem))\n        self.assertNotIn('waiters', repr(sem))\n        sem.acquire()\n        self.assertIn('waiters', repr(sem))\n\n    def test_acquire(self):\n        sem = locks.Semaphore()\n        f0 = sem.acquire()\n        self.assertTrue(f0.done())\n\n        # Wait for release().\n        f1 = sem.acquire()\n        self.assertFalse(f1.done())\n        f2 = sem.acquire()\n        sem.release()\n        self.assertTrue(f1.done())\n        self.assertFalse(f2.done())\n        sem.release()\n        self.assertTrue(f2.done())\n\n        sem.release()\n        # Now acquire() is instant.\n        self.assertTrue(sem.acquire().done())\n        self.assertEqual(0, len(sem._waiters))\n\n    @gen_test\n    def test_acquire_timeout(self):\n        sem = locks.Semaphore(2)\n        yield sem.acquire()\n        yield sem.acquire()\n        acquire = sem.acquire(timedelta(seconds=0.01))\n        self.io_loop.call_later(0.02, sem.release)  # Too late.\n        yield gen.sleep(0.3)\n        with self.assertRaises(gen.TimeoutError):\n            yield acquire\n\n        sem.acquire()\n        f = sem.acquire()\n        self.assertFalse(f.done())\n        sem.release()\n        self.assertTrue(f.done())\n\n    @gen_test\n    def test_acquire_timeout_preempted(self):\n        sem = locks.Semaphore(1)\n        yield sem.acquire()\n\n        # This fires before the wait times out.\n        self.io_loop.call_later(0.01, sem.release)\n        acquire = sem.acquire(timedelta(seconds=0.02))\n        yield gen.sleep(0.03)\n        yield acquire  # No TimeoutError.\n\n    def test_release_unacquired(self):\n        # Unbounded releases are allowed, and increment the semaphore's value.\n        sem = locks.Semaphore()\n        sem.release()\n        sem.release()\n\n        # Now the counter is 3. We can acquire three times before blocking.\n        self.assertTrue(sem.acquire().done())\n        self.assertTrue(sem.acquire().done())\n        self.assertTrue(sem.acquire().done())\n        self.assertFalse(sem.acquire().done())\n\n    @gen_test\n    def test_garbage_collection(self):\n        # Test that timed-out waiters are occasionally cleaned from the queue.\n        sem = locks.Semaphore(value=0)\n        futures = [sem.acquire(timedelta(seconds=0.01)) for _ in range(101)]\n\n        future = sem.acquire()\n        self.assertEqual(102, len(sem._waiters))\n\n        # Let first 101 waiters time out, triggering a collection.\n        yield gen.sleep(0.02)\n        self.assertEqual(1, len(sem._waiters))\n\n        # Final waiter is still active.\n        self.assertFalse(future.done())\n        sem.release()\n        self.assertTrue(future.done())\n\n        # Prevent \"Future exception was never retrieved\" messages.\n        for future in futures:\n            self.assertRaises(TimeoutError, future.result)\n\n\nclass SemaphoreContextManagerTest(AsyncTestCase):\n    @gen_test\n    def test_context_manager(self):\n        sem = locks.Semaphore()\n        with (yield sem.acquire()) as yielded:\n            self.assertTrue(yielded is None)\n\n        # Semaphore was released and can be acquired again.\n        self.assertTrue(sem.acquire().done())\n\n    @gen_test\n    def test_context_manager_exception(self):\n        sem = locks.Semaphore()\n        with self.assertRaises(ZeroDivisionError):\n            with (yield sem.acquire()):\n                1 / 0\n\n        # Semaphore was released and can be acquired again.\n        self.assertTrue(sem.acquire().done())\n\n    @gen_test\n    def test_context_manager_timeout(self):\n        sem = locks.Semaphore()\n        with (yield sem.acquire(timedelta(seconds=0.01))):\n            pass\n\n        # Semaphore was released and can be acquired again.\n        self.assertTrue(sem.acquire().done())\n\n    @gen_test\n    def test_context_manager_timeout_error(self):\n        sem = locks.Semaphore(value=0)\n        with self.assertRaises(gen.TimeoutError):\n            with (yield sem.acquire(timedelta(seconds=0.01))):\n                pass\n\n        # Counter is still 0.\n        self.assertFalse(sem.acquire().done())\n\n    @gen_test\n    def test_context_manager_contended(self):\n        sem = locks.Semaphore()\n        history = []\n\n        @gen.coroutine\n        def f(index):\n            with (yield sem.acquire()):\n                history.append('acquired %d' % index)\n                yield gen.sleep(0.01)\n                history.append('release %d' % index)\n\n        yield [f(i) for i in range(2)]\n\n        expected_history = []\n        for i in range(2):\n            expected_history.extend(['acquired %d' % i, 'release %d' % i])\n\n        self.assertEqual(expected_history, history)\n\n    @gen_test\n    def test_yield_sem(self):\n        # Ensure we catch a \"with (yield sem)\", which should be\n        # \"with (yield sem.acquire())\".\n        with self.assertRaises(gen.BadYieldError):\n            with (yield locks.Semaphore()):\n                pass\n\n    def test_context_manager_misuse(self):\n        # Ensure we catch a \"with sem\", which should be\n        # \"with (yield sem.acquire())\".\n        with self.assertRaises(RuntimeError):\n            with locks.Semaphore():\n                pass\n\n\nclass BoundedSemaphoreTest(AsyncTestCase):\n    def test_release_unacquired(self):\n        sem = locks.BoundedSemaphore()\n        self.assertRaises(ValueError, sem.release)\n        # Value is 0.\n        sem.acquire()\n        # Block on acquire().\n        future = sem.acquire()\n        self.assertFalse(future.done())\n        sem.release()\n        self.assertTrue(future.done())\n        # Value is 1.\n        sem.release()\n        self.assertRaises(ValueError, sem.release)\n\n\nclass LockTests(AsyncTestCase):\n    def test_repr(self):\n        lock = locks.Lock()\n        # No errors.\n        repr(lock)\n        lock.acquire()\n        repr(lock)\n\n    def test_acquire_release(self):\n        lock = locks.Lock()\n        self.assertTrue(lock.acquire().done())\n        future = lock.acquire()\n        self.assertFalse(future.done())\n        lock.release()\n        self.assertTrue(future.done())\n\n    @gen_test\n    def test_acquire_fifo(self):\n        lock = locks.Lock()\n        self.assertTrue(lock.acquire().done())\n        N = 5\n        history = []\n\n        @gen.coroutine\n        def f(idx):\n            with (yield lock.acquire()):\n                history.append(idx)\n\n        futures = [f(i) for i in range(N)]\n        self.assertFalse(any(future.done() for future in futures))\n        lock.release()\n        yield futures\n        self.assertEqual(list(range(N)), history)\n\n    @gen_test\n    def test_acquire_timeout(self):\n        lock = locks.Lock()\n        lock.acquire()\n        with self.assertRaises(gen.TimeoutError):\n            yield lock.acquire(deadline=timedelta(seconds=0.01))\n\n        # Still locked.\n        self.assertFalse(lock.acquire().done())\n\n    def test_multi_release(self):\n        lock = locks.Lock()\n        self.assertRaises(RuntimeError, lock.release)\n        lock.acquire()\n        lock.release()\n        self.assertRaises(RuntimeError, lock.release)\n\n    @gen_test\n    def test_yield_lock(self):\n        # Ensure we catch a \"with (yield lock)\", which should be\n        # \"with (yield lock.acquire())\".\n        with self.assertRaises(gen.BadYieldError):\n            with (yield locks.Lock()):\n                pass\n\n    def test_context_manager_misuse(self):\n        # Ensure we catch a \"with lock\", which should be\n        # \"with (yield lock.acquire())\".\n        with self.assertRaises(RuntimeError):\n            with locks.Lock():\n                pass\n\n\nif __name__ == '__main__':\n    unittest.main()\n",
            "new_file_content": "# Licensed under the Apache License, Version 2.0 (the \"License\"); you may\n# not use this file except in compliance with the License. You may obtain\n# a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n# License for the specific language governing permissions and limitations\n# under the License.\n\nfrom datetime import timedelta\n\nfrom tornado import gen, locks\nfrom tornado.gen import TimeoutError\nfrom tornado.testing import gen_test, AsyncTestCase\nfrom tornado.test.util import unittest\n\n\nclass ConditionTest(AsyncTestCase):\n    def setUp(self):\n        super(ConditionTest, self).setUp()\n        self.history = []\n\n    def record_done(self, future, key):\n        \"\"\"Record the resolution of a Future returned by Condition.wait.\"\"\"\n        def callback(_):\n            if not future.result():\n                # wait() resolved to False, meaning it timed out.\n                self.history.append('timeout')\n            else:\n                self.history.append(key)\n        future.add_done_callback(callback)\n\n    def test_repr(self):\n        c = locks.Condition()\n        self.assertIn('Condition', repr(c))\n        self.assertNotIn('waiters', repr(c))\n        c.wait()\n        self.assertIn('waiters', repr(c))\n\n    @gen_test\n    def test_notify(self):\n        c = locks.Condition()\n        self.io_loop.call_later(0.01, c.notify)\n        yield c.wait()\n\n    def test_notify_1(self):\n        c = locks.Condition()\n        self.record_done(c.wait(), 'wait1')\n        self.record_done(c.wait(), 'wait2')\n        c.notify(1)\n        self.history.append('notify1')\n        c.notify(1)\n        self.history.append('notify2')\n        self.assertEqual(['wait1', 'notify1', 'wait2', 'notify2'],\n                         self.history)\n\n    def test_notify_n(self):\n        c = locks.Condition()\n        for i in range(6):\n            self.record_done(c.wait(), i)\n\n        c.notify(3)\n\n        # Callbacks execute in the order they were registered.\n        self.assertEqual(list(range(3)), self.history)\n        c.notify(1)\n        self.assertEqual(list(range(4)), self.history)\n        c.notify(2)\n        self.assertEqual(list(range(6)), self.history)\n\n    def test_notify_all(self):\n        c = locks.Condition()\n        for i in range(4):\n            self.record_done(c.wait(), i)\n\n        c.notify_all()\n        self.history.append('notify_all')\n\n        # Callbacks execute in the order they were registered.\n        self.assertEqual(\n            list(range(4)) + ['notify_all'],\n            self.history)\n\n    @gen_test\n    def test_wait_timeout(self):\n        c = locks.Condition()\n        wait = c.wait(timedelta(seconds=0.01))\n        self.io_loop.call_later(0.02, c.notify)  # Too late.\n        yield gen.sleep(0.03)\n        self.assertFalse((yield wait))\n\n    @gen_test\n    def test_wait_timeout_preempted(self):\n        c = locks.Condition()\n\n        # This fires before the wait times out.\n        self.io_loop.call_later(0.01, c.notify)\n        wait = c.wait(timedelta(seconds=0.02))\n        yield gen.sleep(0.03)\n        yield wait  # No TimeoutError.\n\n    @gen_test\n    def test_notify_n_with_timeout(self):\n        # Register callbacks 0, 1, 2, and 3. Callback 1 has a timeout.\n        # Wait for that timeout to expire, then do notify(2) and make\n        # sure everyone runs. Verifies that a timed-out callback does\n        # not count against the 'n' argument to notify().\n        c = locks.Condition()\n        self.record_done(c.wait(), 0)\n        self.record_done(c.wait(timedelta(seconds=0.01)), 1)\n        self.record_done(c.wait(), 2)\n        self.record_done(c.wait(), 3)\n\n        # Wait for callback 1 to time out.\n        yield gen.sleep(0.02)\n        self.assertEqual(['timeout'], self.history)\n\n        c.notify(2)\n        yield gen.sleep(0.01)\n        self.assertEqual(['timeout', 0, 2], self.history)\n        self.assertEqual(['timeout', 0, 2], self.history)\n        c.notify()\n        self.assertEqual(['timeout', 0, 2, 3], self.history)\n\n    @gen_test\n    def test_notify_all_with_timeout(self):\n        c = locks.Condition()\n        self.record_done(c.wait(), 0)\n        self.record_done(c.wait(timedelta(seconds=0.01)), 1)\n        self.record_done(c.wait(), 2)\n\n        # Wait for callback 1 to time out.\n        yield gen.sleep(0.02)\n        self.assertEqual(['timeout'], self.history)\n\n        c.notify_all()\n        self.assertEqual(['timeout', 0, 2], self.history)\n\n    @gen_test\n    def test_nested_notify(self):\n        # Ensure no notifications lost, even if notify() is reentered by a\n        # waiter calling notify().\n        c = locks.Condition()\n\n        # Three waiters.\n        futures = [c.wait() for _ in range(3)]\n\n        # First and second futures resolved. Second future reenters notify(),\n        # resolving third future.\n        futures[1].add_done_callback(lambda _: c.notify())\n        c.notify(2)\n        self.assertTrue(all(f.done() for f in futures))\n\n    @gen_test\n    def test_garbage_collection(self):\n        # Test that timed-out waiters are occasionally cleaned from the queue.\n        c = locks.Condition()\n        for _ in range(101):\n            c.wait(timedelta(seconds=0.01))\n\n        future = c.wait()\n        self.assertEqual(102, len(c._waiters))\n\n        # Let first 101 waiters time out, triggering a collection.\n        yield gen.sleep(0.02)\n        self.assertEqual(1, len(c._waiters))\n\n        # Final waiter is still active.\n        self.assertFalse(future.done())\n        c.notify()\n        self.assertTrue(future.done())\n\n\nclass EventTest(AsyncTestCase):\n    def test_repr(self):\n        event = locks.Event()\n        self.assertTrue('clear' in str(event))\n        self.assertFalse('set' in str(event))\n        event.set()\n        self.assertFalse('clear' in str(event))\n        self.assertTrue('set' in str(event))\n\n    def test_event(self):\n        e = locks.Event()\n        future_0 = e.wait()\n        e.set()\n        future_1 = e.wait()\n        e.clear()\n        future_2 = e.wait()\n\n        self.assertTrue(future_0.done())\n        self.assertTrue(future_1.done())\n        self.assertFalse(future_2.done())\n\n    @gen_test\n    def test_event_timeout(self):\n        e = locks.Event()\n        with self.assertRaises(TimeoutError):\n            yield e.wait(timedelta(seconds=0.01))\n\n        # After a timed-out waiter, normal operation works.\n        self.io_loop.add_timeout(timedelta(seconds=0.01), e.set)\n        yield e.wait(timedelta(seconds=1))\n\n    def test_event_set_multiple(self):\n        e = locks.Event()\n        e.set()\n        e.set()\n        self.assertTrue(e.is_set())\n\n    def test_event_wait_clear(self):\n        e = locks.Event()\n        f0 = e.wait()\n        e.clear()\n        f1 = e.wait()\n        e.set()\n        self.assertTrue(f0.done())\n        self.assertTrue(f1.done())\n\n\nclass SemaphoreTest(AsyncTestCase):\n    def test_negative_value(self):\n        self.assertRaises(ValueError, locks.Semaphore, value=-1)\n\n    def test_repr(self):\n        sem = locks.Semaphore()\n        self.assertIn('Semaphore', repr(sem))\n        self.assertIn('unlocked,value:1', repr(sem))\n        sem.acquire()\n        self.assertIn('locked', repr(sem))\n        self.assertNotIn('waiters', repr(sem))\n        sem.acquire()\n        self.assertIn('waiters', repr(sem))\n\n    def test_acquire(self):\n        sem = locks.Semaphore()\n        f0 = sem.acquire()\n        self.assertTrue(f0.done())\n\n        # Wait for release().\n        f1 = sem.acquire()\n        self.assertFalse(f1.done())\n        f2 = sem.acquire()\n        sem.release()\n        self.assertTrue(f1.done())\n        self.assertFalse(f2.done())\n        sem.release()\n        self.assertTrue(f2.done())\n\n        sem.release()\n        # Now acquire() is instant.\n        self.assertTrue(sem.acquire().done())\n        self.assertEqual(0, len(sem._waiters))\n\n    @gen_test\n    def test_acquire_timeout(self):\n        sem = locks.Semaphore(2)\n        yield sem.acquire()\n        yield sem.acquire()\n        acquire = sem.acquire(timedelta(seconds=0.01))\n        self.io_loop.call_later(0.02, sem.release)  # Too late.\n        yield gen.sleep(0.3)\n        with self.assertRaises(gen.TimeoutError):\n            yield acquire\n\n        sem.acquire()\n        f = sem.acquire()\n        self.assertFalse(f.done())\n        sem.release()\n        self.assertTrue(f.done())\n\n    @gen_test\n    def test_acquire_timeout_preempted(self):\n        sem = locks.Semaphore(1)\n        yield sem.acquire()\n\n        # This fires before the wait times out.\n        self.io_loop.call_later(0.01, sem.release)\n        acquire = sem.acquire(timedelta(seconds=0.02))\n        yield gen.sleep(0.03)\n        yield acquire  # No TimeoutError.\n\n    def test_release_unacquired(self):\n        # Unbounded releases are allowed, and increment the semaphore's value.\n        sem = locks.Semaphore()\n        sem.release()\n        sem.release()\n\n        # Now the counter is 3. We can acquire three times before blocking.\n        self.assertTrue(sem.acquire().done())\n        self.assertTrue(sem.acquire().done())\n        self.assertTrue(sem.acquire().done())\n        self.assertFalse(sem.acquire().done())\n\n    @gen_test\n    def test_garbage_collection(self):\n        # Test that timed-out waiters are occasionally cleaned from the queue.\n        sem = locks.Semaphore(value=0)\n        futures = [sem.acquire(timedelta(seconds=0.01)) for _ in range(101)]\n\n        future = sem.acquire()\n        self.assertEqual(102, len(sem._waiters))\n\n        # Let first 101 waiters time out, triggering a collection.\n        yield gen.sleep(0.02)\n        self.assertEqual(1, len(sem._waiters))\n\n        # Final waiter is still active.\n        self.assertFalse(future.done())\n        sem.release()\n        self.assertTrue(future.done())\n\n        # Prevent \"Future exception was never retrieved\" messages.\n        for future in futures:\n            self.assertRaises(TimeoutError, future.result)\n\n\nclass SemaphoreContextManagerTest(AsyncTestCase):\n    @gen_test\n    def test_context_manager(self):\n        sem = locks.Semaphore()\n        with (yield sem.acquire()) as yielded:\n            self.assertTrue(yielded is None)\n\n        # Semaphore was released and can be acquired again.\n        self.assertTrue(sem.acquire().done())\n\n    @gen_test\n    def test_context_manager_exception(self):\n        sem = locks.Semaphore()\n        with self.assertRaises(ZeroDivisionError):\n            with (yield sem.acquire()):\n                1 / 0\n\n        # Semaphore was released and can be acquired again.\n        self.assertTrue(sem.acquire().done())\n\n    @gen_test\n    def test_context_manager_timeout(self):\n        sem = locks.Semaphore()\n        with (yield sem.acquire(timedelta(seconds=0.01))):\n            pass\n\n        # Semaphore was released and can be acquired again.\n        self.assertTrue(sem.acquire().done())\n\n    @gen_test\n    def test_context_manager_timeout_error(self):\n        sem = locks.Semaphore(value=0)\n        with self.assertRaises(gen.TimeoutError):\n            with (yield sem.acquire(timedelta(seconds=0.01))):\n                pass\n\n        # Counter is still 0.\n        self.assertFalse(sem.acquire().done())\n\n    @gen_test\n    def test_context_manager_contended(self):\n        sem = locks.Semaphore()\n        history = []\n\n        @gen.coroutine\n        def f(index):\n            with (yield sem.acquire()):\n                history.append('acquired %d' % index)\n                yield gen.sleep(0.01)\n                history.append('release %d' % index)\n\n        yield [f(i) for i in range(2)]\n\n        expected_history = []\n        for i in range(2):\n            expected_history.extend(['acquired %d' % i, 'release %d' % i])\n\n        self.assertEqual(expected_history, history)\n\n    @gen_test\n    def test_yield_sem(self):\n        # Ensure we catch a \"with (yield sem)\", which should be\n        # \"with (yield sem.acquire())\".\n        with self.assertRaises(gen.BadYieldError):\n            with (yield locks.Semaphore()):\n                pass\n\n    def test_context_manager_misuse(self):\n        # Ensure we catch a \"with sem\", which should be\n        # \"with (yield sem.acquire())\".\n        with self.assertRaises(RuntimeError):\n            with locks.Semaphore():\n                pass\n\n\nclass BoundedSemaphoreTest(AsyncTestCase):\n    def test_release_unacquired(self):\n        sem = locks.BoundedSemaphore()\n        self.assertRaises(ValueError, sem.release)\n        # Value is 0.\n        sem.acquire()\n        # Block on acquire().\n        future = sem.acquire()\n        self.assertFalse(future.done())\n        sem.release()\n        self.assertTrue(future.done())\n        # Value is 1.\n        sem.release()\n        self.assertRaises(ValueError, sem.release)\n\n\nclass LockTests(AsyncTestCase):\n    def test_repr(self):\n        lock = locks.Lock()\n        # No errors.\n        repr(lock)\n        lock.acquire()\n        repr(lock)\n\n    def test_acquire_release(self):\n        lock = locks.Lock()\n        self.assertTrue(lock.acquire().done())\n        future = lock.acquire()\n        self.assertFalse(future.done())\n        lock.release()\n        self.assertTrue(future.done())\n\n    @gen_test\n    def test_acquire_fifo(self):\n        lock = locks.Lock()\n        self.assertTrue(lock.acquire().done())\n        N = 5\n        history = []\n\n        @gen.coroutine\n        def f(idx):\n            with (yield lock.acquire()):\n                history.append(idx)\n\n        futures = [f(i) for i in range(N)]\n        self.assertFalse(any(future.done() for future in futures))\n        lock.release()\n        yield futures\n        self.assertEqual(list(range(N)), history)\n\n    @gen_test\n    def test_acquire_timeout(self):\n        lock = locks.Lock()\n        lock.acquire()\n        with self.assertRaises(gen.TimeoutError):\n            yield lock.acquire(timeout=timedelta(seconds=0.01))\n\n        # Still locked.\n        self.assertFalse(lock.acquire().done())\n\n    def test_multi_release(self):\n        lock = locks.Lock()\n        self.assertRaises(RuntimeError, lock.release)\n        lock.acquire()\n        lock.release()\n        self.assertRaises(RuntimeError, lock.release)\n\n    @gen_test\n    def test_yield_lock(self):\n        # Ensure we catch a \"with (yield lock)\", which should be\n        # \"with (yield lock.acquire())\".\n        with self.assertRaises(gen.BadYieldError):\n            with (yield locks.Lock()):\n                pass\n\n    def test_context_manager_misuse(self):\n        # Ensure we catch a \"with lock\", which should be\n        # \"with (yield lock.acquire())\".\n        with self.assertRaises(RuntimeError):\n            with locks.Lock():\n                pass\n\n\nif __name__ == '__main__':\n    unittest.main()\n",
            "header": {
                "file": {
                    "path": "tornado/test/locks_test.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "49161287",
                "new_commit_hash": "90bdafaa",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/tornado/test/locks_test.py"
            },
            "plus_file": {
                "path": "b/tornado/test/locks_test.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 448,
                            "length": 7
                        },
                        "new_range": {
                            "start": 448,
                            "length": 7
                        },
                        "section": "class LockTests(AsyncTestCase):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        lock = locks.Lock()",
                                "type": "context"
                            },
                            {
                                "content": "        lock.acquire()",
                                "type": "context"
                            },
                            {
                                "content": "        with self.assertRaises(gen.TimeoutError):",
                                "type": "context"
                            },
                            {
                                "content": "            yield lock.acquire(deadline=timedelta(seconds=0.01))",
                                "type": "deleted"
                            },
                            {
                                "content": "            yield lock.acquire(timeout=timedelta(seconds=0.01))",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "        # Still locked.",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertFalse(lock.acquire().done())",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/test/locks_test.py",
                            "type": "class",
                            "name": "LockTests",
                            "content": "class LockTests(AsyncTestCase):\n    def test_repr(self):\n        lock = locks.Lock()\n        # No errors.\n        repr(lock)\n        lock.acquire()\n        repr(lock)\n\n    def test_acquire_release(self):\n        lock = locks.Lock()\n        self.assertTrue(lock.acquire().done())\n        future = lock.acquire()\n        self.assertFalse(future.done())\n        lock.release()\n        self.assertTrue(future.done())\n\n    @gen_test\n    def test_acquire_fifo(self):\n        lock = locks.Lock()\n        self.assertTrue(lock.acquire().done())\n        N = 5\n        history = []\n\n        @gen.coroutine\n        def f(idx):\n            with (yield lock.acquire()):\n                history.append(idx)\n\n        futures = [f(i) for i in range(N)]\n        self.assertFalse(any(future.done() for future in futures))\n        lock.release()\n        yield futures\n        self.assertEqual(list(range(N)), history)\n\n    @gen_test\n    def test_acquire_timeout(self):\n        lock = locks.Lock()\n        lock.acquire()\n        with self.assertRaises(gen.TimeoutError):\n            yield lock.acquire(deadline=timedelta(seconds=0.01))\n\n        # Still locked.\n        self.assertFalse(lock.acquire().done())\n\n    def test_multi_release(self):\n        lock = locks.Lock()\n        self.assertRaises(RuntimeError, lock.release)\n        lock.acquire()\n        lock.release()\n        self.assertRaises(RuntimeError, lock.release)\n\n    @gen_test\n    def test_yield_lock(self):\n        # Ensure we catch a \"with (yield lock)\", which should be\n        # \"with (yield lock.acquire())\".\n        with self.assertRaises(gen.BadYieldError):\n            with (yield locks.Lock()):\n                pass\n\n    def test_context_manager_misuse(self):\n        # Ensure we catch a \"with lock\", which should be\n        # \"with (yield lock.acquire())\".\n        with self.assertRaises(RuntimeError):\n            with locks.Lock():\n                pass",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 412,
                            "end_lineno": 476,
                            "parent": null
                        },
                        {
                            "file_name": "tornado/test/locks_test.py",
                            "type": "method",
                            "name": "LockTests.test_acquire_timeout",
                            "content": "class LockTests(AsyncTestCase):\n    def test_repr(self):\n        lock = locks.Lock()\n        # No errors.\n        repr(lock)\n        lock.acquire()\n        repr(lock)\n\n    def test_acquire_release(self):\n        lock = locks.Lock()\n        self.assertTrue(lock.acquire().done())\n        future = lock.acquire()\n        self.assertFalse(future.done())\n        lock.release()\n        self.assertTrue(future.done())\n\n    @gen_test\n    def test_acquire_fifo(self):\n        lock = locks.Lock()\n        self.assertTrue(lock.acquire().done())\n        N = 5\n        history = []\n\n        @gen.coroutine\n        def f(idx):\n            with (yield lock.acquire()):\n                history.append(idx)\n\n        futures = [f(i) for i in range(N)]\n        self.assertFalse(any(future.done() for future in futures))\n        lock.release()\n        yield futures\n        self.assertEqual(list(range(N)), history)\n\n    @gen_test\n    def test_acquire_timeout(self):\n        lock = locks.Lock()\n        lock.acquire()\n        with self.assertRaises(gen.TimeoutError):\n            yield lock.acquire(deadline=timedelta(seconds=0.01))\n\n        # Still locked.\n        self.assertFalse(lock.acquire().done())\n\n    def test_multi_release(self):\n        lock = locks.Lock()\n        self.assertRaises(RuntimeError, lock.release)\n        lock.acquire()\n        lock.release()\n        self.assertRaises(RuntimeError, lock.release)\n\n    @gen_test\n    def test_yield_lock(self):\n        # Ensure we catch a \"with (yield lock)\", which should be\n        # \"with (yield lock.acquire())\".\n        with self.assertRaises(gen.BadYieldError):\n            with (yield locks.Lock()):\n                pass\n\n    def test_context_manager_misuse(self):\n        # Ensure we catch a \"with lock\", which should be\n        # \"with (yield lock.acquire())\".\n        with self.assertRaises(RuntimeError):\n            with locks.Lock():\n                pass",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 447,
                            "end_lineno": 454,
                            "parent": {
                                "file_name": "tornado/test/locks_test.py",
                                "type": "class",
                                "name": "LockTests",
                                "content": "class LockTests(AsyncTestCase):\n    def test_repr(self):\n        lock = locks.Lock()\n        # No errors.\n        repr(lock)\n        lock.acquire()\n        repr(lock)\n\n    def test_acquire_release(self):\n        lock = locks.Lock()\n        self.assertTrue(lock.acquire().done())\n        future = lock.acquire()\n        self.assertFalse(future.done())\n        lock.release()\n        self.assertTrue(future.done())\n\n    @gen_test\n    def test_acquire_fifo(self):\n        lock = locks.Lock()\n        self.assertTrue(lock.acquire().done())\n        N = 5\n        history = []\n\n        @gen.coroutine\n        def f(idx):\n            with (yield lock.acquire()):\n                history.append(idx)\n\n        futures = [f(i) for i in range(N)]\n        self.assertFalse(any(future.done() for future in futures))\n        lock.release()\n        yield futures\n        self.assertEqual(list(range(N)), history)\n\n    @gen_test\n    def test_acquire_timeout(self):\n        lock = locks.Lock()\n        lock.acquire()\n        with self.assertRaises(gen.TimeoutError):\n            yield lock.acquire(deadline=timedelta(seconds=0.01))\n\n        # Still locked.\n        self.assertFalse(lock.acquire().done())\n\n    def test_multi_release(self):\n        lock = locks.Lock()\n        self.assertRaises(RuntimeError, lock.release)\n        lock.acquire()\n        lock.release()\n        self.assertRaises(RuntimeError, lock.release)\n\n    @gen_test\n    def test_yield_lock(self):\n        # Ensure we catch a \"with (yield lock)\", which should be\n        # \"with (yield lock.acquire())\".\n        with self.assertRaises(gen.BadYieldError):\n            with (yield locks.Lock()):\n                pass\n\n    def test_context_manager_misuse(self):\n        # Ensure we catch a \"with lock\", which should be\n        # \"with (yield lock.acquire())\".\n        with self.assertRaises(RuntimeError):\n            with locks.Lock():\n                pass",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 412,
                                "end_lineno": 476,
                                "parent": null
                            }
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        }
    ],
    "old_commit_hash": "8b1c466cbf12d593255457247404c00f9c7fa4c1^",
    "new_commit_hash": "8b1c466cbf12d593255457247404c00f9c7fa4c1",
    "commit_message": "Replace 'deadline' with 'timeout' for Lock.acquire.",
    "commit_date": "2015-04-18T22:43:56-04:00",
    "metadata": {}
}
{
    "repo_name": "tornado",
    "new_commit_hash": "8b1c466cbf12d593255457247404c00f9c7fa4c1",
    "test_file_codes": [
        "# Licensed under the Apache License, Version 2.0 (the \"License\"); you may\n# not use this file except in compliance with the License. You may obtain\n# a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n# License for the specific language governing permissions and limitations\n# under the License.\n\nfrom datetime import timedelta\n\nfrom tornado import gen, locks\nfrom tornado.gen import TimeoutError\nfrom tornado.testing import gen_test, AsyncTestCase\nfrom tornado.test.util import unittest\n\n\nclass ConditionTest(AsyncTestCase):\n    def setUp(self):\n        super(ConditionTest, self).setUp()\n        self.history = []\n\n    def record_done(self, future, key):\n        \"\"\"Record the resolution of a Future returned by Condition.wait.\"\"\"\n        def callback(_):\n            if not future.result():\n                # wait() resolved to False, meaning it timed out.\n                self.history.append('timeout')\n            else:\n                self.history.append(key)\n        future.add_done_callback(callback)\n\n    def test_repr(self):\n        c = locks.Condition()\n        self.assertIn('Condition', repr(c))\n        self.assertNotIn('waiters', repr(c))\n        c.wait()\n        self.assertIn('waiters', repr(c))\n\n    @gen_test\n    def test_notify(self):\n        c = locks.Condition()\n        self.io_loop.call_later(0.01, c.notify)\n        yield c.wait()\n\n    def test_notify_1(self):\n        c = locks.Condition()\n        self.record_done(c.wait(), 'wait1')\n        self.record_done(c.wait(), 'wait2')\n        c.notify(1)\n        self.history.append('notify1')\n        c.notify(1)\n        self.history.append('notify2')\n        self.assertEqual(['wait1', 'notify1', 'wait2', 'notify2'],\n                         self.history)\n\n    def test_notify_n(self):\n        c = locks.Condition()\n        for i in range(6):\n            self.record_done(c.wait(), i)\n\n        c.notify(3)\n\n        # Callbacks execute in the order they were registered.\n        self.assertEqual(list(range(3)), self.history)\n        c.notify(1)\n        self.assertEqual(list(range(4)), self.history)\n        c.notify(2)\n        self.assertEqual(list(range(6)), self.history)\n\n    def test_notify_all(self):\n        c = locks.Condition()\n        for i in range(4):\n            self.record_done(c.wait(), i)\n\n        c.notify_all()\n        self.history.append('notify_all')\n\n        # Callbacks execute in the order they were registered.\n        self.assertEqual(\n            list(range(4)) + ['notify_all'],\n            self.history)\n\n    @gen_test\n    def test_wait_timeout(self):\n        c = locks.Condition()\n        wait = c.wait(timedelta(seconds=0.01))\n        self.io_loop.call_later(0.02, c.notify)  # Too late.\n        yield gen.sleep(0.03)\n        self.assertFalse((yield wait))\n\n    @gen_test\n    def test_wait_timeout_preempted(self):\n        c = locks.Condition()\n\n        # This fires before the wait times out.\n        self.io_loop.call_later(0.01, c.notify)\n        wait = c.wait(timedelta(seconds=0.02))\n        yield gen.sleep(0.03)\n        yield wait  # No TimeoutError.\n\n    @gen_test\n    def test_notify_n_with_timeout(self):\n        # Register callbacks 0, 1, 2, and 3. Callback 1 has a timeout.\n        # Wait for that timeout to expire, then do notify(2) and make\n        # sure everyone runs. Verifies that a timed-out callback does\n        # not count against the 'n' argument to notify().\n        c = locks.Condition()\n        self.record_done(c.wait(), 0)\n        self.record_done(c.wait(timedelta(seconds=0.01)), 1)\n        self.record_done(c.wait(), 2)\n        self.record_done(c.wait(), 3)\n\n        # Wait for callback 1 to time out.\n        yield gen.sleep(0.02)\n        self.assertEqual(['timeout'], self.history)\n\n        c.notify(2)\n        yield gen.sleep(0.01)\n        self.assertEqual(['timeout', 0, 2], self.history)\n        self.assertEqual(['timeout', 0, 2], self.history)\n        c.notify()\n        self.assertEqual(['timeout', 0, 2, 3], self.history)\n\n    @gen_test\n    def test_notify_all_with_timeout(self):\n        c = locks.Condition()\n        self.record_done(c.wait(), 0)\n        self.record_done(c.wait(timedelta(seconds=0.01)), 1)\n        self.record_done(c.wait(), 2)\n\n        # Wait for callback 1 to time out.\n        yield gen.sleep(0.02)\n        self.assertEqual(['timeout'], self.history)\n\n        c.notify_all()\n        self.assertEqual(['timeout', 0, 2], self.history)\n\n    @gen_test\n    def test_nested_notify(self):\n        # Ensure no notifications lost, even if notify() is reentered by a\n        # waiter calling notify().\n        c = locks.Condition()\n\n        # Three waiters.\n        futures = [c.wait() for _ in range(3)]\n\n        # First and second futures resolved. Second future reenters notify(),\n        # resolving third future.\n        futures[1].add_done_callback(lambda _: c.notify())\n        c.notify(2)\n        self.assertTrue(all(f.done() for f in futures))\n\n    @gen_test\n    def test_garbage_collection(self):\n        # Test that timed-out waiters are occasionally cleaned from the queue.\n        c = locks.Condition()\n        for _ in range(101):\n            c.wait(timedelta(seconds=0.01))\n\n        future = c.wait()\n        self.assertEqual(102, len(c._waiters))\n\n        # Let first 101 waiters time out, triggering a collection.\n        yield gen.sleep(0.02)\n        self.assertEqual(1, len(c._waiters))\n\n        # Final waiter is still active.\n        self.assertFalse(future.done())\n        c.notify()\n        self.assertTrue(future.done())\n\n\nclass EventTest(AsyncTestCase):\n    def test_repr(self):\n        event = locks.Event()\n        self.assertTrue('clear' in str(event))\n        self.assertFalse('set' in str(event))\n        event.set()\n        self.assertFalse('clear' in str(event))\n        self.assertTrue('set' in str(event))\n\n    def test_event(self):\n        e = locks.Event()\n        future_0 = e.wait()\n        e.set()\n        future_1 = e.wait()\n        e.clear()\n        future_2 = e.wait()\n\n        self.assertTrue(future_0.done())\n        self.assertTrue(future_1.done())\n        self.assertFalse(future_2.done())\n\n    @gen_test\n    def test_event_timeout(self):\n        e = locks.Event()\n        with self.assertRaises(TimeoutError):\n            yield e.wait(timedelta(seconds=0.01))\n\n        # After a timed-out waiter, normal operation works.\n        self.io_loop.add_timeout(timedelta(seconds=0.01), e.set)\n        yield e.wait(timedelta(seconds=1))\n\n    def test_event_set_multiple(self):\n        e = locks.Event()\n        e.set()\n        e.set()\n        self.assertTrue(e.is_set())\n\n    def test_event_wait_clear(self):\n        e = locks.Event()\n        f0 = e.wait()\n        e.clear()\n        f1 = e.wait()\n        e.set()\n        self.assertTrue(f0.done())\n        self.assertTrue(f1.done())\n\n\nclass SemaphoreTest(AsyncTestCase):\n    def test_negative_value(self):\n        self.assertRaises(ValueError, locks.Semaphore, value=-1)\n\n    def test_repr(self):\n        sem = locks.Semaphore()\n        self.assertIn('Semaphore', repr(sem))\n        self.assertIn('unlocked,value:1', repr(sem))\n        sem.acquire()\n        self.assertIn('locked', repr(sem))\n        self.assertNotIn('waiters', repr(sem))\n        sem.acquire()\n        self.assertIn('waiters', repr(sem))\n\n    def test_acquire(self):\n        sem = locks.Semaphore()\n        f0 = sem.acquire()\n        self.assertTrue(f0.done())\n\n        # Wait for release().\n        f1 = sem.acquire()\n        self.assertFalse(f1.done())\n        f2 = sem.acquire()\n        sem.release()\n        self.assertTrue(f1.done())\n        self.assertFalse(f2.done())\n        sem.release()\n        self.assertTrue(f2.done())\n\n        sem.release()\n        # Now acquire() is instant.\n        self.assertTrue(sem.acquire().done())\n        self.assertEqual(0, len(sem._waiters))\n\n    @gen_test\n    def test_acquire_timeout(self):\n        sem = locks.Semaphore(2)\n        yield sem.acquire()\n        yield sem.acquire()\n        acquire = sem.acquire(timedelta(seconds=0.01))\n        self.io_loop.call_later(0.02, sem.release)  # Too late.\n        yield gen.sleep(0.3)\n        with self.assertRaises(gen.TimeoutError):\n            yield acquire\n\n        sem.acquire()\n        f = sem.acquire()\n        self.assertFalse(f.done())\n        sem.release()\n        self.assertTrue(f.done())\n\n    @gen_test\n    def test_acquire_timeout_preempted(self):\n        sem = locks.Semaphore(1)\n        yield sem.acquire()\n\n        # This fires before the wait times out.\n        self.io_loop.call_later(0.01, sem.release)\n        acquire = sem.acquire(timedelta(seconds=0.02))\n        yield gen.sleep(0.03)\n        yield acquire  # No TimeoutError.\n\n    def test_release_unacquired(self):\n        # Unbounded releases are allowed, and increment the semaphore's value.\n        sem = locks.Semaphore()\n        sem.release()\n        sem.release()\n\n        # Now the counter is 3. We can acquire three times before blocking.\n        self.assertTrue(sem.acquire().done())\n        self.assertTrue(sem.acquire().done())\n        self.assertTrue(sem.acquire().done())\n        self.assertFalse(sem.acquire().done())\n\n    @gen_test\n    def test_garbage_collection(self):\n        # Test that timed-out waiters are occasionally cleaned from the queue.\n        sem = locks.Semaphore(value=0)\n        futures = [sem.acquire(timedelta(seconds=0.01)) for _ in range(101)]\n\n        future = sem.acquire()\n        self.assertEqual(102, len(sem._waiters))\n\n        # Let first 101 waiters time out, triggering a collection.\n        yield gen.sleep(0.02)\n        self.assertEqual(1, len(sem._waiters))\n\n        # Final waiter is still active.\n        self.assertFalse(future.done())\n        sem.release()\n        self.assertTrue(future.done())\n\n        # Prevent \"Future exception was never retrieved\" messages.\n        for future in futures:\n            self.assertRaises(TimeoutError, future.result)\n\n\nclass SemaphoreContextManagerTest(AsyncTestCase):\n    @gen_test\n    def test_context_manager(self):\n        sem = locks.Semaphore()\n        with (yield sem.acquire()) as yielded:\n            self.assertTrue(yielded is None)\n\n        # Semaphore was released and can be acquired again.\n        self.assertTrue(sem.acquire().done())\n\n    @gen_test\n    def test_context_manager_exception(self):\n        sem = locks.Semaphore()\n        with self.assertRaises(ZeroDivisionError):\n            with (yield sem.acquire()):\n                1 / 0\n\n        # Semaphore was released and can be acquired again.\n        self.assertTrue(sem.acquire().done())\n\n    @gen_test\n    def test_context_manager_timeout(self):\n        sem = locks.Semaphore()\n        with (yield sem.acquire(timedelta(seconds=0.01))):\n            pass\n\n        # Semaphore was released and can be acquired again.\n        self.assertTrue(sem.acquire().done())\n\n    @gen_test\n    def test_context_manager_timeout_error(self):\n        sem = locks.Semaphore(value=0)\n        with self.assertRaises(gen.TimeoutError):\n            with (yield sem.acquire(timedelta(seconds=0.01))):\n                pass\n\n        # Counter is still 0.\n        self.assertFalse(sem.acquire().done())\n\n    @gen_test\n    def test_context_manager_contended(self):\n        sem = locks.Semaphore()\n        history = []\n\n        @gen.coroutine\n        def f(index):\n            with (yield sem.acquire()):\n                history.append('acquired %d' % index)\n                yield gen.sleep(0.01)\n                history.append('release %d' % index)\n\n        yield [f(i) for i in range(2)]\n\n        expected_history = []\n        for i in range(2):\n            expected_history.extend(['acquired %d' % i, 'release %d' % i])\n\n        self.assertEqual(expected_history, history)\n\n    @gen_test\n    def test_yield_sem(self):\n        # Ensure we catch a \"with (yield sem)\", which should be\n        # \"with (yield sem.acquire())\".\n        with self.assertRaises(gen.BadYieldError):\n            with (yield locks.Semaphore()):\n                pass\n\n    def test_context_manager_misuse(self):\n        # Ensure we catch a \"with sem\", which should be\n        # \"with (yield sem.acquire())\".\n        with self.assertRaises(RuntimeError):\n            with locks.Semaphore():\n                pass\n\n\nclass BoundedSemaphoreTest(AsyncTestCase):\n    def test_release_unacquired(self):\n        sem = locks.BoundedSemaphore()\n        self.assertRaises(ValueError, sem.release)\n        # Value is 0.\n        sem.acquire()\n        # Block on acquire().\n        future = sem.acquire()\n        self.assertFalse(future.done())\n        sem.release()\n        self.assertTrue(future.done())\n        # Value is 1.\n        sem.release()\n        self.assertRaises(ValueError, sem.release)\n\n\nclass LockTests(AsyncTestCase):\n    def test_repr(self):\n        lock = locks.Lock()\n        # No errors.\n        repr(lock)\n        lock.acquire()\n        repr(lock)\n\n    def test_acquire_release(self):\n        lock = locks.Lock()\n        self.assertTrue(lock.acquire().done())\n        future = lock.acquire()\n        self.assertFalse(future.done())\n        lock.release()\n        self.assertTrue(future.done())\n\n    @gen_test\n    def test_acquire_fifo(self):\n        lock = locks.Lock()\n        self.assertTrue(lock.acquire().done())\n        N = 5\n        history = []\n\n        @gen.coroutine\n        def f(idx):\n            with (yield lock.acquire()):\n                history.append(idx)\n\n        futures = [f(i) for i in range(N)]\n        self.assertFalse(any(future.done() for future in futures))\n        lock.release()\n        yield futures\n        self.assertEqual(list(range(N)), history)\n\n    @gen_test\n    def test_acquire_timeout(self):\n        lock = locks.Lock()\n        lock.acquire()\n        with self.assertRaises(gen.TimeoutError):\n            yield lock.acquire(timeout=timedelta(seconds=0.01))\n\n        # Still locked.\n        self.assertFalse(lock.acquire().done())\n\n    def test_multi_release(self):\n        lock = locks.Lock()\n        self.assertRaises(RuntimeError, lock.release)\n        lock.acquire()\n        lock.release()\n        self.assertRaises(RuntimeError, lock.release)\n\n    @gen_test\n    def test_yield_lock(self):\n        # Ensure we catch a \"with (yield lock)\", which should be\n        # \"with (yield lock.acquire())\".\n        with self.assertRaises(gen.BadYieldError):\n            with (yield locks.Lock()):\n                pass\n\n    def test_context_manager_misuse(self):\n        # Ensure we catch a \"with lock\", which should be\n        # \"with (yield lock.acquire())\".\n        with self.assertRaises(RuntimeError):\n            with locks.Lock():\n                pass\n\n\nif __name__ == '__main__':\n    unittest.main()\n",
        "#!/usr/bin/env python\nimport unittest\nimport sys\nimport time\nimport traceback\nimport platform\nimport os\n\n\nclass PytestLikeResult(unittest.TestResult):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self.start_time = None\n        # Store (test, outcome, info) for each test:\n        #   outcome ∈ { \"passed\", \"failed\", \"error\", \"skipped\" }\n        #   info can hold the exception or skip reason, etc.\n        self.results = []\n\n    def startTestRun(self):\n        \"\"\"Called once before all tests.\"\"\"\n        self.start_time = time.time()\n        # Print a header similar to pytest\n        print(\"=\" * 29 + \" test session starts \" + \"=\" * 29)\n        # You can customize the platform/versions/paths as you like:\n        print(\n            f\"platform {platform.system().lower()} -- Python {platform.python_version()}\"\n        )\n        print(f\"rootdir: {os.path.abspath(os.curdir)}\")\n\n    def stopTestRun(self):\n        \"\"\"Called once after all tests are done.\"\"\"\n        elapsed = time.time() - self.start_time\n        print()  # blank line after final dot\n\n        # Summarize\n        ntests = len(self.results)\n        print(f\"collected {ntests} items\")\n\n        # Show details of failures/errors\n        failures = [r for r in self.results if r[1] == \"failed\"]\n        errors = [r for r in self.results if r[1] == \"error\"]\n\n        if failures:\n            print(\"\\n\" + \"=\" * 35 + \" FAILURES \" + \"=\" * 35)\n            for test, outcome, err_info in failures:\n                test = test.split(\"::\")\n                if len(test) == 3:\n                    test = f\"{test[1]}.{test[2]}\"\n                else:\n                    test = f\"{test[1]}\"\n                print(f\"__________ {test} __________\")\n                self._print_traceback(err_info)\n        if errors:\n            print(\"\\n\" + \"=\" * 35 + \" ERRORS \" + \"=\" * 37)\n            for test, outcome, err_info in errors:\n                test = test.split(\"::\")\n                if len(test) == 3:\n                    test = f\"{test[1]}.{test[2]}\"\n                else:\n                    test = f\"{test[1]}\"\n                print(f\"__________ {test} __________\")\n                self._print_traceback(err_info)\n\n        # Optional short summary lines for passes/fails/skips\n        print(\"\\n==================== short test summary info ====================\")\n        for test, outcome, info in self.results:\n            if outcome in (\"passed\", \"failed\", \"error\", \"skipped\"):\n                print(f\"{outcome.upper()} {test}\")\n\n        # Final one-line summary: “1 failed, 1 errors, 10 passed in 2.04s”\n        passed_count = sum(1 for r in self.results if r[1] == \"passed\")\n        failed_count = len(failures)\n        error_count = len(errors)\n        skipped_count = sum(1 for r in self.results if r[1] == \"skipped\")\n\n        summary_bits = []\n        if failed_count:\n            summary_bits.append(f\"{failed_count} failed\")\n        if error_count:\n            summary_bits.append(f\"{error_count} error{'s' if error_count != 1 else ''}\")\n        if passed_count:\n            summary_bits.append(f\"{passed_count} passed\")\n        if skipped_count:\n            summary_bits.append(f\"{skipped_count} skipped\")\n\n        summary_str = \", \".join(summary_bits) if summary_bits else \"no tests run\"\n        print(\n            f\"=================== {summary_str} in {elapsed:.2f}s ===================\"\n        )\n\n    def startTest(self, test):\n        \"\"\"Called right before each test method.\"\"\"\n        super().startTest(test)\n        # Print a dot or some indicator\n        print(\".\", end=\"\", flush=True)\n\n    def addSuccess(self, test):\n        super().addSuccess(test)\n        self.results.append((self._test_id(test), \"passed\", None))\n\n    def addFailure(self, test, err):\n        super().addFailure(test, err)\n        self.results.append((self._test_id(test), \"failed\", err))\n\n    def addError(self, test, err):\n        super().addError(test, err)\n        self.results.append((self._test_id(test), \"error\", err))\n\n    def addSkip(self, test, reason):\n        super().addSkip(test, reason)\n        self.results.append((self._test_id(test), \"skipped\", reason))\n\n    def _print_traceback(self, err_info):\n        \"\"\"Helper to print the traceback like pytest does.\"\"\"\n        if isinstance(err_info, tuple) and len(err_info) == 3:\n            exc_type, exc_value, tb = err_info\n            traceback.print_exception(exc_type, exc_value, tb, file=sys.stdout)\n        else:\n            print(str(err_info))\n\n    def _test_id(self, test):\n        try:\n            return f\"{test.__class__.__module__}::{test.__class__.__name__}::{test._testMethodName}\"\n        except AttributeError:\n            # Fallback for _ErrorHolder objects\n            return f\"{test.__class__.__module__}::{test.__class__.__name__}\"\n\n\nclass PytestLikeRunner(unittest.TextTestRunner):\n    \"\"\"A custom TextTestRunner that uses the PytestLikeResult.\"\"\"\n\n    resultclass = PytestLikeResult\n\n    def run(self, test):\n        result = self._makeResult()\n        # Overriding run to ensure we call startTestRun/stopTestRun\n        result.startTestRun()\n        test(result)\n        result.stopTestRun()\n        return result\n\n    def tearDown(self):\n        # Reset signal handlers\n        from twisted.internet import reactor\n\n        reactor.removeAll()\n        reactor.stop()\n        super().tearDown()\n\n\ndef main():\n    loader = unittest.TestLoader()\n    suite = loader.discover(\".\", pattern=\"test_*.py\")  # discover tests in r2e_tests/\n    runner = PytestLikeRunner(verbosity=0)\n    result = runner.run(suite)\n    # Exit with code 0 if all tests passed/skipped, 1 if there were fails/errors\n    sys.exit(not result.wasSuccessful())\n\n\nif __name__ == \"__main__\":\n    main()\n"
    ],
    "test_file_names": [
        "test_1.py",
        "tornado_unittest_runner.py"
    ],
    "setup_res_code": 0,
    "setup_res_stdout": "",
    "setup_res_stderr": "Using CPython 3.9.21\nCreating virtual environment at: .venv\nActivate with: source .venv/bin/activate\nResolved 1 package in 583ms\nPrepared 1 package in 1.05s\nInstalled 1 package in 1ms\n + tornado==4.2.dev1 (from file:///home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_8b1c466cbf12d593255457247404c00f9c7fa4c1)\nResolved 29 packages in 21ms\nInstalled 29 packages in 137ms\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_8b1c466cbf12d593255457247404c00f9c7fa4c1\n......................................\ncollected 38 items\n\n==================== short test summary info ====================\nPASSED r2e_tests.test_1::BoundedSemaphoreTest::test_release_unacquired\nPASSED r2e_tests.test_1::ConditionTest::test_garbage_collection\nPASSED r2e_tests.test_1::ConditionTest::test_nested_notify\nPASSED r2e_tests.test_1::ConditionTest::test_notify\nPASSED r2e_tests.test_1::ConditionTest::test_notify_1\nPASSED r2e_tests.test_1::ConditionTest::test_notify_all\nPASSED r2e_tests.test_1::ConditionTest::test_notify_all_with_timeout\nPASSED r2e_tests.test_1::ConditionTest::test_notify_n\nPASSED r2e_tests.test_1::ConditionTest::test_notify_n_with_timeout\nPASSED r2e_tests.test_1::ConditionTest::test_repr\nPASSED r2e_tests.test_1::ConditionTest::test_wait_timeout\nPASSED r2e_tests.test_1::ConditionTest::test_wait_timeout_preempted\nPASSED r2e_tests.test_1::EventTest::test_event\nPASSED r2e_tests.test_1::EventTest::test_event_set_multiple\nPASSED r2e_tests.test_1::EventTest::test_event_timeout\nPASSED r2e_tests.test_1::EventTest::test_event_wait_clear\nPASSED r2e_tests.test_1::EventTest::test_repr\nPASSED r2e_tests.test_1::LockTests::test_acquire_fifo\nPASSED r2e_tests.test_1::LockTests::test_acquire_release\nPASSED r2e_tests.test_1::LockTests::test_acquire_timeout\nPASSED r2e_tests.test_1::LockTests::test_context_manager_misuse\nPASSED r2e_tests.test_1::LockTests::test_multi_release\nPASSED r2e_tests.test_1::LockTests::test_repr\nPASSED r2e_tests.test_1::LockTests::test_yield_lock\nPASSED r2e_tests.test_1::SemaphoreContextManagerTest::test_context_manager\nPASSED r2e_tests.test_1::SemaphoreContextManagerTest::test_context_manager_contended\nPASSED r2e_tests.test_1::SemaphoreContextManagerTest::test_context_manager_exception\nPASSED r2e_tests.test_1::SemaphoreContextManagerTest::test_context_manager_misuse\nPASSED r2e_tests.test_1::SemaphoreContextManagerTest::test_context_manager_timeout\nPASSED r2e_tests.test_1::SemaphoreContextManagerTest::test_context_manager_timeout_error\nPASSED r2e_tests.test_1::SemaphoreContextManagerTest::test_yield_sem\nPASSED r2e_tests.test_1::SemaphoreTest::test_acquire\nPASSED r2e_tests.test_1::SemaphoreTest::test_acquire_timeout\nPASSED r2e_tests.test_1::SemaphoreTest::test_acquire_timeout_preempted\nPASSED r2e_tests.test_1::SemaphoreTest::test_garbage_collection\nPASSED r2e_tests.test_1::SemaphoreTest::test_negative_value\nPASSED r2e_tests.test_1::SemaphoreTest::test_release_unacquired\nPASSED r2e_tests.test_1::SemaphoreTest::test_repr\n=================== 38 passed in 0.57s ===================\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_8b1c466cbf12d593255457247404c00f9c7fa4c1\n......................................\ncollected 38 items\n\n=================================== ERRORS =====================================\n__________ LockTests.test_acquire_timeout __________\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_8b1c466cbf12d593255457247404c00f9c7fa4c1/tornado/testing.py\", line 120, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_8b1c466cbf12d593255457247404c00f9c7fa4c1/tornado/testing.py\", line 499, in post_coroutine\n    return self.io_loop.run_sync(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_8b1c466cbf12d593255457247404c00f9c7fa4c1/tornado/ioloop.py\", line 445, in run_sync\n    return future_cell[0].result()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_8b1c466cbf12d593255457247404c00f9c7fa4c1/tornado/concurrent.py\", line 211, in result\n    raise_exc_info(self._exc_info)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_8b1c466cbf12d593255457247404c00f9c7fa4c1/tornado/gen.py\", line 230, in wrapper\n    yielded = next(result)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_8b1c466cbf12d593255457247404c00f9c7fa4c1/r2e_tests/test_1.py\", line 451, in test_acquire_timeout\n    yield lock.acquire(timeout=timedelta(seconds=0.01))\nTypeError: acquire() got an unexpected keyword argument 'timeout'\n\n==================== short test summary info ====================\nPASSED r2e_tests.test_1::BoundedSemaphoreTest::test_release_unacquired\nPASSED r2e_tests.test_1::ConditionTest::test_garbage_collection\nPASSED r2e_tests.test_1::ConditionTest::test_nested_notify\nPASSED r2e_tests.test_1::ConditionTest::test_notify\nPASSED r2e_tests.test_1::ConditionTest::test_notify_1\nPASSED r2e_tests.test_1::ConditionTest::test_notify_all\nPASSED r2e_tests.test_1::ConditionTest::test_notify_all_with_timeout\nPASSED r2e_tests.test_1::ConditionTest::test_notify_n\nPASSED r2e_tests.test_1::ConditionTest::test_notify_n_with_timeout\nPASSED r2e_tests.test_1::ConditionTest::test_repr\nPASSED r2e_tests.test_1::ConditionTest::test_wait_timeout\nPASSED r2e_tests.test_1::ConditionTest::test_wait_timeout_preempted\nPASSED r2e_tests.test_1::EventTest::test_event\nPASSED r2e_tests.test_1::EventTest::test_event_set_multiple\nPASSED r2e_tests.test_1::EventTest::test_event_timeout\nPASSED r2e_tests.test_1::EventTest::test_event_wait_clear\nPASSED r2e_tests.test_1::EventTest::test_repr\nPASSED r2e_tests.test_1::LockTests::test_acquire_fifo\nPASSED r2e_tests.test_1::LockTests::test_acquire_release\nERROR r2e_tests.test_1::LockTests::test_acquire_timeout\nPASSED r2e_tests.test_1::LockTests::test_context_manager_misuse\nPASSED r2e_tests.test_1::LockTests::test_multi_release\nPASSED r2e_tests.test_1::LockTests::test_repr\nPASSED r2e_tests.test_1::LockTests::test_yield_lock\nPASSED r2e_tests.test_1::SemaphoreContextManagerTest::test_context_manager\nPASSED r2e_tests.test_1::SemaphoreContextManagerTest::test_context_manager_contended\nPASSED r2e_tests.test_1::SemaphoreContextManagerTest::test_context_manager_exception\nPASSED r2e_tests.test_1::SemaphoreContextManagerTest::test_context_manager_misuse\nPASSED r2e_tests.test_1::SemaphoreContextManagerTest::test_context_manager_timeout\nPASSED r2e_tests.test_1::SemaphoreContextManagerTest::test_context_manager_timeout_error\nPASSED r2e_tests.test_1::SemaphoreContextManagerTest::test_yield_sem\nPASSED r2e_tests.test_1::SemaphoreTest::test_acquire\nPASSED r2e_tests.test_1::SemaphoreTest::test_acquire_timeout\nPASSED r2e_tests.test_1::SemaphoreTest::test_acquire_timeout_preempted\nPASSED r2e_tests.test_1::SemaphoreTest::test_garbage_collection\nPASSED r2e_tests.test_1::SemaphoreTest::test_negative_value\nPASSED r2e_tests.test_1::SemaphoreTest::test_release_unacquired\nPASSED r2e_tests.test_1::SemaphoreTest::test_repr\n=================== 1 error, 37 passed in 0.55s ===================\n",
    "old_commit_res_stderr": ""
}
tornado/locks.py tornado/test/locks_test.py
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ISSUE]
**Title:** `Lock.acquire()` Does Not Accept `timeout` Keyword Argument

**Description:**
When attempting to acquire a lock with a timeout, using the `timeout` keyword results in a `TypeError`. The `Lock.acquire()` method currently does not recognize the `timeout` parameter, causing unexpected failures in scenarios where a timeout is necessary.

**Example Code:**
```python
from datetime import timedelta
from tornado import locks, gen

lock = locks.Lock()
lock.acquire()
with self.assertRaises(gen.TimeoutError):
    yield lock.acquire(timeout=timedelta(seconds=0.01))
```

**Expected Behavior:**
The `Lock.acquire()` method should accept a `timeout` argument to specify the maximum duration to wait for the lock. Using `timeout=timedelta(seconds=0.01)` should raise a `TimeoutError` if the lock cannot be acquired within the specified time.

**Actual Behavior:**
Passing `timeout=timedelta(seconds=0.01)` to `Lock.acquire()` results in the following error:
```
TypeError: acquire() got an unexpected keyword argument 'timeout'
```
This prevents the lock from being acquired with a timeout and disrupts the intended asynchronous flow.
[/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/locks.py
# Copyright 2015 The Tornado Authors
#
# 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.

"""
.. testsetup:: *

    from tornado import ioloop, gen, locks
    io_loop = ioloop.IOLoop.current()
"""

from __future__ import absolute_import, division, print_function, with_statement

__all__ = ['Condition', 'Event', 'Semaphore', 'BoundedSemaphore', 'Lock']

import collections

from tornado import gen, ioloop
from tornado.concurrent import Future


class _TimeoutGarbageCollector(object):
    """Base class for objects that periodically clean up timed-out waiters.

    Avoids memory leak in a common pattern like:

        while True:
            yield condition.wait(short_timeout)
            print('looping....')
    """
    def __init__(self):
        self._waiters = collections.deque()  # Futures.
        self._timeouts = 0

    def _garbage_collect(self):
        # Occasionally clear timed-out waiters.
        self._timeouts += 1
        if self._timeouts > 100:
            self._timeouts = 0
            self._waiters = collections.deque(
                w for w in self._waiters if not w.done())


class Condition(_TimeoutGarbageCollector):
    """A condition allows one or more coroutines to wait until notified.

    Like a standard `threading.Condition`, but does not need an underlying lock
    that is acquired and released.

    With a `Condition`, coroutines can wait to be notified by other coroutines:

    .. testcode::

        condition = locks.Condition()

        @gen.coroutine
        def waiter():
            print("I'll wait right here")
            yield condition.wait()  # Yield a Future.
            print("I'm done waiting")

        @gen.coroutine
        def notifier():
            print("About to notify")
            condition.notify()
            print("Done notifying")

        @gen.coroutine
        def runner():
            # Yield two Futures; wait for waiter() and notifier() to finish.
            yield [waiter(), notifier()]

        io_loop.run_sync(runner)

    .. testoutput::

        I'll wait right here
        About to notify
        Done notifying
        I'm done waiting

    `wait` takes an optional ``timeout`` argument, which is either an absolute
    timestamp::

        io_loop = ioloop.IOLoop.current()

        # Wait up to 1 second for a notification.
        yield condition.wait(timeout=io_loop.time() + 1)

    ...or a `datetime.timedelta` for a timeout relative to the current time::

        # Wait up to 1 second.
        yield condition.wait(timeout=datetime.timedelta(seconds=1))

    The method raises `tornado.gen.TimeoutError` if there's no notification
    before the deadline.
    """

    def __init__(self):
        super(Condition, self).__init__()
        self.io_loop = ioloop.IOLoop.current()

    def __repr__(self):
        result = '<%s' % (self.__class__.__name__, )
        if self._waiters:
            result += ' waiters[%s]' % len(self._waiters)
        return result + '>'

    def wait(self, timeout=None):
        """Wait for `.notify`.

        Returns a `.Future` that resolves ``True`` if the condition is notified,
        or ``False`` after a timeout.
        """
        waiter = Future()
        self._waiters.append(waiter)
        if timeout:
            def on_timeout():
                waiter.set_result(False)
                self._garbage_collect()
            io_loop = ioloop.IOLoop.current()
            timeout_handle = io_loop.add_timeout(timeout, on_timeout)
            waiter.add_done_callback(
                lambda _: io_loop.remove_timeout(timeout_handle))
        return waiter

    def notify(self, n=1):
        """Wake ``n`` waiters."""
        waiters = []  # Waiters we plan to run right now.
        while n and self._waiters:
            waiter = self._waiters.popleft()
            if not waiter.done():  # Might have timed out.
                n -= 1
                waiters.append(waiter)

        for waiter in waiters:
            waiter.set_result(True)

    def notify_all(self):
        """Wake all waiters."""
        self.notify(len(self._waiters))


class Event(object):
    """An event blocks coroutines until its internal flag is set to True.

    Similar to `threading.Event`.

    A coroutine can wait for an event to be set. Once it is set, calls to
    ``yield event.wait()`` will not block unless the event has been cleared:

    .. testcode::

        event = locks.Event()

        @gen.coroutine
        def waiter():
            print("Waiting for event")
            yield event.wait()
            print("Not waiting this time")
            yield event.wait()
            print("Done")

        @gen.coroutine
        def setter():
            print("About to set the event")
            event.set()

        @gen.coroutine
        def runner():
            yield [waiter(), setter()]

        io_loop.run_sync(runner)

    .. testoutput::

        Waiting for event
        About to set the event
        Not waiting this time
        Done
    """
    def __init__(self):
        self._future = Future()

    def __repr__(self):
        return '<%s %s>' % (
            self.__class__.__name__, 'set' if self.is_set() else 'clear')

    def is_set(self):
        """Return ``True`` if the internal flag is true."""
        return self._future.done()

    def set(self):
        """Set the internal flag to ``True``. All waiters are awakened.

        Calling `.wait` once the flag is set will not block.
        """
        if not self._future.done():
            self._future.set_result(None)

    def clear(self):
        """Reset the internal flag to ``False``.
        
        Calls to `.wait` will block until `.set` is called.
        """
        if self._future.done():
            self._future = Future()

    def wait(self, timeout=None):
        """Block until the internal flag is true.

        Returns a Future, which raises `tornado.gen.TimeoutError` after a
        timeout.
        """
        if timeout is None:
            return self._future
        else:
            return gen.with_timeout(timeout, self._future)


class _ReleasingContextManager(object):
    """Releases a Lock or Semaphore at the end of a "with" statement.

        with (yield semaphore.acquire()):
            pass

        # Now semaphore.release() has been called.
    """
    def __init__(self, obj):
        self._obj = obj

    def __enter__(self):
        pass

    def __exit__(self, exc_type, exc_val, exc_tb):
        self._obj.release()


class Semaphore(_TimeoutGarbageCollector):
    """A lock that can be acquired a fixed number of times before blocking.

    A Semaphore manages a counter representing the number of `.release` calls
    minus the number of `.acquire` calls, plus an initial value. The `.acquire`
    method blocks if necessary until it can return without making the counter
    negative.

    Semaphores limit access to a shared resource. To allow access for two
    workers at a time:

    .. testsetup:: semaphore

       from collections import deque

       from tornado import gen, ioloop
       from tornado.concurrent import Future

       # Ensure reliable doctest output: resolve Futures one at a time.
       futures_q = deque([Future() for _ in range(3)])

       @gen.coroutine
       def simulator(futures):
           for f in futures:
               yield gen.moment
               f.set_result(None)

       ioloop.IOLoop.current().add_callback(simulator, list(futures_q))

       def use_some_resource():
           return futures_q.popleft()

    .. testcode:: semaphore

        sem = locks.Semaphore(2)

        @gen.coroutine
        def worker(worker_id):
            yield sem.acquire()
            try:
                print("Worker %d is working" % worker_id)
                yield use_some_resource()
            finally:
                print("Worker %d is done" % worker_id)
                sem.release()

        @gen.coroutine
        def runner():
            # Join all workers.
            yield [worker(i) for i in range(3)]

        io_loop.run_sync(runner)

    .. testoutput:: semaphore

        Worker 0 is working
        Worker 1 is working
        Worker 0 is done
        Worker 2 is working
        Worker 1 is done
        Worker 2 is done

    Workers 0 and 1 are allowed to run concurrently, but worker 2 waits until
    the semaphore has been released once, by worker 0.

    `.acquire` is a context manager, so ``worker`` could be written as::

        @gen.coroutine
        def worker(worker_id):
            with (yield sem.acquire()):
                print("Worker %d is working" % worker_id)
                yield use_some_resource()

            # Now the semaphore has been released.
            print("Worker %d is done" % worker_id)
    """
    def __init__(self, value=1):
        super(Semaphore, self).__init__()
        if value < 0:
            raise ValueError('semaphore initial value must be >= 0')

        self._value = value

    def __repr__(self):
        res = super(Semaphore, self).__repr__()
        extra = 'locked' if self._value == 0 else 'unlocked,value:{0}'.format(
            self._value)
        if self._waiters:
            extra = '{0},waiters:{1}'.format(extra, len(self._waiters))
        return '<{0} [{1}]>'.format(res[1:-1], extra)

    def release(self):
        """Increment the counter and wake one waiter."""
        self._value += 1
        while self._waiters:
            waiter = self._waiters.popleft()
            if not waiter.done():
                self._value -= 1

                # If the waiter is a coroutine paused at
                #
                #     with (yield semaphore.acquire()):
                #
                # then the context manager's __exit__ calls release() at the end
                # of the "with" block.
                waiter.set_result(_ReleasingContextManager(self))
                break

    def acquire(self, timeout=None):
        """Decrement the counter. Returns a Future.

        Block if the counter is zero and wait for a `.release`. The Future
        raises `.TimeoutError` after the deadline.
        """
        waiter = Future()
        if self._value > 0:
            self._value -= 1
            waiter.set_result(_ReleasingContextManager(self))
        else:
            self._waiters.append(waiter)
            if timeout:
                def on_timeout():
                    waiter.set_exception(gen.TimeoutError())
                    self._garbage_collect()
                io_loop = ioloop.IOLoop.current()
                timeout_handle = io_loop.add_timeout(timeout, on_timeout)
                waiter.add_done_callback(
                    lambda _: io_loop.remove_timeout(timeout_handle))
        return waiter

    def __enter__(self):
        raise RuntimeError(
            "Use Semaphore like 'with (yield semaphore.acquire())', not like"
            " 'with semaphore'")

    __exit__ = __enter__


class BoundedSemaphore(Semaphore):
    """A semaphore that prevents release() being called too many times.

    If `.release` would increment the semaphore's value past the initial
    value, it raises `ValueError`. Semaphores are mostly used to guard
    resources with limited capacity, so a semaphore released too many times
    is a sign of a bug.
    """
    def __init__(self, value=1):
        super(BoundedSemaphore, self).__init__(value=value)
        self._initial_value = value

    def release(self):
        """Increment the counter and wake one waiter."""
        if self._value >= self._initial_value:
            raise ValueError("Semaphore released too many times")
        super(BoundedSemaphore, self).release()


class Lock(object):
    """A lock for coroutines.

    A Lock begins unlocked, and `acquire` locks it immediately. While it is
    locked, a coroutine that yields `acquire` waits until another coroutine
    calls `release`.

    Releasing an unlocked lock raises `RuntimeError`.

    `acquire` supports the context manager protocol:

    >>> from tornado import gen, locks
    >>> lock = locks.Lock()
    >>>
    >>> @gen.coroutine
    ... def f():
    ...    with (yield lock.acquire()):
    ...        # Do something holding the lock.
    ...        pass
    ...
    ...    # Now the lock is released.
    """
    def __init__(self):
        self._block = BoundedSemaphore(value=1)

    def __repr__(self):
        return "<%s _block=%s>" % (
            self.__class__.__name__,
            self._block)

    def acquire(self, deadline=None):
        """Attempt to lock. Returns a Future.

        Returns a Future, which raises `tornado.gen.TimeoutError` after a
        timeout.
        """
        return self._block.acquire(deadline)

    def release(self):
        """Unlock.

        The first coroutine in line waiting for `acquire` gets the lock.

        If not locked, raise a `RuntimeError`.
        """
        try:
            self._block.release()
        except ValueError:
            raise RuntimeError('release unlocked lock')

    def __enter__(self):
        raise RuntimeError(
            "Use Lock like 'with (yield lock)', not like 'with lock'")

    __exit__ = __enter__

```
--- 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:** `Lock.acquire()` Does Not Accept `timeout` Keyword Argument

**Description:**
When attempting to acquire a lock with a timeout, using the `timeout` keyword results in a `TypeError`. The `Lock.acquire()` method currently does not recognize the `timeout` parameter, causing unexpected failures in scenarios where a timeout is necessary.

**Example Code:**
```python
from datetime import timedelta
from tornado import locks, gen

lock = locks.Lock()
lock.acquire()
with self.assertRaises(gen.TimeoutError):
    yield lock.acquire(timeout=timedelta(seconds=0.01))
```

**Expected Behavior:**
The `Lock.acquire()` method should accept a `timeout` argument to specify the maximum duration to wait for the lock. Using `timeout=timedelta(seconds=0.01)` should raise a `TimeoutError` if the lock cannot be acquired within the specified time.

**Actual Behavior:**
Passing `timeout=timedelta(seconds=0.01)` to `Lock.acquire()` results in the following error:
```
TypeError: acquire() got an unexpected keyword argument 'timeout'
```
This prevents the lock from being acquired with a timeout and disrupts the intended asynchronous flow.
[/ISSUE]
{
    "BoundedSemaphoreTest.test_release_unacquired": "PASSED",
    "ConditionTest.test_garbage_collection": "PASSED",
    "ConditionTest.test_nested_notify": "PASSED",
    "ConditionTest.test_notify": "PASSED",
    "ConditionTest.test_notify_1": "PASSED",
    "ConditionTest.test_notify_all": "PASSED",
    "ConditionTest.test_notify_all_with_timeout": "PASSED",
    "ConditionTest.test_notify_n": "PASSED",
    "ConditionTest.test_notify_n_with_timeout": "PASSED",
    "ConditionTest.test_repr": "PASSED",
    "ConditionTest.test_wait_timeout": "PASSED",
    "ConditionTest.test_wait_timeout_preempted": "PASSED",
    "EventTest.test_event": "PASSED",
    "EventTest.test_event_set_multiple": "PASSED",
    "EventTest.test_event_timeout": "PASSED",
    "EventTest.test_event_wait_clear": "PASSED",
    "EventTest.test_repr": "PASSED",
    "LockTests.test_acquire_fifo": "PASSED",
    "LockTests.test_acquire_release": "PASSED",
    "LockTests.test_acquire_timeout": "PASSED",
    "LockTests.test_context_manager_misuse": "PASSED",
    "LockTests.test_multi_release": "PASSED",
    "LockTests.test_repr": "PASSED",
    "LockTests.test_yield_lock": "PASSED",
    "SemaphoreContextManagerTest.test_context_manager": "PASSED",
    "SemaphoreContextManagerTest.test_context_manager_contended": "PASSED",
    "SemaphoreContextManagerTest.test_context_manager_exception": "PASSED",
    "SemaphoreContextManagerTest.test_context_manager_misuse": "PASSED",
    "SemaphoreContextManagerTest.test_context_manager_timeout": "PASSED",
    "SemaphoreContextManagerTest.test_context_manager_timeout_error": "PASSED",
    "SemaphoreContextManagerTest.test_yield_sem": "PASSED",
    "SemaphoreTest.test_acquire": "PASSED",
    "SemaphoreTest.test_acquire_timeout": "PASSED",
    "SemaphoreTest.test_acquire_timeout_preempted": "PASSED",
    "SemaphoreTest.test_garbage_collection": "PASSED",
    "SemaphoreTest.test_negative_value": "PASSED",
    "SemaphoreTest.test_release_unacquired": "PASSED",
    "SemaphoreTest.test_repr": "PASSED"
}
diff --git a/tornado/locks.py b/tornado/locks.py
index 77340abc..4b0bdb38 100644
--- a/tornado/locks.py
+++ b/tornado/locks.py
@@ -433,13 +433,13 @@ class Lock(object):
             self.__class__.__name__,
             self._block)
 
-    def acquire(self, deadline=None):
+    def acquire(self, timeout=None):
         """Attempt to lock. Returns a Future.
 
         Returns a Future, which raises `tornado.gen.TimeoutError` after a
         timeout.
         """
-        return self._block.acquire(deadline)
+        return self._block.acquire(timeout)
 
     def release(self):
         """Unlock.

{"tornado/locks.py": "# Copyright 2015 The Tornado Authors\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\"\"\"\n.. testsetup:: *\n\n    from tornado import ioloop, gen, locks\n    io_loop = ioloop.IOLoop.current()\n\"\"\"\n\nfrom __future__ import absolute_import, division, print_function, with_statement\n\n__all__ = ['Condition', 'Event', 'Semaphore', 'BoundedSemaphore', 'Lock']\n\nimport collections\n\nfrom tornado import gen, ioloop\nfrom tornado.concurrent import Future\n\n\nclass _TimeoutGarbageCollector(object):\n    \"\"\"Base class for objects that periodically clean up timed-out waiters.\n\n    Avoids memory leak in a common pattern like:\n\n        while True:\n            yield condition.wait(short_timeout)\n            print('looping....')\n    \"\"\"\n    def __init__(self):\n        self._waiters = collections.deque()  # Futures.\n        self._timeouts = 0\n\n    def _garbage_collect(self):\n        # Occasionally clear timed-out waiters.\n        self._timeouts += 1\n        if self._timeouts > 100:\n            self._timeouts = 0\n            self._waiters = collections.deque(\n                w for w in self._waiters if not w.done())\n\n\nclass Condition(_TimeoutGarbageCollector):\n    \"\"\"A condition allows one or more coroutines to wait until notified.\n\n    Like a standard `threading.Condition`, but does not need an underlying lock\n    that is acquired and released.\n\n    With a `Condition`, coroutines can wait to be notified by other coroutines:\n\n    .. testcode::\n\n        condition = locks.Condition()\n\n        @gen.coroutine\n        def waiter():\n            print(\"I'll wait right here\")\n            yield condition.wait()  # Yield a Future.\n            print(\"I'm done waiting\")\n\n        @gen.coroutine\n        def notifier():\n            print(\"About to notify\")\n            condition.notify()\n            print(\"Done notifying\")\n\n        @gen.coroutine\n        def runner():\n            # Yield two Futures; wait for waiter() and notifier() to finish.\n            yield [waiter(), notifier()]\n\n        io_loop.run_sync(runner)\n\n    .. testoutput::\n\n        I'll wait right here\n        About to notify\n        Done notifying\n        I'm done waiting\n\n    `wait` takes an optional ``timeout`` argument, which is either an absolute\n    timestamp::\n\n        io_loop = ioloop.IOLoop.current()\n\n        # Wait up to 1 second for a notification.\n        yield condition.wait(timeout=io_loop.time() + 1)\n\n    ...or a `datetime.timedelta` for a timeout relative to the current time::\n\n        # Wait up to 1 second.\n        yield condition.wait(timeout=datetime.timedelta(seconds=1))\n\n    The method raises `tornado.gen.TimeoutError` if there's no notification\n    before the deadline.\n    \"\"\"\n\n    def __init__(self):\n        super(Condition, self).__init__()\n        self.io_loop = ioloop.IOLoop.current()\n\n    def __repr__(self):\n        result = '<%s' % (self.__class__.__name__, )\n        if self._waiters:\n            result += ' waiters[%s]' % len(self._waiters)\n        return result + '>'\n\n    def wait(self, timeout=None):\n        \"\"\"Wait for `.notify`.\n\n        Returns a `.Future` that resolves ``True`` if the condition is notified,\n        or ``False`` after a timeout.\n        \"\"\"\n        waiter = Future()\n        self._waiters.append(waiter)\n        if timeout:\n            def on_timeout():\n                waiter.set_result(False)\n                self._garbage_collect()\n            io_loop = ioloop.IOLoop.current()\n            timeout_handle = io_loop.add_timeout(timeout, on_timeout)\n            waiter.add_done_callback(\n                lambda _: io_loop.remove_timeout(timeout_handle))\n        return waiter\n\n    def notify(self, n=1):\n        \"\"\"Wake ``n`` waiters.\"\"\"\n        waiters = []  # Waiters we plan to run right now.\n        while n and self._waiters:\n            waiter = self._waiters.popleft()\n            if not waiter.done():  # Might have timed out.\n                n -= 1\n                waiters.append(waiter)\n\n        for waiter in waiters:\n            waiter.set_result(True)\n\n    def notify_all(self):\n        \"\"\"Wake all waiters.\"\"\"\n        self.notify(len(self._waiters))\n\n\nclass Event(object):\n    \"\"\"An event blocks coroutines until its internal flag is set to True.\n\n    Similar to `threading.Event`.\n\n    A coroutine can wait for an event to be set. Once it is set, calls to\n    ``yield event.wait()`` will not block unless the event has been cleared:\n\n    .. testcode::\n\n        event = locks.Event()\n\n        @gen.coroutine\n        def waiter():\n            print(\"Waiting for event\")\n            yield event.wait()\n            print(\"Not waiting this time\")\n            yield event.wait()\n            print(\"Done\")\n\n        @gen.coroutine\n        def setter():\n            print(\"About to set the event\")\n            event.set()\n\n        @gen.coroutine\n        def runner():\n            yield [waiter(), setter()]\n\n        io_loop.run_sync(runner)\n\n    .. testoutput::\n\n        Waiting for event\n        About to set the event\n        Not waiting this time\n        Done\n    \"\"\"\n    def __init__(self):\n        self._future = Future()\n\n    def __repr__(self):\n        return '<%s %s>' % (\n            self.__class__.__name__, 'set' if self.is_set() else 'clear')\n\n    def is_set(self):\n        \"\"\"Return ``True`` if the internal flag is true.\"\"\"\n        return self._future.done()\n\n    def set(self):\n        \"\"\"Set the internal flag to ``True``. All waiters are awakened.\n\n        Calling `.wait` once the flag is set will not block.\n        \"\"\"\n        if not self._future.done():\n            self._future.set_result(None)\n\n    def clear(self):\n        \"\"\"Reset the internal flag to ``False``.\n        \n        Calls to `.wait` will block until `.set` is called.\n        \"\"\"\n        if self._future.done():\n            self._future = Future()\n\n    def wait(self, timeout=None):\n        \"\"\"Block until the internal flag is true.\n\n        Returns a Future, which raises `tornado.gen.TimeoutError` after a\n        timeout.\n        \"\"\"\n        if timeout is None:\n            return self._future\n        else:\n            return gen.with_timeout(timeout, self._future)\n\n\nclass _ReleasingContextManager(object):\n    \"\"\"Releases a Lock or Semaphore at the end of a \"with\" statement.\n\n        with (yield semaphore.acquire()):\n            pass\n\n        # Now semaphore.release() has been called.\n    \"\"\"\n    def __init__(self, obj):\n        self._obj = obj\n\n    def __enter__(self):\n        pass\n\n    def __exit__(self, exc_type, exc_val, exc_tb):\n        self._obj.release()\n\n\nclass Semaphore(_TimeoutGarbageCollector):\n    \"\"\"A lock that can be acquired a fixed number of times before blocking.\n\n    A Semaphore manages a counter representing the number of `.release` calls\n    minus the number of `.acquire` calls, plus an initial value. The `.acquire`\n    method blocks if necessary until it can return without making the counter\n    negative.\n\n    Semaphores limit access to a shared resource. To allow access for two\n    workers at a time:\n\n    .. testsetup:: semaphore\n\n       from collections import deque\n\n       from tornado import gen, ioloop\n       from tornado.concurrent import Future\n\n       # Ensure reliable doctest output: resolve Futures one at a time.\n       futures_q = deque([Future() for _ in range(3)])\n\n       @gen.coroutine\n       def simulator(futures):\n           for f in futures:\n               yield gen.moment\n               f.set_result(None)\n\n       ioloop.IOLoop.current().add_callback(simulator, list(futures_q))\n\n       def use_some_resource():\n           return futures_q.popleft()\n\n    .. testcode:: semaphore\n\n        sem = locks.Semaphore(2)\n\n        @gen.coroutine\n        def worker(worker_id):\n            yield sem.acquire()\n            try:\n                print(\"Worker %d is working\" % worker_id)\n                yield use_some_resource()\n            finally:\n                print(\"Worker %d is done\" % worker_id)\n                sem.release()\n\n        @gen.coroutine\n        def runner():\n            # Join all workers.\n            yield [worker(i) for i in range(3)]\n\n        io_loop.run_sync(runner)\n\n    .. testoutput:: semaphore\n\n        Worker 0 is working\n        Worker 1 is working\n        Worker 0 is done\n        Worker 2 is working\n        Worker 1 is done\n        Worker 2 is done\n\n    Workers 0 and 1 are allowed to run concurrently, but worker 2 waits until\n    the semaphore has been released once, by worker 0.\n\n    `.acquire` is a context manager, so ``worker`` could be written as::\n\n        @gen.coroutine\n        def worker(worker_id):\n            with (yield sem.acquire()):\n                print(\"Worker %d is working\" % worker_id)\n                yield use_some_resource()\n\n            # Now the semaphore has been released.\n            print(\"Worker %d is done\" % worker_id)\n    \"\"\"\n    def __init__(self, value=1):\n        super(Semaphore, self).__init__()\n        if value < 0:\n            raise ValueError('semaphore initial value must be >= 0')\n\n        self._value = value\n\n    def __repr__(self):\n        res = super(Semaphore, self).__repr__()\n        extra = 'locked' if self._value == 0 else 'unlocked,value:{0}'.format(\n            self._value)\n        if self._waiters:\n            extra = '{0},waiters:{1}'.format(extra, len(self._waiters))\n        return '<{0} [{1}]>'.format(res[1:-1], extra)\n\n    def release(self):\n        \"\"\"Increment the counter and wake one waiter.\"\"\"\n        self._value += 1\n        while self._waiters:\n            waiter = self._waiters.popleft()\n            if not waiter.done():\n                self._value -= 1\n\n                # If the waiter is a coroutine paused at\n                #\n                #     with (yield semaphore.acquire()):\n                #\n                # then the context manager's __exit__ calls release() at the end\n                # of the \"with\" block.\n                waiter.set_result(_ReleasingContextManager(self))\n                break\n\n    def acquire(self, timeout=None):\n        \"\"\"Decrement the counter. Returns a Future.\n\n        Block if the counter is zero and wait for a `.release`. The Future\n        raises `.TimeoutError` after the deadline.\n        \"\"\"\n        waiter = Future()\n        if self._value > 0:\n            self._value -= 1\n            waiter.set_result(_ReleasingContextManager(self))\n        else:\n            self._waiters.append(waiter)\n            if timeout:\n                def on_timeout():\n                    waiter.set_exception(gen.TimeoutError())\n                    self._garbage_collect()\n                io_loop = ioloop.IOLoop.current()\n                timeout_handle = io_loop.add_timeout(timeout, on_timeout)\n                waiter.add_done_callback(\n                    lambda _: io_loop.remove_timeout(timeout_handle))\n        return waiter\n\n    def __enter__(self):\n        raise RuntimeError(\n            \"Use Semaphore like 'with (yield semaphore.acquire())', not like\"\n            \" 'with semaphore'\")\n\n    __exit__ = __enter__\n\n\nclass BoundedSemaphore(Semaphore):\n    \"\"\"A semaphore that prevents release() being called too many times.\n\n    If `.release` would increment the semaphore's value past the initial\n    value, it raises `ValueError`. Semaphores are mostly used to guard\n    resources with limited capacity, so a semaphore released too many times\n    is a sign of a bug.\n    \"\"\"\n    def __init__(self, value=1):\n        super(BoundedSemaphore, self).__init__(value=value)\n        self._initial_value = value\n\n    def release(self):\n        \"\"\"Increment the counter and wake one waiter.\"\"\"\n        if self._value >= self._initial_value:\n            raise ValueError(\"Semaphore released too many times\")\n        super(BoundedSemaphore, self).release()\n\n\nclass Lock(object):\n    \"\"\"A lock for coroutines.\n\n    A Lock begins unlocked, and `acquire` locks it immediately. While it is\n    locked, a coroutine that yields `acquire` waits until another coroutine\n    calls `release`.\n\n    Releasing an unlocked lock raises `RuntimeError`.\n\n    `acquire` supports the context manager protocol:\n\n    >>> from tornado import gen, locks\n    >>> lock = locks.Lock()\n    >>>\n    >>> @gen.coroutine\n    ... def f():\n    ...    with (yield lock.acquire()):\n    ...        # Do something holding the lock.\n    ...        pass\n    ...\n    ...    # Now the lock is released.\n    \"\"\"\n    def __init__(self):\n        self._block = BoundedSemaphore(value=1)\n\n    def __repr__(self):\n        return \"<%s _block=%s>\" % (\n            self.__class__.__name__,\n            self._block)\n\n    def acquire(self, deadline=None):\n        \"\"\"Attempt to lock. Returns a Future.\n\n        Returns a Future, which raises `tornado.gen.TimeoutError` after a\n        timeout.\n        \"\"\"\n        return self._block.acquire(deadline)\n\n    def release(self):\n        \"\"\"Unlock.\n\n        The first coroutine in line waiting for `acquire` gets the lock.\n\n        If not locked, raise a `RuntimeError`.\n        \"\"\"\n        try:\n            self._block.release()\n        except ValueError:\n            raise RuntimeError('release unlocked lock')\n\n    def __enter__(self):\n        raise RuntimeError(\n            \"Use Lock like 'with (yield lock)', not like 'with lock'\")\n\n    __exit__ = __enter__\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:** `Lock.acquire()` Does Not Accept `timeout` Keyword Argument

**Description:**
When attempting to acquire a lock with a timeout, using the `timeout` keyword results in a `TypeError`. The `Lock.acquire()` method currently does not recognize the `timeout` parameter, causing unexpected failures in scenarios where a timeout is necessary.

**Example Code:**
```python
from datetime import timedelta
from tornado import locks, gen

lock = locks.Lock()
lock.acquire()
with self.assertRaises(gen.TimeoutError):
    yield lock.acquire(timeout=timedelta(seconds=0.01))
```

**Expected Behavior:**
The `Lock.acquire()` method should accept a `timeout` argument to specify the maximum duration to wait for the lock. Using `timeout=timedelta(seconds=0.01)` should raise a `TimeoutError` if the lock cannot be acquired within the specified time.

**Actual Behavior:**
Passing `timeout=timedelta(seconds=0.01)` to `Lock.acquire()` results in the following error:
```
TypeError: acquire() got an unexpected keyword argument 'timeout'
```
This prevents the lock from being acquired with a timeout and disrupts the intended asynchronous flow.
[/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/locks.py
# Copyright 2015 The Tornado Authors
#
# 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.

"""
.. testsetup:: *

    from tornado import ioloop, gen, locks
    io_loop = ioloop.IOLoop.current()
"""

from __future__ import absolute_import, division, print_function, with_statement

__all__ = ['Condition', 'Event', 'Semaphore', 'BoundedSemaphore', 'Lock']

import collections

from tornado import gen, ioloop
from tornado.concurrent import Future


class _TimeoutGarbageCollector(object):
    """Base class for objects that periodically clean up timed-out waiters.

    Avoids memory leak in a common pattern like:

        while True:
            yield condition.wait(short_timeout)
            print('looping....')
    """
    def __init__(self):
        self._waiters = collections.deque()  # Futures.
        self._timeouts = 0

    def _garbage_collect(self):
        # Occasionally clear timed-out waiters.
        self._timeouts += 1
        if self._timeouts > 100:
            self._timeouts = 0
            self._waiters = collections.deque(
                w for w in self._waiters if not w.done())


class Condition(_TimeoutGarbageCollector):
    """A condition allows one or more coroutines to wait until notified.

    Like a standard `threading.Condition`, but does not need an underlying lock
    that is acquired and released.

    With a `Condition`, coroutines can wait to be notified by other coroutines:

    .. testcode::

        condition = locks.Condition()

        @gen.coroutine
        def waiter():
            print("I'll wait right here")
            yield condition.wait()  # Yield a Future.
            print("I'm done waiting")

        @gen.coroutine
        def notifier():
            print("About to notify")
            condition.notify()
            print("Done notifying")

        @gen.coroutine
        def runner():
            # Yield two Futures; wait for waiter() and notifier() to finish.
            yield [waiter(), notifier()]

        io_loop.run_sync(runner)

    .. testoutput::

        I'll wait right here
        About to notify
        Done notifying
        I'm done waiting

    `wait` takes an optional ``timeout`` argument, which is either an absolute
    timestamp::

        io_loop = ioloop.IOLoop.current()

        # Wait up to 1 second for a notification.
        yield condition.wait(timeout=io_loop.time() + 1)

    ...or a `datetime.timedelta` for a timeout relative to the current time::

        # Wait up to 1 second.
        yield condition.wait(timeout=datetime.timedelta(seconds=1))

    The method raises `tornado.gen.TimeoutError` if there's no notification
    before the deadline.
    """

    def __init__(self):
        super(Condition, self).__init__()
        self.io_loop = ioloop.IOLoop.current()

    def __repr__(self):
        result = '<%s' % (self.__class__.__name__, )
        if self._waiters:
            result += ' waiters[%s]' % len(self._waiters)
        return result + '>'

    def wait(self, timeout=None):
        """Wait for `.notify`.

        Returns a `.Future` that resolves ``True`` if the condition is notified,
        or ``False`` after a timeout.
        """
        waiter = Future()
        self._waiters.append(waiter)
        if timeout:
            def on_timeout():
                waiter.set_result(False)
                self._garbage_collect()
            io_loop = ioloop.IOLoop.current()
            timeout_handle = io_loop.add_timeout(timeout, on_timeout)
            waiter.add_done_callback(
                lambda _: io_loop.remove_timeout(timeout_handle))
        return waiter

    def notify(self, n=1):
        """Wake ``n`` waiters."""
        waiters = []  # Waiters we plan to run right now.
        while n and self._waiters:
            waiter = self._waiters.popleft()
            if not waiter.done():  # Might have timed out.
                n -= 1
                waiters.append(waiter)

        for waiter in waiters:
            waiter.set_result(True)

    def notify_all(self):
        """Wake all waiters."""
        self.notify(len(self._waiters))


class Event(object):
    """An event blocks coroutines until its internal flag is set to True.

    Similar to `threading.Event`.

    A coroutine can wait for an event to be set. Once it is set, calls to
    ``yield event.wait()`` will not block unless the event has been cleared:

    .. testcode::

        event = locks.Event()

        @gen.coroutine
        def waiter():
            print("Waiting for event")
            yield event.wait()
            print("Not waiting this time")
            yield event.wait()
            print("Done")

        @gen.coroutine
        def setter():
            print("About to set the event")
            event.set()

        @gen.coroutine
        def runner():
            yield [waiter(), setter()]

        io_loop.run_sync(runner)

    .. testoutput::

        Waiting for event
        About to set the event
        Not waiting this time
        Done
    """
    def __init__(self):
        self._future = Future()

    def __repr__(self):
        return '<%s %s>' % (
            self.__class__.__name__, 'set' if self.is_set() else 'clear')

    def is_set(self):
        """Return ``True`` if the internal flag is true."""
        return self._future.done()

    def set(self):
        """Set the internal flag to ``True``. All waiters are awakened.

        Calling `.wait` once the flag is set will not block.
        """
        if not self._future.done():
            self._future.set_result(None)

    def clear(self):
        """Reset the internal flag to ``False``.
        
        Calls to `.wait` will block until `.set` is called.
        """
        if self._future.done():
            self._future = Future()

    def wait(self, timeout=None):
        """Block until the internal flag is true.

        Returns a Future, which raises `tornado.gen.TimeoutError` after a
        timeout.
        """
        if timeout is None:
            return self._future
        else:
            return gen.with_timeout(timeout, self._future)


class _ReleasingContextManager(object):
    """Releases a Lock or Semaphore at the end of a "with" statement.

        with (yield semaphore.acquire()):
            pass

        # Now semaphore.release() has been called.
    """
    def __init__(self, obj):
        self._obj = obj

    def __enter__(self):
        pass

    def __exit__(self, exc_type, exc_val, exc_tb):
        self._obj.release()


class Semaphore(_TimeoutGarbageCollector):
    """A lock that can be acquired a fixed number of times before blocking.

    A Semaphore manages a counter representing the number of `.release` calls
    minus the number of `.acquire` calls, plus an initial value. The `.acquire`
    method blocks if necessary until it can return without making the counter
    negative.

    Semaphores limit access to a shared resource. To allow access for two
    workers at a time:

    .. testsetup:: semaphore

       from collections import deque

       from tornado import gen, ioloop
       from tornado.concurrent import Future

       # Ensure reliable doctest output: resolve Futures one at a time.
       futures_q = deque([Future() for _ in range(3)])

       @gen.coroutine
       def simulator(futures):
           for f in futures:
               yield gen.moment
               f.set_result(None)

       ioloop.IOLoop.current().add_callback(simulator, list(futures_q))

       def use_some_resource():
           return futures_q.popleft()

    .. testcode:: semaphore

        sem = locks.Semaphore(2)

        @gen.coroutine
        def worker(worker_id):
            yield sem.acquire()
            try:
                print("Worker %d is working" % worker_id)
                yield use_some_resource()
            finally:
                print("Worker %d is done" % worker_id)
                sem.release()

        @gen.coroutine
        def runner():
            # Join all workers.
            yield [worker(i) for i in range(3)]

        io_loop.run_sync(runner)

    .. testoutput:: semaphore

        Worker 0 is working
        Worker 1 is working
        Worker 0 is done
        Worker 2 is working
        Worker 1 is done
        Worker 2 is done

    Workers 0 and 1 are allowed to run concurrently, but worker 2 waits until
    the semaphore has been released once, by worker 0.

    `.acquire` is a context manager, so ``worker`` could be written as::

        @gen.coroutine
        def worker(worker_id):
            with (yield sem.acquire()):
                print("Worker %d is working" % worker_id)
                yield use_some_resource()

            # Now the semaphore has been released.
            print("Worker %d is done" % worker_id)
    """
    def __init__(self, value=1):
        super(Semaphore, self).__init__()
        if value < 0:
            raise ValueError('semaphore initial value must be >= 0')

        self._value = value

    def __repr__(self):
        res = super(Semaphore, self).__repr__()
        extra = 'locked' if self._value == 0 else 'unlocked,value:{0}'.format(
            self._value)
        if self._waiters:
            extra = '{0},waiters:{1}'.format(extra, len(self._waiters))
        return '<{0} [{1}]>'.format(res[1:-1], extra)

    def release(self):
        """Increment the counter and wake one waiter."""
        self._value += 1
        while self._waiters:
            waiter = self._waiters.popleft()
            if not waiter.done():
                self._value -= 1

                # If the waiter is a coroutine paused at
                #
                #     with (yield semaphore.acquire()):
                #
                # then the context manager's __exit__ calls release() at the end
                # of the "with" block.
                waiter.set_result(_ReleasingContextManager(self))
                break

    def acquire(self, timeout=None):
        """Decrement the counter. Returns a Future.

        Block if the counter is zero and wait for a `.release`. The Future
        raises `.TimeoutError` after the deadline.
        """
        waiter = Future()
        if self._value > 0:
            self._value -= 1
            waiter.set_result(_ReleasingContextManager(self))
        else:
            self._waiters.append(waiter)
            if timeout:
                def on_timeout():
                    waiter.set_exception(gen.TimeoutError())
                    self._garbage_collect()
                io_loop = ioloop.IOLoop.current()
                timeout_handle = io_loop.add_timeout(timeout, on_timeout)
                waiter.add_done_callback(
                    lambda _: io_loop.remove_timeout(timeout_handle))
        return waiter

    def __enter__(self):
        raise RuntimeError(
            "Use Semaphore like 'with (yield semaphore.acquire())', not like"
            " 'with semaphore'")

    __exit__ = __enter__


class BoundedSemaphore(Semaphore):
    """A semaphore that prevents release() being called too many times.

    If `.release` would increment the semaphore's value past the initial
    value, it raises `ValueError`. Semaphores are mostly used to guard
    resources with limited capacity, so a semaphore released too many times
    is a sign of a bug.
    """
    def __init__(self, value=1):
        super(BoundedSemaphore, self).__init__(value=value)
        self._initial_value = value

    def release(self):
        """Increment the counter and wake one waiter."""
        if self._value >= self._initial_value:
            raise ValueError("Semaphore released too many times")
        super(BoundedSemaphore, self).release()


class Lock(object):
    """A lock for coroutines.

    A Lock begins unlocked, and `acquire` locks it immediately. While it is
    locked, a coroutine that yields `acquire` waits until another coroutine
    calls `release`.

    Releasing an unlocked lock raises `RuntimeError`.

    `acquire` supports the context manager protocol:

    >>> from tornado import gen, locks
    >>> lock = locks.Lock()
    >>>
    >>> @gen.coroutine
    ... def f():
    ...    with (yield lock.acquire()):
    ...        # Do something holding the lock.
    ...        pass
    ...
    ...    # Now the lock is released.
    """
    def __init__(self):
        self._block = BoundedSemaphore(value=1)

    def __repr__(self):
        return "<%s _block=%s>" % (
            self.__class__.__name__,
            self._block)

    def acquire(self, deadline=None):
        """Attempt to lock. Returns a Future.

        Returns a Future, which raises `tornado.gen.TimeoutError` after a
        timeout.
        """
        return self._block.acquire(deadline)

    def release(self):
        """Unlock.

        The first coroutine in line waiting for `acquire` gets the lock.

        If not locked, raise a `RuntimeError`.
        """
        try:
            self._block.release()
        except ValueError:
            raise RuntimeError('release unlocked lock')

    def __enter__(self):
        raise RuntimeError(
            "Use Lock like 'with (yield lock)', not like 'with lock'")

    __exit__ = __enter__

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