We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
pytest-aiohttp: compatibility with pytest v3.3.0
## Long story short

https://github.com/pytest-dev/pytest/issues/2959
Fixture parameters are now immutable, [pytest_plugin.py](https://github.com/aio-libs/aiohttp/blob/master/aiohttp/pytest_plugin.py#L195-L200) need to be updated

pytest-aiohttp: compatibility with pytest v3.3.0
## Long story short

https://github.com/pytest-dev/pytest/issues/2959
Fixture parameters are now immutable, [pytest_plugin.py](https://github.com/aio-libs/aiohttp/blob/master/aiohttp/pytest_plugin.py#L195-L200) need to be updated


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `aiohttp/pytest_plugin.py`
Content:
```
1 import asyncio
2 import collections
3 import contextlib
4 import tempfile
5 import warnings
6 
7 import pytest
8 from py import path
9 
10 from aiohttp.helpers import isasyncgenfunction
11 from aiohttp.web import Application
12 
13 from .test_utils import unused_port as _unused_port
14 from .test_utils import (BaseTestServer, RawTestServer, TestClient, TestServer,
15                          loop_context, setup_test_loop, teardown_test_loop)
16 
17 
18 try:
19     import uvloop
20 except:  # pragma: no cover
21     uvloop = None
22 
23 try:
24     import tokio
25 except:  # pragma: no cover
26     tokio = None
27 
28 
29 def pytest_addoption(parser):
30     parser.addoption(
31         '--fast', action='store_true', default=False,
32         help='run tests faster by disabling extra checks')
33     parser.addoption(
34         '--loop', action='store', default='pyloop',
35         help='run tests with specific loop: pyloop, uvloop, tokio or all')
36     parser.addoption(
37         '--enable-loop-debug', action='store_true', default=False,
38         help='enable event loop debug mode')
39 
40 
41 def pytest_fixture_setup(fixturedef, request):
42     """
43     Allow fixtures to be coroutines. Run coroutine fixtures in an event loop.
44     """
45     func = fixturedef.func
46 
47     if isasyncgenfunction(func):
48         # async generator fixture
49         is_async_gen = True
50     elif asyncio.iscoroutinefunction(func):
51         # regular async fixture
52         is_async_gen = False
53     else:
54         # not an async fixture, nothing to do
55         return
56 
57     strip_request = False
58     if 'request' not in fixturedef.argnames:
59         fixturedef.argnames += ('request',)
60         strip_request = True
61 
62     def wrapper(*args, **kwargs):
63         request = kwargs['request']
64         if strip_request:
65             del kwargs['request']
66 
67         # if neither the fixture nor the test use the 'loop' fixture,
68         # 'getfixturevalue' will fail because the test is not parameterized
69         # (this can be removed someday if 'loop' is no longer parameterized)
70         if 'loop' not in request.fixturenames:
71             raise Exception(
72                 "Asynchronous fixtures must depend on the 'loop' fixture or "
73                 "be used in tests depending from it."
74             )
75 
76         _loop = request.getfixturevalue('loop')
77 
78         if is_async_gen:
79             # for async generators, we need to advance the generator once,
80             # then advance it again in a finalizer
81             gen = func(*args, **kwargs)
82 
83             def finalizer():
84                 try:
85                     return _loop.run_until_complete(gen.__anext__())
86                 except StopAsyncIteration:  # NOQA
87                     pass
88 
89             request.addfinalizer(finalizer)
90             return _loop.run_until_complete(gen.__anext__())
91         else:
92             return _loop.run_until_complete(func(*args, **kwargs))
93 
94     fixturedef.func = wrapper
95 
96 
97 @pytest.fixture
98 def fast(request):
99     """ --fast config option """
100     return request.config.getoption('--fast')  # pragma: no cover
101 
102 
103 @contextlib.contextmanager
104 def _runtime_warning_context():
105     """
106     Context manager which checks for RuntimeWarnings, specifically to
107     avoid "coroutine 'X' was never awaited" warnings being missed.
108 
109     If RuntimeWarnings occur in the context a RuntimeError is raised.
110     """
111     with warnings.catch_warnings(record=True) as _warnings:
112         yield
113         rw = ['{w.filename}:{w.lineno}:{w.message}'.format(w=w)
114               for w in _warnings if w.category == RuntimeWarning]
115         if rw:
116             raise RuntimeError('{} Runtime Warning{},\n{}'.format(
117                 len(rw),
118                 '' if len(rw) == 1 else 's',
119                 '\n'.join(rw)
120             ))
121 
122 
123 @contextlib.contextmanager
124 def _passthrough_loop_context(loop, fast=False):
125     """
126     setups and tears down a loop unless one is passed in via the loop
127     argument when it's passed straight through.
128     """
129     if loop:
130         # loop already exists, pass it straight through
131         yield loop
132     else:
133         # this shadows loop_context's standard behavior
134         loop = setup_test_loop()
135         yield loop
136         teardown_test_loop(loop, fast=fast)
137 
138 
139 def pytest_pycollect_makeitem(collector, name, obj):
140     """
141     Fix pytest collecting for coroutines.
142     """
143     if collector.funcnamefilter(name) and asyncio.iscoroutinefunction(obj):
144         return list(collector._genfunctions(name, obj))
145 
146 
147 def pytest_pyfunc_call(pyfuncitem):
148     """
149     Run coroutines in an event loop instead of a normal function call.
150     """
151     fast = pyfuncitem.config.getoption("--fast")
152     if asyncio.iscoroutinefunction(pyfuncitem.function):
153         existing_loop = pyfuncitem.funcargs.get('loop', None)
154         with _runtime_warning_context():
155             with _passthrough_loop_context(existing_loop, fast=fast) as _loop:
156                 testargs = {arg: pyfuncitem.funcargs[arg]
157                             for arg in pyfuncitem._fixtureinfo.argnames}
158 
159                 task = _loop.create_task(pyfuncitem.obj(**testargs))
160                 _loop.run_until_complete(task)
161 
162         return True
163 
164 
165 def pytest_configure(config):
166     loops = config.getoption('--loop')
167 
168     factories = {'pyloop': asyncio.new_event_loop}
169 
170     if uvloop is not None:  # pragma: no cover
171         factories['uvloop'] = uvloop.new_event_loop
172 
173     if tokio is not None:  # pragma: no cover
174         factories['tokio'] = tokio.new_event_loop
175 
176     LOOP_FACTORIES.clear()
177     LOOP_FACTORY_IDS.clear()
178 
179     if loops == 'all':
180         loops = 'pyloop,uvloop?,tokio?'
181 
182     for name in loops.split(','):
183         required = not name.endswith('?')
184         name = name.strip(' ?')
185         if name in factories:
186             LOOP_FACTORIES.append(factories[name])
187             LOOP_FACTORY_IDS.append(name)
188         elif required:
189             raise ValueError(
190                 "Unknown loop '%s', available loops: %s" % (
191                     name, list(factories.keys())))
192     asyncio.set_event_loop(None)
193 
194 
195 LOOP_FACTORIES = []
196 LOOP_FACTORY_IDS = []
197 
198 
199 @pytest.fixture(params=LOOP_FACTORIES, ids=LOOP_FACTORY_IDS)
200 def loop(request):
201     """Return an instance of the event loop."""
202     fast = request.config.getoption('--fast')
203     debug = request.config.getoption('--enable-loop-debug')
204 
205     with loop_context(request.param, fast=fast) as _loop:
206         if debug:
207             _loop.set_debug(True)  # pragma: no cover
208         yield _loop
209 
210 
211 @pytest.fixture
212 def unused_port():
213     """Return a port that is unused on the current host."""
214     return _unused_port
215 
216 
217 @pytest.yield_fixture
218 def test_server(loop):
219     """Factory to create a TestServer instance, given an app.
220 
221     test_server(app, **kwargs)
222     """
223     servers = []
224 
225     @asyncio.coroutine
226     def go(app, **kwargs):
227         server = TestServer(app)
228         yield from server.start_server(loop=loop, **kwargs)
229         servers.append(server)
230         return server
231 
232     yield go
233 
234     @asyncio.coroutine
235     def finalize():
236         while servers:
237             yield from servers.pop().close()
238 
239     loop.run_until_complete(finalize())
240 
241 
242 @pytest.yield_fixture
243 def raw_test_server(loop):
244     """Factory to create a RawTestServer instance, given a web handler.
245 
246     raw_test_server(handler, **kwargs)
247     """
248     servers = []
249 
250     @asyncio.coroutine
251     def go(handler, **kwargs):
252         server = RawTestServer(handler)
253         yield from server.start_server(loop=loop, **kwargs)
254         servers.append(server)
255         return server
256 
257     yield go
258 
259     @asyncio.coroutine
260     def finalize():
261         while servers:
262             yield from servers.pop().close()
263 
264     loop.run_until_complete(finalize())
265 
266 
267 @pytest.yield_fixture
268 def test_client(loop):
269     """Factory to create a TestClient instance.
270 
271     test_client(app, **kwargs)
272     test_client(server, **kwargs)
273     test_client(raw_server, **kwargs)
274     """
275     clients = []
276 
277     @asyncio.coroutine
278     def go(__param, *args, server_kwargs=None, **kwargs):
279 
280         if isinstance(__param, collections.Callable) and \
281                 not isinstance(__param, (Application, BaseTestServer)):
282             __param = __param(loop, *args, **kwargs)
283             kwargs = {}
284         else:
285             assert not args, "args should be empty"
286 
287         if isinstance(__param, Application):
288             server_kwargs = server_kwargs or {}
289             server = TestServer(__param, loop=loop, **server_kwargs)
290             client = TestClient(server, loop=loop, **kwargs)
291         elif isinstance(__param, BaseTestServer):
292             client = TestClient(__param, loop=loop, **kwargs)
293         else:
294             raise ValueError("Unknown argument type: %r" % type(__param))
295 
296         yield from client.start_server()
297         clients.append(client)
298         return client
299 
300     yield go
301 
302     @asyncio.coroutine
303     def finalize():
304         while clients:
305             yield from clients.pop().close()
306 
307     loop.run_until_complete(finalize())
308 
309 
310 @pytest.fixture
311 def shorttmpdir():
312     """Provides a temporary directory with a shorter file system path than the
313     tmpdir fixture.
314     """
315     tmpdir = path.local(tempfile.mkdtemp())
316     yield tmpdir
317     tmpdir.remove(rec=1)
318
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/aiohttp/pytest_plugin.py b/aiohttp/pytest_plugin.py
--- a/aiohttp/pytest_plugin.py
+++ b/aiohttp/pytest_plugin.py
@@ -96,8 +96,14 @@
 
 @pytest.fixture
 def fast(request):
-    """ --fast config option """
-    return request.config.getoption('--fast')  # pragma: no cover
+    """--fast config option"""
+    return request.config.getoption('--fast')
+
+
+@pytest.fixture
+def loop_debug(request):
+    """--enable-loop-debug config option"""
+    return request.config.getoption('--enable-loop-debug')
 
 
 @contextlib.contextmanager
@@ -162,50 +168,47 @@
         return True
 
 
-def pytest_configure(config):
-    loops = config.getoption('--loop')
+def pytest_generate_tests(metafunc):
+    if 'loop_factory' not in metafunc.fixturenames:
+        return
 
-    factories = {'pyloop': asyncio.new_event_loop}
+    loops = metafunc.config.option.loop
+    avail_factories = {'pyloop': asyncio.new_event_loop}
 
     if uvloop is not None:  # pragma: no cover
-        factories['uvloop'] = uvloop.new_event_loop
+        avail_factories['uvloop'] = uvloop.new_event_loop
 
     if tokio is not None:  # pragma: no cover
-        factories['tokio'] = tokio.new_event_loop
-
-    LOOP_FACTORIES.clear()
-    LOOP_FACTORY_IDS.clear()
+        avail_factories['tokio'] = tokio.new_event_loop
 
     if loops == 'all':
         loops = 'pyloop,uvloop?,tokio?'
 
+    factories = {}
     for name in loops.split(','):
         required = not name.endswith('?')
         name = name.strip(' ?')
-        if name in factories:
-            LOOP_FACTORIES.append(factories[name])
-            LOOP_FACTORY_IDS.append(name)
-        elif required:
-            raise ValueError(
-                "Unknown loop '%s', available loops: %s" % (
-                    name, list(factories.keys())))
-    asyncio.set_event_loop(None)
+        if name not in avail_factories:  # pragma: no cover
+            if required:
+                raise ValueError(
+                    "Unknown loop '%s', available loops: %s" % (
+                        name, list(factories.keys())))
+            else:
+                continue
+        factories[name] = avail_factories[name]
+    metafunc.parametrize("loop_factory",
+                         list(factories.values()),
+                         ids=list(factories.keys()))
 
 
-LOOP_FACTORIES = []
-LOOP_FACTORY_IDS = []
-
-
-@pytest.fixture(params=LOOP_FACTORIES, ids=LOOP_FACTORY_IDS)
-def loop(request):
+@pytest.fixture
+def loop(loop_factory, fast, loop_debug):
     """Return an instance of the event loop."""
-    fast = request.config.getoption('--fast')
-    debug = request.config.getoption('--enable-loop-debug')
-
-    with loop_context(request.param, fast=fast) as _loop:
-        if debug:
+    with loop_context(loop_factory, fast=fast) as _loop:
+        if loop_debug:
             _loop.set_debug(True)  # pragma: no cover
         yield _loop
+    asyncio.set_event_loop(None)
 
 
 @pytest.fixture

{"golden_diff": "diff --git a/aiohttp/pytest_plugin.py b/aiohttp/pytest_plugin.py\n--- a/aiohttp/pytest_plugin.py\n+++ b/aiohttp/pytest_plugin.py\n@@ -96,8 +96,14 @@\n \n @pytest.fixture\n def fast(request):\n-    \"\"\" --fast config option \"\"\"\n-    return request.config.getoption('--fast')  # pragma: no cover\n+    \"\"\"--fast config option\"\"\"\n+    return request.config.getoption('--fast')\n+\n+\n+@pytest.fixture\n+def loop_debug(request):\n+    \"\"\"--enable-loop-debug config option\"\"\"\n+    return request.config.getoption('--enable-loop-debug')\n \n \n @contextlib.contextmanager\n@@ -162,50 +168,47 @@\n         return True\n \n \n-def pytest_configure(config):\n-    loops = config.getoption('--loop')\n+def pytest_generate_tests(metafunc):\n+    if 'loop_factory' not in metafunc.fixturenames:\n+        return\n \n-    factories = {'pyloop': asyncio.new_event_loop}\n+    loops = metafunc.config.option.loop\n+    avail_factories = {'pyloop': asyncio.new_event_loop}\n \n     if uvloop is not None:  # pragma: no cover\n-        factories['uvloop'] = uvloop.new_event_loop\n+        avail_factories['uvloop'] = uvloop.new_event_loop\n \n     if tokio is not None:  # pragma: no cover\n-        factories['tokio'] = tokio.new_event_loop\n-\n-    LOOP_FACTORIES.clear()\n-    LOOP_FACTORY_IDS.clear()\n+        avail_factories['tokio'] = tokio.new_event_loop\n \n     if loops == 'all':\n         loops = 'pyloop,uvloop?,tokio?'\n \n+    factories = {}\n     for name in loops.split(','):\n         required = not name.endswith('?')\n         name = name.strip(' ?')\n-        if name in factories:\n-            LOOP_FACTORIES.append(factories[name])\n-            LOOP_FACTORY_IDS.append(name)\n-        elif required:\n-            raise ValueError(\n-                \"Unknown loop '%s', available loops: %s\" % (\n-                    name, list(factories.keys())))\n-    asyncio.set_event_loop(None)\n+        if name not in avail_factories:  # pragma: no cover\n+            if required:\n+                raise ValueError(\n+                    \"Unknown loop '%s', available loops: %s\" % (\n+                        name, list(factories.keys())))\n+            else:\n+                continue\n+        factories[name] = avail_factories[name]\n+    metafunc.parametrize(\"loop_factory\",\n+                         list(factories.values()),\n+                         ids=list(factories.keys()))\n \n \n-LOOP_FACTORIES = []\n-LOOP_FACTORY_IDS = []\n-\n-\n-@pytest.fixture(params=LOOP_FACTORIES, ids=LOOP_FACTORY_IDS)\n-def loop(request):\n+@pytest.fixture\n+def loop(loop_factory, fast, loop_debug):\n     \"\"\"Return an instance of the event loop.\"\"\"\n-    fast = request.config.getoption('--fast')\n-    debug = request.config.getoption('--enable-loop-debug')\n-\n-    with loop_context(request.param, fast=fast) as _loop:\n-        if debug:\n+    with loop_context(loop_factory, fast=fast) as _loop:\n+        if loop_debug:\n             _loop.set_debug(True)  # pragma: no cover\n         yield _loop\n+    asyncio.set_event_loop(None)\n \n \n @pytest.fixture\n", "issue": "pytest-aiohttp: compatibility with pytest v3.3.0\n## Long story short\r\n\r\nhttps://github.com/pytest-dev/pytest/issues/2959\r\nFixture parameters are now immutable, [pytest_plugin.py](https://github.com/aio-libs/aiohttp/blob/master/aiohttp/pytest_plugin.py#L195-L200) need to be updated\r\n\npytest-aiohttp: compatibility with pytest v3.3.0\n## Long story short\r\n\r\nhttps://github.com/pytest-dev/pytest/issues/2959\r\nFixture parameters are now immutable, [pytest_plugin.py](https://github.com/aio-libs/aiohttp/blob/master/aiohttp/pytest_plugin.py#L195-L200) need to be updated\r\n\n", "before_files": [{"content": "import asyncio\nimport collections\nimport contextlib\nimport tempfile\nimport warnings\n\nimport pytest\nfrom py import path\n\nfrom aiohttp.helpers import isasyncgenfunction\nfrom aiohttp.web import Application\n\nfrom .test_utils import unused_port as _unused_port\nfrom .test_utils import (BaseTestServer, RawTestServer, TestClient, TestServer,\n                         loop_context, setup_test_loop, teardown_test_loop)\n\n\ntry:\n    import uvloop\nexcept:  # pragma: no cover\n    uvloop = None\n\ntry:\n    import tokio\nexcept:  # pragma: no cover\n    tokio = None\n\n\ndef pytest_addoption(parser):\n    parser.addoption(\n        '--fast', action='store_true', default=False,\n        help='run tests faster by disabling extra checks')\n    parser.addoption(\n        '--loop', action='store', default='pyloop',\n        help='run tests with specific loop: pyloop, uvloop, tokio or all')\n    parser.addoption(\n        '--enable-loop-debug', action='store_true', default=False,\n        help='enable event loop debug mode')\n\n\ndef pytest_fixture_setup(fixturedef, request):\n    \"\"\"\n    Allow fixtures to be coroutines. Run coroutine fixtures in an event loop.\n    \"\"\"\n    func = fixturedef.func\n\n    if isasyncgenfunction(func):\n        # async generator fixture\n        is_async_gen = True\n    elif asyncio.iscoroutinefunction(func):\n        # regular async fixture\n        is_async_gen = False\n    else:\n        # not an async fixture, nothing to do\n        return\n\n    strip_request = False\n    if 'request' not in fixturedef.argnames:\n        fixturedef.argnames += ('request',)\n        strip_request = True\n\n    def wrapper(*args, **kwargs):\n        request = kwargs['request']\n        if strip_request:\n            del kwargs['request']\n\n        # if neither the fixture nor the test use the 'loop' fixture,\n        # 'getfixturevalue' will fail because the test is not parameterized\n        # (this can be removed someday if 'loop' is no longer parameterized)\n        if 'loop' not in request.fixturenames:\n            raise Exception(\n                \"Asynchronous fixtures must depend on the 'loop' fixture or \"\n                \"be used in tests depending from it.\"\n            )\n\n        _loop = request.getfixturevalue('loop')\n\n        if is_async_gen:\n            # for async generators, we need to advance the generator once,\n            # then advance it again in a finalizer\n            gen = func(*args, **kwargs)\n\n            def finalizer():\n                try:\n                    return _loop.run_until_complete(gen.__anext__())\n                except StopAsyncIteration:  # NOQA\n                    pass\n\n            request.addfinalizer(finalizer)\n            return _loop.run_until_complete(gen.__anext__())\n        else:\n            return _loop.run_until_complete(func(*args, **kwargs))\n\n    fixturedef.func = wrapper\n\n\n@pytest.fixture\ndef fast(request):\n    \"\"\" --fast config option \"\"\"\n    return request.config.getoption('--fast')  # pragma: no cover\n\n\n@contextlib.contextmanager\ndef _runtime_warning_context():\n    \"\"\"\n    Context manager which checks for RuntimeWarnings, specifically to\n    avoid \"coroutine 'X' was never awaited\" warnings being missed.\n\n    If RuntimeWarnings occur in the context a RuntimeError is raised.\n    \"\"\"\n    with warnings.catch_warnings(record=True) as _warnings:\n        yield\n        rw = ['{w.filename}:{w.lineno}:{w.message}'.format(w=w)\n              for w in _warnings if w.category == RuntimeWarning]\n        if rw:\n            raise RuntimeError('{} Runtime Warning{},\\n{}'.format(\n                len(rw),\n                '' if len(rw) == 1 else 's',\n                '\\n'.join(rw)\n            ))\n\n\n@contextlib.contextmanager\ndef _passthrough_loop_context(loop, fast=False):\n    \"\"\"\n    setups and tears down a loop unless one is passed in via the loop\n    argument when it's passed straight through.\n    \"\"\"\n    if loop:\n        # loop already exists, pass it straight through\n        yield loop\n    else:\n        # this shadows loop_context's standard behavior\n        loop = setup_test_loop()\n        yield loop\n        teardown_test_loop(loop, fast=fast)\n\n\ndef pytest_pycollect_makeitem(collector, name, obj):\n    \"\"\"\n    Fix pytest collecting for coroutines.\n    \"\"\"\n    if collector.funcnamefilter(name) and asyncio.iscoroutinefunction(obj):\n        return list(collector._genfunctions(name, obj))\n\n\ndef pytest_pyfunc_call(pyfuncitem):\n    \"\"\"\n    Run coroutines in an event loop instead of a normal function call.\n    \"\"\"\n    fast = pyfuncitem.config.getoption(\"--fast\")\n    if asyncio.iscoroutinefunction(pyfuncitem.function):\n        existing_loop = pyfuncitem.funcargs.get('loop', None)\n        with _runtime_warning_context():\n            with _passthrough_loop_context(existing_loop, fast=fast) as _loop:\n                testargs = {arg: pyfuncitem.funcargs[arg]\n                            for arg in pyfuncitem._fixtureinfo.argnames}\n\n                task = _loop.create_task(pyfuncitem.obj(**testargs))\n                _loop.run_until_complete(task)\n\n        return True\n\n\ndef pytest_configure(config):\n    loops = config.getoption('--loop')\n\n    factories = {'pyloop': asyncio.new_event_loop}\n\n    if uvloop is not None:  # pragma: no cover\n        factories['uvloop'] = uvloop.new_event_loop\n\n    if tokio is not None:  # pragma: no cover\n        factories['tokio'] = tokio.new_event_loop\n\n    LOOP_FACTORIES.clear()\n    LOOP_FACTORY_IDS.clear()\n\n    if loops == 'all':\n        loops = 'pyloop,uvloop?,tokio?'\n\n    for name in loops.split(','):\n        required = not name.endswith('?')\n        name = name.strip(' ?')\n        if name in factories:\n            LOOP_FACTORIES.append(factories[name])\n            LOOP_FACTORY_IDS.append(name)\n        elif required:\n            raise ValueError(\n                \"Unknown loop '%s', available loops: %s\" % (\n                    name, list(factories.keys())))\n    asyncio.set_event_loop(None)\n\n\nLOOP_FACTORIES = []\nLOOP_FACTORY_IDS = []\n\n\n@pytest.fixture(params=LOOP_FACTORIES, ids=LOOP_FACTORY_IDS)\ndef loop(request):\n    \"\"\"Return an instance of the event loop.\"\"\"\n    fast = request.config.getoption('--fast')\n    debug = request.config.getoption('--enable-loop-debug')\n\n    with loop_context(request.param, fast=fast) as _loop:\n        if debug:\n            _loop.set_debug(True)  # pragma: no cover\n        yield _loop\n\n\n@pytest.fixture\ndef unused_port():\n    \"\"\"Return a port that is unused on the current host.\"\"\"\n    return _unused_port\n\n\n@pytest.yield_fixture\ndef test_server(loop):\n    \"\"\"Factory to create a TestServer instance, given an app.\n\n    test_server(app, **kwargs)\n    \"\"\"\n    servers = []\n\n    @asyncio.coroutine\n    def go(app, **kwargs):\n        server = TestServer(app)\n        yield from server.start_server(loop=loop, **kwargs)\n        servers.append(server)\n        return server\n\n    yield go\n\n    @asyncio.coroutine\n    def finalize():\n        while servers:\n            yield from servers.pop().close()\n\n    loop.run_until_complete(finalize())\n\n\n@pytest.yield_fixture\ndef raw_test_server(loop):\n    \"\"\"Factory to create a RawTestServer instance, given a web handler.\n\n    raw_test_server(handler, **kwargs)\n    \"\"\"\n    servers = []\n\n    @asyncio.coroutine\n    def go(handler, **kwargs):\n        server = RawTestServer(handler)\n        yield from server.start_server(loop=loop, **kwargs)\n        servers.append(server)\n        return server\n\n    yield go\n\n    @asyncio.coroutine\n    def finalize():\n        while servers:\n            yield from servers.pop().close()\n\n    loop.run_until_complete(finalize())\n\n\n@pytest.yield_fixture\ndef test_client(loop):\n    \"\"\"Factory to create a TestClient instance.\n\n    test_client(app, **kwargs)\n    test_client(server, **kwargs)\n    test_client(raw_server, **kwargs)\n    \"\"\"\n    clients = []\n\n    @asyncio.coroutine\n    def go(__param, *args, server_kwargs=None, **kwargs):\n\n        if isinstance(__param, collections.Callable) and \\\n                not isinstance(__param, (Application, BaseTestServer)):\n            __param = __param(loop, *args, **kwargs)\n            kwargs = {}\n        else:\n            assert not args, \"args should be empty\"\n\n        if isinstance(__param, Application):\n            server_kwargs = server_kwargs or {}\n            server = TestServer(__param, loop=loop, **server_kwargs)\n            client = TestClient(server, loop=loop, **kwargs)\n        elif isinstance(__param, BaseTestServer):\n            client = TestClient(__param, loop=loop, **kwargs)\n        else:\n            raise ValueError(\"Unknown argument type: %r\" % type(__param))\n\n        yield from client.start_server()\n        clients.append(client)\n        return client\n\n    yield go\n\n    @asyncio.coroutine\n    def finalize():\n        while clients:\n            yield from clients.pop().close()\n\n    loop.run_until_complete(finalize())\n\n\n@pytest.fixture\ndef shorttmpdir():\n    \"\"\"Provides a temporary directory with a shorter file system path than the\n    tmpdir fixture.\n    \"\"\"\n    tmpdir = path.local(tempfile.mkdtemp())\n    yield tmpdir\n    tmpdir.remove(rec=1)\n", "path": "aiohttp/pytest_plugin.py"}], "after_files": [{"content": "import asyncio\nimport collections\nimport contextlib\nimport tempfile\nimport warnings\n\nimport pytest\nfrom py import path\n\nfrom aiohttp.helpers import isasyncgenfunction\nfrom aiohttp.web import Application\n\nfrom .test_utils import unused_port as _unused_port\nfrom .test_utils import (BaseTestServer, RawTestServer, TestClient, TestServer,\n                         loop_context, setup_test_loop, teardown_test_loop)\n\n\ntry:\n    import uvloop\nexcept:  # pragma: no cover\n    uvloop = None\n\ntry:\n    import tokio\nexcept:  # pragma: no cover\n    tokio = None\n\n\ndef pytest_addoption(parser):\n    parser.addoption(\n        '--fast', action='store_true', default=False,\n        help='run tests faster by disabling extra checks')\n    parser.addoption(\n        '--loop', action='store', default='pyloop',\n        help='run tests with specific loop: pyloop, uvloop, tokio or all')\n    parser.addoption(\n        '--enable-loop-debug', action='store_true', default=False,\n        help='enable event loop debug mode')\n\n\ndef pytest_fixture_setup(fixturedef, request):\n    \"\"\"\n    Allow fixtures to be coroutines. Run coroutine fixtures in an event loop.\n    \"\"\"\n    func = fixturedef.func\n\n    if isasyncgenfunction(func):\n        # async generator fixture\n        is_async_gen = True\n    elif asyncio.iscoroutinefunction(func):\n        # regular async fixture\n        is_async_gen = False\n    else:\n        # not an async fixture, nothing to do\n        return\n\n    strip_request = False\n    if 'request' not in fixturedef.argnames:\n        fixturedef.argnames += ('request',)\n        strip_request = True\n\n    def wrapper(*args, **kwargs):\n        request = kwargs['request']\n        if strip_request:\n            del kwargs['request']\n\n        # if neither the fixture nor the test use the 'loop' fixture,\n        # 'getfixturevalue' will fail because the test is not parameterized\n        # (this can be removed someday if 'loop' is no longer parameterized)\n        if 'loop' not in request.fixturenames:\n            raise Exception(\n                \"Asynchronous fixtures must depend on the 'loop' fixture or \"\n                \"be used in tests depending from it.\"\n            )\n\n        _loop = request.getfixturevalue('loop')\n\n        if is_async_gen:\n            # for async generators, we need to advance the generator once,\n            # then advance it again in a finalizer\n            gen = func(*args, **kwargs)\n\n            def finalizer():\n                try:\n                    return _loop.run_until_complete(gen.__anext__())\n                except StopAsyncIteration:  # NOQA\n                    pass\n\n            request.addfinalizer(finalizer)\n            return _loop.run_until_complete(gen.__anext__())\n        else:\n            return _loop.run_until_complete(func(*args, **kwargs))\n\n    fixturedef.func = wrapper\n\n\n@pytest.fixture\ndef fast(request):\n    \"\"\"--fast config option\"\"\"\n    return request.config.getoption('--fast')\n\n\n@pytest.fixture\ndef loop_debug(request):\n    \"\"\"--enable-loop-debug config option\"\"\"\n    return request.config.getoption('--enable-loop-debug')\n\n\n@contextlib.contextmanager\ndef _runtime_warning_context():\n    \"\"\"\n    Context manager which checks for RuntimeWarnings, specifically to\n    avoid \"coroutine 'X' was never awaited\" warnings being missed.\n\n    If RuntimeWarnings occur in the context a RuntimeError is raised.\n    \"\"\"\n    with warnings.catch_warnings(record=True) as _warnings:\n        yield\n        rw = ['{w.filename}:{w.lineno}:{w.message}'.format(w=w)\n              for w in _warnings if w.category == RuntimeWarning]\n        if rw:\n            raise RuntimeError('{} Runtime Warning{},\\n{}'.format(\n                len(rw),\n                '' if len(rw) == 1 else 's',\n                '\\n'.join(rw)\n            ))\n\n\n@contextlib.contextmanager\ndef _passthrough_loop_context(loop, fast=False):\n    \"\"\"\n    setups and tears down a loop unless one is passed in via the loop\n    argument when it's passed straight through.\n    \"\"\"\n    if loop:\n        # loop already exists, pass it straight through\n        yield loop\n    else:\n        # this shadows loop_context's standard behavior\n        loop = setup_test_loop()\n        yield loop\n        teardown_test_loop(loop, fast=fast)\n\n\ndef pytest_pycollect_makeitem(collector, name, obj):\n    \"\"\"\n    Fix pytest collecting for coroutines.\n    \"\"\"\n    if collector.funcnamefilter(name) and asyncio.iscoroutinefunction(obj):\n        return list(collector._genfunctions(name, obj))\n\n\ndef pytest_pyfunc_call(pyfuncitem):\n    \"\"\"\n    Run coroutines in an event loop instead of a normal function call.\n    \"\"\"\n    fast = pyfuncitem.config.getoption(\"--fast\")\n    if asyncio.iscoroutinefunction(pyfuncitem.function):\n        existing_loop = pyfuncitem.funcargs.get('loop', None)\n        with _runtime_warning_context():\n            with _passthrough_loop_context(existing_loop, fast=fast) as _loop:\n                testargs = {arg: pyfuncitem.funcargs[arg]\n                            for arg in pyfuncitem._fixtureinfo.argnames}\n\n                task = _loop.create_task(pyfuncitem.obj(**testargs))\n                _loop.run_until_complete(task)\n\n        return True\n\n\ndef pytest_generate_tests(metafunc):\n    if 'loop_factory' not in metafunc.fixturenames:\n        return\n\n    loops = metafunc.config.option.loop\n    avail_factories = {'pyloop': asyncio.new_event_loop}\n\n    if uvloop is not None:  # pragma: no cover\n        avail_factories['uvloop'] = uvloop.new_event_loop\n\n    if tokio is not None:  # pragma: no cover\n        avail_factories['tokio'] = tokio.new_event_loop\n\n    if loops == 'all':\n        loops = 'pyloop,uvloop?,tokio?'\n\n    factories = {}\n    for name in loops.split(','):\n        required = not name.endswith('?')\n        name = name.strip(' ?')\n        if name not in avail_factories:  # pragma: no cover\n            if required:\n                raise ValueError(\n                    \"Unknown loop '%s', available loops: %s\" % (\n                        name, list(factories.keys())))\n            else:\n                continue\n        factories[name] = avail_factories[name]\n    metafunc.parametrize(\"loop_factory\",\n                         list(factories.values()),\n                         ids=list(factories.keys()))\n\n\n@pytest.fixture\ndef loop(loop_factory, fast, loop_debug):\n    \"\"\"Return an instance of the event loop.\"\"\"\n    with loop_context(loop_factory, fast=fast) as _loop:\n        if loop_debug:\n            _loop.set_debug(True)  # pragma: no cover\n        yield _loop\n    asyncio.set_event_loop(None)\n\n\n@pytest.fixture\ndef unused_port():\n    \"\"\"Return a port that is unused on the current host.\"\"\"\n    return _unused_port\n\n\n@pytest.yield_fixture\ndef test_server(loop):\n    \"\"\"Factory to create a TestServer instance, given an app.\n\n    test_server(app, **kwargs)\n    \"\"\"\n    servers = []\n\n    @asyncio.coroutine\n    def go(app, **kwargs):\n        server = TestServer(app)\n        yield from server.start_server(loop=loop, **kwargs)\n        servers.append(server)\n        return server\n\n    yield go\n\n    @asyncio.coroutine\n    def finalize():\n        while servers:\n            yield from servers.pop().close()\n\n    loop.run_until_complete(finalize())\n\n\n@pytest.yield_fixture\ndef raw_test_server(loop):\n    \"\"\"Factory to create a RawTestServer instance, given a web handler.\n\n    raw_test_server(handler, **kwargs)\n    \"\"\"\n    servers = []\n\n    @asyncio.coroutine\n    def go(handler, **kwargs):\n        server = RawTestServer(handler)\n        yield from server.start_server(loop=loop, **kwargs)\n        servers.append(server)\n        return server\n\n    yield go\n\n    @asyncio.coroutine\n    def finalize():\n        while servers:\n            yield from servers.pop().close()\n\n    loop.run_until_complete(finalize())\n\n\n@pytest.yield_fixture\ndef test_client(loop):\n    \"\"\"Factory to create a TestClient instance.\n\n    test_client(app, **kwargs)\n    test_client(server, **kwargs)\n    test_client(raw_server, **kwargs)\n    \"\"\"\n    clients = []\n\n    @asyncio.coroutine\n    def go(__param, *args, server_kwargs=None, **kwargs):\n\n        if isinstance(__param, collections.Callable) and \\\n                not isinstance(__param, (Application, BaseTestServer)):\n            __param = __param(loop, *args, **kwargs)\n            kwargs = {}\n        else:\n            assert not args, \"args should be empty\"\n\n        if isinstance(__param, Application):\n            server_kwargs = server_kwargs or {}\n            server = TestServer(__param, loop=loop, **server_kwargs)\n            client = TestClient(server, loop=loop, **kwargs)\n        elif isinstance(__param, BaseTestServer):\n            client = TestClient(__param, loop=loop, **kwargs)\n        else:\n            raise ValueError(\"Unknown argument type: %r\" % type(__param))\n\n        yield from client.start_server()\n        clients.append(client)\n        return client\n\n    yield go\n\n    @asyncio.coroutine\n    def finalize():\n        while clients:\n            yield from clients.pop().close()\n\n    loop.run_until_complete(finalize())\n\n\n@pytest.fixture\ndef shorttmpdir():\n    \"\"\"Provides a temporary directory with a shorter file system path than the\n    tmpdir fixture.\n    \"\"\"\n    tmpdir = path.local(tempfile.mkdtemp())\n    yield tmpdir\n    tmpdir.remove(rec=1)\n", "path": "aiohttp/pytest_plugin.py"}]}