Hello community,

here is the log from the commit of package python-aioresponses for 
openSUSE:Factory checked in at 2020-11-02 09:39:05
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-aioresponses (Old)
 and      /work/SRC/openSUSE:Factory/.python-aioresponses.new.3463 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-aioresponses"

Mon Nov  2 09:39:05 2020 rev:9 rq:844824 version:0.7.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-aioresponses/python-aioresponses.changes  
2020-08-12 10:36:49.048300797 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-aioresponses.new.3463/python-aioresponses.changes
        2020-11-02 09:39:24.413553128 +0100
@@ -1,0 +2,10 @@
+Wed Oct 28 14:43:39 UTC 2020 - John Vandenberg <[email protected]>
+
+- Remove no longer necessary aioresponses-replace-asynctest.patch
+- Add pr_174.patch to add compatibility with aiohttp 3.7.0
+- Update to v0.7.0
+  * fixes race condition while removing matchers
+  * drop support for py3.5 and aiohttp2.x
+  * replace asynctest with native Python 3.8 unittest
+
+-------------------------------------------------------------------

Old:
----
  aioresponses-0.6.4.tar.gz
  aioresponses-replace-asynctest.patch

New:
----
  aioresponses-0.7.0.tar.gz
  pr_174.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-aioresponses.spec ++++++
--- /var/tmp/diff_new_pack.wvVjAV/_old  2020-11-02 09:39:26.137554783 +0100
+++ /var/tmp/diff_new_pack.wvVjAV/_new  2020-11-02 09:39:26.141554787 +0100
@@ -19,14 +19,14 @@
 %{?!python_module:%define python_module() python3-%{**}}
 %define skip_python2 1
 Name:           python-aioresponses
-Version:        0.6.4
+Version:        0.7.0
 Release:        0
 Summary:        Python module for mocking out requests made by ClientSession 
from aiohttp
 License:        MIT
 URL:            https://github.com/pnuckowski/aioresponses
 Source:         
https://files.pythonhosted.org/packages/source/a/aioresponses/aioresponses-%{version}.tar.gz
-# PATCH-FIX-UPSTREAM aioresponses-replace-asynctest.patch 
gh#pnuckowski/aioresponses#166
-Patch0:         aioresponses-replace-asynctest.patch
+# PATCH-FIX-UPSTREAM pr_174.patch gh#pnuckowski/aioresponses#174
+Patch0:         pr_174.patch
 BuildRequires:  %{python_module aiohttp >= 2.0.0}
 BuildRequires:  %{python_module base >= 3.8}
 BuildRequires:  %{python_module ddt >= 1.1.0}

++++++ aioresponses-0.6.4.tar.gz -> aioresponses-0.7.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioresponses-0.6.4/.travis.yml 
new/aioresponses-0.7.0/.travis.yml
--- old/aioresponses-0.6.4/.travis.yml  2020-02-11 22:27:00.000000000 +0100
+++ new/aioresponses-0.7.0/.travis.yml  2020-08-22 21:41:32.000000000 +0200
@@ -5,37 +5,6 @@
 
 matrix:
   include:
-  - python: 3.5
-    env: TOXENV=py35-aiohttp20
-  - python: 3.5
-    env: TOXENV=py35-aiohttp21
-  - python: 3.5
-    env: TOXENV=py35-aiohttp22
-  - python: 3.5
-    env: TOXENV=py35-aiohttp23
-  - python: 3.5
-    env: TOXENV=py35-aiohttp30
-  - python: 3.5
-    env: TOXENV=py35-aiohttp31
-  - python: 3.5
-    env: TOXENV=py35-aiohttp32
-  - python: 3.5
-    env: TOXENV=py35-aiohttp33
-  - python: 3.5
-    env: TOXENV=py35-aiohttp34
-  - python: 3.5
-    env: TOXENV=py35-aiohttp35
-  - python: 3.5
-    env: TOXENV=py35-aiohttp36
-
-  - python: 3.6
-    env: TOXENV=py36-aiohttp20
-  - python: 3.6
-    env: TOXENV=py36-aiohttp21
-  - python: 3.6
-    env: TOXENV=py36-aiohttp22
-  - python: 3.6
-    env: TOXENV=py36-aiohttp23
   - python: 3.6
     env: TOXENV=py36-aiohttp30
   - python: 3.6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioresponses-0.6.4/AUTHORS 
new/aioresponses-0.7.0/AUTHORS
--- old/aioresponses-0.6.4/AUTHORS      2020-06-02 11:15:01.000000000 +0200
+++ new/aioresponses-0.7.0/AUTHORS      2020-10-19 17:04:57.000000000 +0200
@@ -5,6 +5,7 @@
 Allisson Azevedo <[email protected]>
 Andrew Grinevich <[email protected]>
 Anthony Lukach <[email protected]>
+Ben Greiner <[email protected]>
 Brett Wandel <[email protected]>
 Bryce Drennan <[email protected]>
 Colin-b <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioresponses-0.6.4/ChangeLog 
new/aioresponses-0.7.0/ChangeLog
--- old/aioresponses-0.6.4/ChangeLog    2020-06-02 11:15:01.000000000 +0200
+++ new/aioresponses-0.7.0/ChangeLog    2020-10-19 17:04:57.000000000 +0200
@@ -1,6 +1,15 @@
 CHANGES
 =======
 
+0.7.0
+-----
+
+* bump ver to 0.7.0
+* fixes race condition while removing matchers
+* drop support for py3.5 and aiohttp2.x Currently supported versions of 
Python: 3.6, 3.7, 3.8
+* update requirements-dev.txt
+* replace asynctest with native Python 3.8 unittest
+
 0.6.4
 -----
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioresponses-0.6.4/Makefile 
new/aioresponses-0.7.0/Makefile
--- old/aioresponses-0.6.4/Makefile     2019-01-20 00:09:08.000000000 +0100
+++ new/aioresponses-0.7.0/Makefile     2020-08-22 21:41:32.000000000 +0200
@@ -44,6 +44,7 @@
 
 clean-test: ## remove test and coverage artifacts
        rm -fr .tox/
+       rm -fr .pytest_cache/
        rm -f .coverage
        rm -fr htmlcov/
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioresponses-0.6.4/PKG-INFO 
new/aioresponses-0.7.0/PKG-INFO
--- old/aioresponses-0.6.4/PKG-INFO     2020-06-02 11:15:02.000000000 +0200
+++ new/aioresponses-0.7.0/PKG-INFO     2020-10-19 17:05:05.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: aioresponses
-Version: 0.6.4
+Version: 0.7.0
 Summary: Mock out requests made by ClientSession from aiohttp package
 Home-page: https://github.com/pnuckowski/aioresponses
 Author: Pawel Nuckowski
@@ -253,13 +253,15 @@
         
         
 Platform: UNKNOWN
-Classifier: Development Status :: 3 - Alpha
+Classifier: Development Status :: 4 - Beta
 Classifier: Intended Audience :: Developers
+Classifier: Operating System :: OS Independent
 Classifier: Topic :: Internet :: WWW/HTTP
 Classifier: Topic :: Software Development :: Testing
+Classifier: Topic :: Software Development :: Testing :: Mocking
 Classifier: License :: OSI Approved :: MIT License
 Classifier: Natural Language :: English
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioresponses-0.6.4/aioresponses/__init__.py 
new/aioresponses-0.7.0/aioresponses/__init__.py
--- old/aioresponses-0.6.4/aioresponses/__init__.py     2020-02-11 
22:41:24.000000000 +0100
+++ new/aioresponses-0.7.0/aioresponses/__init__.py     2020-10-19 
17:03:15.000000000 +0200
@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 from .core import CallbackResult, aioresponses
 
-__version__ = '0.6.3'
+__version__ = '0.7.0'
 
 __all__ = [
     'CallbackResult',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioresponses-0.6.4/aioresponses/compat.py 
new/aioresponses-0.7.0/aioresponses/compat.py
--- old/aioresponses-0.6.4/aioresponses/compat.py       2019-10-02 
00:32:40.000000000 +0200
+++ new/aioresponses-0.7.0/aioresponses/compat.py       2020-08-22 
21:41:32.000000000 +0200
@@ -9,18 +9,40 @@
 from multidict import MultiDict
 from yarl import URL
 
+try:
+    # as from Py3.8 unittest supports coroutines as test functions
+    from unittest import IsolatedAsyncioTestCase, skipIf
+
+
+    def fail_on(**kw):  # noqa
+        def outer(fn):
+            def inner(*args, **kwargs):
+                return fn(*args, **kwargs)
+
+            return inner
+
+        return outer
+
+
+except ImportError:
+    # fallback to asynctest
+    from asynctest import fail_on, skipIf
+    from asynctest.case import TestCase as IsolatedAsyncioTestCase
+
 if sys.version_info < (3, 7):
     from re import _pattern_type as Pattern
 else:
     from re import Pattern
 
 AIOHTTP_VERSION = StrictVersion(aiohttp_version)
+IS_GTE_PY38 = sys.version_info >= (3, 8)
 
 if AIOHTTP_VERSION >= StrictVersion('3.0.0'):
     from aiohttp.client_proto import ResponseHandler
 
-    def stream_reader_factory(
-            loop: 'Optional[asyncio.AbstractEventLoop]' = None
+
+    def stream_reader_factory(  # noqa
+        loop: 'Optional[asyncio.AbstractEventLoop]' = None
     ):
         protocol = ResponseHandler(loop=loop)
         return StreamReader(protocol, loop=loop)
@@ -46,11 +68,47 @@
     return url.with_query(urlencode(sorted(parse_qsl(url.query_string))))
 
 
+class AsyncTestCase(IsolatedAsyncioTestCase):
+    """Asynchronous test case class that covers up differences in usage
+    between unittest (starting from Python 3.8) and asynctest.
+
+    `setup` and `teardown` is used to be called before each test case
+    (note: that they are in lowercase)
+    """
+
+    async def setup(self):
+        pass
+
+    async def teardown(self):
+        pass
+
+    if IS_GTE_PY38:
+        # from Python3.8
+        async def asyncSetUp(self):
+            self.loop = asyncio.get_event_loop()
+            await self.setup()
+
+        async def asyncTearDown(self):
+            await self.teardown()
+    else:
+        # asynctest
+        use_default_loop = False
+
+        async def setUp(self) -> None:
+            await self.setup()
+
+        async def tearDown(self) -> None:
+            await self.teardown()
+
+
 __all__ = [
     'URL',
     'Pattern',
+    'skipIf',
     'AIOHTTP_VERSION',
+    'AsyncTestCase',
     'merge_params',
     'stream_reader_factory',
     'normalize_url',
+    'fail_on',
 ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioresponses-0.6.4/aioresponses/core.py 
new/aioresponses-0.7.0/aioresponses/core.py
--- old/aioresponses-0.6.4/aioresponses/core.py 2020-06-02 11:12:41.000000000 
+0200
+++ new/aioresponses-0.7.0/aioresponses/core.py 2020-08-23 00:00:53.000000000 
+0200
@@ -1,13 +1,15 @@
 # -*- coding: utf-8 -*-
 import asyncio
-import json
 import copy
+import inspect
+import json
 from collections import namedtuple
 from distutils.version import StrictVersion
 from functools import wraps
 from typing import Callable, Dict, Tuple, Union, Optional, List  # noqa
 from unittest.mock import Mock, patch
-import inspect
+from uuid import uuid4
+
 from aiohttp import (
     ClientConnectionError,
     ClientResponse,
@@ -174,7 +176,7 @@
         return resp
 
     async def build_response(
-            self, url: URL, **kwargs
+        self, url: URL, **kwargs
     ) -> 'Union[ClientResponse, Exception]':
         if self.exception is not None:
             return self.exception
@@ -206,7 +208,7 @@
 
 class aioresponses(object):
     """Mock aiohttp requests made by ClientSession."""
-    _matches = None  # type: List[RequestMatch]
+    _matches = None  # type: Dict[str, RequestMatch]
     _responses = None  # type: List[ClientResponse]
     requests = None  # type: Dict
 
@@ -253,7 +255,7 @@
 
     def start(self):
         self._responses = []
-        self._matches = []
+        self._matches = {}
         self.patcher.start()
         self.patcher.return_value = self._request_mock
 
@@ -296,7 +298,8 @@
             timeout: bool = False,
             reason: Optional[str] = None,
             callback: Optional[Callable] = None) -> None:
-        self._matches.append(RequestMatch(
+
+        self._matches[str(uuid4())] = (RequestMatch(
             url,
             method=method,
             status=status,
@@ -324,12 +327,12 @@
         return False
 
     async def match(
-            self, method: str, url: URL,
-            allow_redirects: bool = True, **kwargs: Dict
+        self, method: str, url: URL,
+        allow_redirects: bool = True, **kwargs: Dict
     ) -> Optional['ClientResponse']:
         history = []
         while True:
-            for i, matcher in enumerate(self._matches):
+            for key, matcher in self._matches.items():
                 if matcher.match(method, url):
                     response_or_exc = await matcher.build_response(
                         url, allow_redirects=allow_redirects, **kwargs
@@ -339,13 +342,12 @@
                 return None
 
             if matcher.repeat is False:
-                del self._matches[i]
+                del self._matches[key]
 
             if self.is_exception(response_or_exc):
                 raise response_or_exc
-
-            if response_or_exc.status in (
-                    301, 302, 303, 307, 308) and allow_redirects:
+            is_redirect = response_or_exc.status in (301, 302, 303, 307, 308)
+            if is_redirect and allow_redirects:
                 if hdrs.LOCATION not in response_or_exc.headers:
                     break
                 history.append(response_or_exc)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioresponses-0.6.4/aioresponses.egg-info/PKG-INFO 
new/aioresponses-0.7.0/aioresponses.egg-info/PKG-INFO
--- old/aioresponses-0.6.4/aioresponses.egg-info/PKG-INFO       2020-06-02 
11:15:01.000000000 +0200
+++ new/aioresponses-0.7.0/aioresponses.egg-info/PKG-INFO       2020-10-19 
17:04:57.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: aioresponses
-Version: 0.6.4
+Version: 0.7.0
 Summary: Mock out requests made by ClientSession from aiohttp package
 Home-page: https://github.com/pnuckowski/aioresponses
 Author: Pawel Nuckowski
@@ -253,13 +253,15 @@
         
         
 Platform: UNKNOWN
-Classifier: Development Status :: 3 - Alpha
+Classifier: Development Status :: 4 - Beta
 Classifier: Intended Audience :: Developers
+Classifier: Operating System :: OS Independent
 Classifier: Topic :: Internet :: WWW/HTTP
 Classifier: Topic :: Software Development :: Testing
+Classifier: Topic :: Software Development :: Testing :: Mocking
 Classifier: License :: OSI Approved :: MIT License
 Classifier: Natural Language :: English
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioresponses-0.6.4/aioresponses.egg-info/pbr.json 
new/aioresponses-0.7.0/aioresponses.egg-info/pbr.json
--- old/aioresponses-0.6.4/aioresponses.egg-info/pbr.json       2020-06-02 
11:15:01.000000000 +0200
+++ new/aioresponses-0.7.0/aioresponses.egg-info/pbr.json       2020-10-19 
17:04:57.000000000 +0200
@@ -1 +1 @@
-{"git_version": "fc8f747", "is_release": false}
\ No newline at end of file
+{"git_version": "e61977f", "is_release": false}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioresponses-0.6.4/requirements-dev.txt 
new/aioresponses-0.7.0/requirements-dev.txt
--- old/aioresponses-0.6.4/requirements-dev.txt 2019-11-22 08:35:35.000000000 
+0100
+++ new/aioresponses-0.7.0/requirements-dev.txt 2020-08-22 21:41:32.000000000 
+0200
@@ -1,12 +1,12 @@
 pip
 wheel
-flake8==3.5.0
-tox==3.4.0
-coverage==4.5.1
+flake8==3.8.3
+tox==3.19.0
+coverage==5.2.1
 Sphinx==1.5.6
-pytest==3.8.1
-pytest-cov==2.6.0
-pytest-html==1.19.0
-ddt==1.2.0
+pytest==6.0.1
+pytest-cov==2.10.1
+pytest-html==2.1.1
+ddt==1.4.1
 typing
-asynctest==0.12.2
\ No newline at end of file
+asynctest==0.13.0
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioresponses-0.6.4/setup.cfg 
new/aioresponses-0.7.0/setup.cfg
--- old/aioresponses-0.6.4/setup.cfg    2020-06-02 11:15:02.000000000 +0200
+++ new/aioresponses-0.7.0/setup.cfg    2020-10-19 17:05:05.000000000 +0200
@@ -6,16 +6,18 @@
 description-file = README.rst
 home-page = https://github.com/pnuckowski/aioresponses
 classifier = 
-       Development Status :: 3 - Alpha
+       Development Status :: 4 - Beta
        Intended Audience :: Developers
+       Operating System :: OS Independent
        Topic :: Internet :: WWW/HTTP
        Topic :: Software Development :: Testing
+       Topic :: Software Development :: Testing :: Mocking
        License :: OSI Approved :: MIT License
        Natural Language :: English
        Programming Language :: Python :: 3
-       Programming Language :: Python :: 3.5
        Programming Language :: Python :: 3.6
        Programming Language :: Python :: 3.7
+       Programming Language :: Python :: 3.8
 
 [files]
 packages = 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioresponses-0.6.4/tests/test_aioresponses.py 
new/aioresponses-0.7.0/tests/test_aioresponses.py
--- old/aioresponses-0.6.4/tests/test_aioresponses.py   2020-06-02 
11:12:41.000000000 +0200
+++ new/aioresponses-0.7.0/tests/test_aioresponses.py   2020-08-23 
00:00:53.000000000 +0200
@@ -1,6 +1,8 @@
 # -*- coding: utf-8 -*-
 import asyncio
 import re
+from asyncio import CancelledError, TimeoutError
+from random import uniform
 from typing import Coroutine, Generator, Union
 from unittest.mock import patch
 
@@ -8,10 +10,8 @@
 from aiohttp import http
 from aiohttp.client import ClientSession
 from aiohttp.client_reqrep import ClientResponse
-from asynctest import fail_on, skipIf
-from asynctest.case import TestCase
 from ddt import ddt, data
-from asyncio import CancelledError, TimeoutError
+
 try:
     from aiohttp.errors import (
         ClientConnectionError,
@@ -25,33 +25,33 @@
     )
     from aiohttp.http_exceptions import HttpProcessingError
 
-from aioresponses.compat import AIOHTTP_VERSION, URL
+from aioresponses.compat import (
+    AIOHTTP_VERSION, URL,
+    fail_on,
+    skipIf,
+    AsyncTestCase
+)
+
 from aioresponses import CallbackResult, aioresponses
 
 
 @ddt
-class AIOResponsesTestCase(TestCase):
-    use_default_loop = False
+class AIOResponsesTestCase(AsyncTestCase):
 
-    @asyncio.coroutine
-    def setUp(self):
+    async def setup(self):
         self.url = 'http://example.com/api?foo=bar#fragment'
         self.session = ClientSession()
-        super().setUp()
 
-    @asyncio.coroutine
-    def tearDown(self):
+    async def teardown(self):
         close_result = self.session.close()
         if close_result is not None:
-            yield from close_result
-        super().tearDown()
+            await close_result
 
     def run_async(self, coroutine: Union[Coroutine, Generator]):
         return self.loop.run_until_complete(coroutine)
 
-    @asyncio.coroutine
-    def request(self, url: str):
-        return (yield from self.session.get(url))
+    async def request(self, url: str):
+        return await self.session.get(url)
 
     @data(
         hdrs.METH_HEAD,
@@ -76,40 +76,36 @@
         self.assertIsInstance(response, ClientResponse)
 
     @aioresponses()
-    @asyncio.coroutine
-    def test_returned_instance_and_status_code(self, m):
+    async def test_returned_instance_and_status_code(self, m):
         m.get(self.url, status=204)
-        response = yield from self.session.get(self.url)
+        response = await self.session.get(self.url)
         self.assertIsInstance(response, ClientResponse)
         self.assertEqual(response.status, 204)
 
     @aioresponses()
-    @asyncio.coroutine
-    def test_returned_response_headers(self, m):
+    async def test_returned_response_headers(self, m):
         m.get(self.url,
               content_type='text/html',
               headers={'Connection': 'keep-alive'})
-        response = yield from self.session.get(self.url)
+        response = await self.session.get(self.url)
 
         self.assertEqual(response.headers['Connection'], 'keep-alive')
         self.assertEqual(response.headers[hdrs.CONTENT_TYPE], 'text/html')
 
     @aioresponses()
-    @asyncio.coroutine
-    def test_returned_response_cookies(self, m):
+    async def test_returned_response_cookies(self, m):
         m.get(self.url,
               headers={'Set-Cookie': 'cookie=value'})
-        response = yield from self.session.get(self.url)
+        response = await self.session.get(self.url)
 
         self.assertEqual(response.cookies['cookie'].value, 'value')
 
     @aioresponses()
-    @asyncio.coroutine
-    def test_returned_response_raw_headers(self, m):
+    async def test_returned_response_raw_headers(self, m):
         m.get(self.url,
               content_type='text/html',
               headers={'Connection': 'keep-alive'})
-        response = yield from self.session.get(self.url)
+        response = await self.session.get(self.url)
         expected_raw_headers = (
             (hdrs.CONTENT_TYPE.encode(), b'text/html'),
             (b'Connection', b'keep-alive')
@@ -118,37 +114,34 @@
         self.assertEqual(response.raw_headers, expected_raw_headers)
 
     @aioresponses()
-    @asyncio.coroutine
-    def test_raise_for_status(self, m):
+    async def test_raise_for_status(self, m):
         m.get(self.url, status=400)
         with self.assertRaises(ClientResponseError) as cm:
-            response = yield from self.session.get(self.url)
+            response = await self.session.get(self.url)
             response.raise_for_status()
         self.assertEqual(cm.exception.message, http.RESPONSES[400][0])
 
     @aioresponses()
-    @asyncio.coroutine
     @skipIf(condition=AIOHTTP_VERSION < '3.4.0',
             reason='aiohttp<3.4.0 does not support raise_for_status '
                    'arguments for requests')
-    def test_request_raise_for_status(self, m):
+    async def test_request_raise_for_status(self, m):
         m.get(self.url, status=400)
         with self.assertRaises(ClientResponseError) as cm:
-            yield from self.session.get(self.url, raise_for_status=True)
+            await self.session.get(self.url, raise_for_status=True)
         self.assertEqual(cm.exception.message, http.RESPONSES[400][0])
 
     @aioresponses()
-    @asyncio.coroutine
-    def test_returned_instance_and_params_handling(self, m):
+    async def test_returned_instance_and_params_handling(self, m):
         expected_url = 'http://example.com/api?foo=bar&x=42#fragment'
         m.get(expected_url)
-        response = yield from self.session.get(self.url, params={'x': 42})
+        response = await self.session.get(self.url, params={'x': 42})
         self.assertIsInstance(response, ClientResponse)
         self.assertEqual(response.status, 200)
 
         expected_url = 'http://example.com/api?x=42#fragment'
         m.get(expected_url)
-        response = yield from self.session.get(
+        response = await self.session.get(
             'http://example.com/api#fragment',
             params={'x': 42}
         )
@@ -162,30 +155,27 @@
             self.run_async(self.session.post(self.url))
 
     @aioresponses()
-    @asyncio.coroutine
-    def test_streaming(self, m):
+    async def test_streaming(self, m):
         m.get(self.url, body='Test')
-        resp = yield from self.session.get(self.url)
-        content = yield from resp.content.read()
+        resp = await self.session.get(self.url)
+        content = await resp.content.read()
         self.assertEqual(content, b'Test')
 
     @aioresponses()
-    @asyncio.coroutine
-    def test_streaming_up_to(self, m):
+    async def test_streaming_up_to(self, m):
         m.get(self.url, body='Test')
-        resp = yield from self.session.get(self.url)
-        content = yield from resp.content.read(2)
+        resp = await self.session.get(self.url)
+        content = await resp.content.read(2)
         self.assertEqual(content, b'Te')
-        content = yield from resp.content.read(2)
+        content = await resp.content.read(2)
         self.assertEqual(content, b'st')
 
-    @asyncio.coroutine
-    def test_mocking_as_context_manager(self):
+    async def test_mocking_as_context_manager(self):
         with aioresponses() as aiomock:
             aiomock.add(self.url, payload={'foo': 'bar'})
-            resp = yield from self.session.get(self.url)
+            resp = await self.session.get(self.url)
             self.assertEqual(resp.status, 200)
-            payload = yield from resp.json()
+            payload = await resp.json()
             self.assertDictEqual(payload, {'foo': 'bar'})
 
     def test_mocking_as_decorator(self):
@@ -200,16 +190,14 @@
 
         foo(self.loop)
 
-    @asyncio.coroutine
-    def test_passing_argument(self):
+    async def test_passing_argument(self):
         @aioresponses(param='mocked')
-        @asyncio.coroutine
-        def foo(mocked):
+        async def foo(mocked):
             mocked.add(self.url, payload={'foo': 'bar'})
-            resp = yield from self.session.get(self.url)
+            resp = await self.session.get(self.url)
             self.assertEqual(resp.status, 200)
 
-        yield from foo()
+        await foo()
 
     @fail_on(unused_loop=False)
     def test_mocking_as_decorator_wrong_mocked_arg_name(self):
@@ -224,70 +212,67 @@
         self.assertIn("foo() got an unexpected keyword argument 'foo'",
                       str(exc))
 
-    @asyncio.coroutine
-    def test_unknown_request(self):
+    async def test_unknown_request(self):
         with aioresponses() as aiomock:
             aiomock.add(self.url, payload={'foo': 'bar'})
             with self.assertRaises(ClientConnectionError):
-                yield from self.session.get('http://example.com/foo')
+                await self.session.get('http://example.com/foo')
 
-    @asyncio.coroutine
-    def test_raising_exception(self):
+    async def test_raising_exception(self):
         with aioresponses() as aiomock:
             url = 'http://example.com/Exception'
             aiomock.get(url, exception=Exception)
             with self.assertRaises(Exception):
-                yield from self.session.get(url)
+                await self.session.get(url)
 
             url = 'http://example.com/Exception_object'
             aiomock.get(url, exception=Exception())
             with self.assertRaises(Exception):
-                yield from self.session.get(url)
+                await self.session.get(url)
 
             url = 'http://example.com/BaseException'
             aiomock.get(url, exception=BaseException)
             with self.assertRaises(BaseException):
-                yield from self.session.get(url)
+                await self.session.get(url)
 
             url = 'http://example.com/BaseException_object'
             aiomock.get(url, exception=BaseException())
             with self.assertRaises(BaseException):
-                yield from self.session.get(url)
+                await self.session.get(url)
 
             url = 'http://example.com/CancelError'
             aiomock.get(url, exception=CancelledError)
             with self.assertRaises(CancelledError):
-                yield from self.session.get(url)
+                await self.session.get(url)
 
             url = 'http://example.com/TimeoutError'
             aiomock.get(url, exception=TimeoutError)
             with self.assertRaises(TimeoutError):
-                yield from self.session.get(url)
+                await self.session.get(url)
 
             url = 'http://example.com/HttpProcessingError'
             aiomock.get(url, exception=HttpProcessingError(message='foo'))
             with self.assertRaises(HttpProcessingError):
-                yield from self.session.get(url)
+                await self.session.get(url)
 
-    @asyncio.coroutine
-    def test_multiple_requests(self):
+    async def test_multiple_requests(self):
         """Ensure that requests are saved the way they would have been sent."""
         with aioresponses() as m:
             m.get(self.url, status=200)
             m.get(self.url, status=201)
             m.get(self.url, status=202)
             json_content_as_ref = [1]
-            resp = yield from self.session.get(
+            resp = await self.session.get(
                 self.url, json=json_content_as_ref
             )
             self.assertEqual(resp.status, 200)
             json_content_as_ref[:] = [2]
-            resp = yield from self.session.get(
+            resp = await self.session.get(
                 self.url, json=json_content_as_ref
             )
             self.assertEqual(resp.status, 201)
             json_content_as_ref[:] = [3]
-            resp = yield from self.session.get(
+            resp = await self.session.get(
                 self.url, json=json_content_as_ref
             )
             self.assertEqual(resp.status, 202)
@@ -311,8 +296,7 @@
             self.assertEqual(third_request.kwargs,
                              {'allow_redirects': True, "json": [3]})
 
-    @asyncio.coroutine
-    def test_request_with_non_deepcopyable_parameter(self):
+    async def test_request_with_non_deepcopyable_parameter(self):
         def non_deep_copyable():
             """A generator does not allow deepcopy."""
             for line in ["header1,header2", "v1,v2", "v10,v20"]:
@@ -322,7 +306,7 @@
 
         with aioresponses() as m:
             m.get(self.url, status=200)
-            resp = yield from self.session.get(self.url, data=generator_value)
+            resp = await self.session.get(self.url, data=generator_value)
             self.assertEqual(resp.status, 200)
 
             key = ('GET', URL(self.url))
@@ -332,13 +316,13 @@
             request = m.requests[key][0]
             self.assertEqual(request.args, tuple())
             self.assertEqual(request.kwargs,
-                             {'allow_redirects': True, "data": 
generator_value})
+                             {'allow_redirects': True,
+                                 "data": generator_value})
 
-    @asyncio.coroutine
-    def test_request_retrieval_in_case_no_response(self):
+    async def test_request_retrieval_in_case_no_response(self):
         with aioresponses() as m:
             with self.assertRaises(ClientConnectionError):
-                yield from self.session.get(self.url)
+                await self.session.get(self.url)
 
             key = ('GET', URL(self.url))
             self.assertIn(key, m.requests)
@@ -347,64 +331,59 @@
             self.assertEqual(m.requests[key][0].kwargs,
                              {'allow_redirects': True})
 
-    @asyncio.coroutine
-    def test_request_failure_in_case_session_is_closed(self):
-        @asyncio.coroutine
-        def do_request(session):
-            return (yield from session.get(self.url))
+    async def test_request_failure_in_case_session_is_closed(self):
+        async def do_request(session):
+            return (await session.get(self.url))
 
         with aioresponses():
             coro = do_request(self.session)
-            yield from self.session.close()
+            await self.session.close()
 
             with self.assertRaises(RuntimeError) as exception_info:
-                yield from coro
+                await coro
             assert str(exception_info.exception) == "Session is closed"
 
-    @asyncio.coroutine
-    def test_address_as_instance_of_url_combined_with_pass_through(self):
+    async def test_address_as_instance_of_url_combined_with_pass_through(self):
         external_api = 'http://httpbin.org/status/201'
 
-        @asyncio.coroutine
-        def doit():
-            api_resp = yield from self.session.get(self.url)
+        async def doit():
+            api_resp = await self.session.get(self.url)
             # we have to hit actual url,
             # otherwise we do not test pass through option properly
-            ext_rep = yield from self.session.get(URL(external_api))
+            ext_rep = await self.session.get(URL(external_api))
             return api_resp, ext_rep
 
         with aioresponses(passthrough=[external_api]) as m:
             m.get(self.url, status=200)
-            api, ext = yield from doit()
+            api, ext = await doit()
 
             self.assertEqual(api.status, 200)
             self.assertEqual(ext.status, 201)
 
-    @asyncio.coroutine
-    def test_pass_through_with_origin_params(self):
+    async def test_pass_through_with_origin_params(self):
         external_api = 'http://httpbin.org/get'
 
-        @asyncio.coroutine
-        def doit(params):
+        async def doit(params):
             # we have to hit actual url,
             # otherwise we do not test pass through option properly
-            ext_rep = (yield from self.session.get(URL(external_api), 
params=params))
+            ext_rep = await self.session.get(
+                URL(external_api), params=params
+            )
             return ext_rep
 
         with aioresponses(passthrough=[external_api]) as m:
             params = {'foo': 'bar'}
-            ext = yield from doit(params=params)
+            ext = await doit(params=params)
             self.assertEqual(ext.status, 200)
             self.assertEqual(str(ext.url), 'http://httpbin.org/get?foo=bar')
 
     @aioresponses()
-    @asyncio.coroutine
-    def test_custom_response_class(self, m):
+    async def test_custom_response_class(self, m):
         class CustomClientResponse(ClientResponse):
             pass
 
         m.get(self.url, body='Test', response_class=CustomClientResponse)
-        resp = yield from self.session.get(self.url)
+        resp = await self.session.get(self.url)
         self.assertTrue(isinstance(resp, CustomClientResponse))
 
     @aioresponses()
@@ -415,9 +394,8 @@
         mocked.get(self.url, exception=ValueError('oops'), )
         mocked.get(self.url, payload={}, status=200)
 
-        @asyncio.coroutine
-        def doit():
-            return (yield from self.session.get(self.url))
+        async def doit():
+            return (await self.session.get(self.url))
 
         self.assertEqual(self.run_async(doit()).status, 204)
         with self.assertRaises(ValueError):
@@ -428,25 +406,23 @@
         self.assertEqual(self.run_async(doit()).status, 200)
 
     @aioresponses()
-    @asyncio.coroutine
-    def test_request_should_match_regexp(self, mocked):
+    async def test_request_should_match_regexp(self, mocked):
         mocked.get(
             re.compile(r'^http://example\.com/api\?foo=.*$'),
             payload={}, status=200
         )
 
-        response = yield from self.request(self.url)
+        response = await self.request(self.url)
         self.assertEqual(response.status, 200)
 
     @aioresponses()
-    @asyncio.coroutine
-    def test_request_does_not_match_regexp(self, mocked):
+    async def test_request_does_not_match_regexp(self, mocked):
         mocked.get(
             re.compile(r'^http://exampleexample\.com/api\?foo=.*$'),
             payload={}, status=200
         )
         with self.assertRaises(ClientConnectionError):
-            yield from self.request(self.url)
+            await self.request(self.url)
 
     @aioresponses()
     def test_timeout(self, mocked):
@@ -474,9 +450,8 @@
         body = b'New body'
         event = asyncio.Event()
 
-        @asyncio.coroutine
-        def callback(url, **kwargs):
-            yield from event.wait()
+        async def callback(url, **kwargs):
+            await event.wait()
             self.assertEqual(str(url), self.url)
             self.assertEqual(kwargs, {'allow_redirects': True})
             return CallbackResult(body=body)
@@ -493,13 +468,12 @@
         assert data == body
 
     @aioresponses()
-    @asyncio.coroutine
-    def test_exception_requests_are_tracked(self, mocked):
+    async def test_exception_requests_are_tracked(self, mocked):
         kwargs = {"json": [42], "allow_redirects": True}
         mocked.get(self.url, exception=ValueError('oops'))
 
         with self.assertRaises(ValueError):
-            yield from self.session.get(self.url, **kwargs)
+            await self.session.get(self.url, **kwargs)
 
         key = ('GET', URL(self.url))
         mocked_requests = mocked.requests[key]
@@ -509,8 +483,26 @@
         self.assertEqual(request.args, ())
         self.assertEqual(request.kwargs, kwargs)
 
+    async def test_possible_race_condition(self):
+        async def random_sleep_cb(url, **kwargs):
+            await asyncio.sleep(uniform(0.1, 1))
+            return CallbackResult(body='test')
+
+        with aioresponses() as mocked:
+            for i in range(20):
+                mocked.get(
+                    'http://example.org/id-{}'.format(i),
+                    callback=random_sleep_cb
+                )
+
+            tasks = [
+                self.session.get('http://example.org/id-{}'.format(i)) for
+                i in range(20)
+            ]
+            await asyncio.gather(*tasks)
 
-class AIOResponsesRaiseForStatusSessionTestCase(TestCase):
+
+class AIOResponsesRaiseForStatusSessionTestCase(AsyncTestCase):
     """Test case for sessions with raise_for_status=True.
 
     This flag, introduced in aiohttp v2.0.0, automatically calls
@@ -519,66 +511,55 @@
     aiohttp v3.4.a0.
 
     """
-    use_default_loop = False
 
-    @asyncio.coroutine
-    def setUp(self):
+    async def setup(self):
         self.url = 'http://example.com/api?foo=bar#fragment'
         self.session = ClientSession(raise_for_status=True)
-        super().setUp()
 
-    @asyncio.coroutine
-    def tearDown(self):
+    async def teardown(self):
         close_result = self.session.close()
         if close_result is not None:
-            yield from close_result
-        super().tearDown()
+            await close_result
 
     @aioresponses()
-    @asyncio.coroutine
-    def test_raise_for_status(self, m):
+    async def test_raise_for_status(self, m):
         m.get(self.url, status=400)
         with self.assertRaises(ClientResponseError) as cm:
-            yield from self.session.get(self.url)
+            await self.session.get(self.url)
         self.assertEqual(cm.exception.message, http.RESPONSES[400][0])
 
     @aioresponses()
-    @asyncio.coroutine
     @skipIf(condition=AIOHTTP_VERSION < '3.4.0',
             reason='aiohttp<3.4.0 does not support raise_for_status '
                    'arguments for requests')
-    def test_do_not_raise_for_status(self, m):
+    async def test_do_not_raise_for_status(self, m):
         m.get(self.url, status=400)
-        response = yield from self.session.get(self.url,
-                                               raise_for_status=False)
+        response = await self.session.get(self.url,
+                                          raise_for_status=False)
 
         self.assertEqual(response.status, 400)
 
 
-class AIOResponseRedirectTest(TestCase):
-    @asyncio.coroutine
-    def setUp(self):
+class AIOResponseRedirectTest(AsyncTestCase):
+
+    async def setup(self):
         self.url = "http://10.1.1.1:8080/redirect";
         self.session = ClientSession()
-        super().setUp()
 
-    @asyncio.coroutine
-    def tearDown(self):
+    async def teardown(self):
         close_result = self.session.close()
         if close_result is not None:
-            yield from close_result
-        super().tearDown()
+            await close_result
 
     @aioresponses()
-    @asyncio.coroutine
-    def test_redirect_followed(self, rsps):
+    async def test_redirect_followed(self, rsps):
         rsps.get(
             self.url,
             status=307,
             headers={"Location": "https://httpbin.org"},
         )
         rsps.get("https://httpbin.org";)
-        response = yield from self.session.get(
+        response = await self.session.get(
             self.url, allow_redirects=True
         )
         self.assertEqual(response.status, 200)
@@ -587,15 +568,14 @@
         self.assertEqual(str(response.history[0].url), self.url)
 
     @aioresponses()
-    @asyncio.coroutine
-    def test_post_redirect_followed(self, rsps):
+    async def test_post_redirect_followed(self, rsps):
         rsps.post(
             self.url,
             status=307,
             headers={"Location": "https://httpbin.org"},
         )
         rsps.get("https://httpbin.org";)
-        response = yield from self.session.post(
+        response = await self.session.post(
             self.url, allow_redirects=True
         )
         self.assertEqual(response.status, 200)
@@ -605,15 +585,14 @@
         self.assertEqual(str(response.history[0].url), self.url)
 
     @aioresponses()
-    @asyncio.coroutine
-    def test_redirect_missing_mocked_match(self, rsps):
+    async def test_redirect_missing_mocked_match(self, rsps):
         rsps.get(
             self.url,
             status=307,
             headers={"Location": "https://httpbin.org"},
         )
         with self.assertRaises(ClientConnectionError) as cm:
-            yield from self.session.get(
+            await self.session.get(
                 self.url, allow_redirects=True
             )
         self.assertEqual(
@@ -622,34 +601,31 @@
         )
 
     @aioresponses()
-    @asyncio.coroutine
-    def test_redirect_missing_location_header(self, rsps):
+    async def test_redirect_missing_location_header(self, rsps):
         rsps.get(self.url, status=307)
-        response = yield from self.session.get(self.url, allow_redirects=True)
+        response = await self.session.get(self.url, allow_redirects=True)
         self.assertEqual(str(response.url), self.url)
 
     @aioresponses()
-    @asyncio.coroutine
     @skipIf(condition=AIOHTTP_VERSION < '3.1.0',
             reason='aiohttp<3.1.0 does not add request info on response')
-    def test_request_info(self, rsps):
+    async def test_request_info(self, rsps):
         rsps.get(self.url, status=200)
 
-        response = yield from self.session.get(self.url)
+        response = await self.session.get(self.url)
 
         request_info = response.request_info
         assert str(request_info.url) == self.url
         assert request_info.headers == {}
 
     @aioresponses()
-    @asyncio.coroutine
     @skipIf(condition=AIOHTTP_VERSION < '3.1.0',
             reason='aiohttp<3.1.0 does not add request info on response')
-    def test_request_info_with_original_request_headers(self, rsps):
+    async def test_request_info_with_original_request_headers(self, rsps):
         headers = {"Authorization": "Bearer access-token"}
         rsps.get(self.url, status=200)
 
-        response = yield from self.session.get(self.url, headers=headers)
+        response = await self.session.get(self.url, headers=headers)
 
         request_info = response.request_info
         assert str(request_info.url) == self.url
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioresponses-0.6.4/tox.ini 
new/aioresponses-0.7.0/tox.ini
--- old/aioresponses-0.6.4/tox.ini      2020-02-11 22:27:00.000000000 +0100
+++ new/aioresponses-0.7.0/tox.ini      2020-08-22 21:41:32.000000000 +0200
@@ -2,12 +2,8 @@
 envlist =
     flake8,
     coverage,
-    py35-aiohttp{20,21,22,23,30,31,32,33,34,35,36}
-    py36-aiohttp-master
-    py36-aiohttp{20,21,22,23,30,31,32,33,34,35,36}
-    py37-aiohttp-master
+    py36-aiohttp{30,31,32,33,34,35,36}
     py37-aiohttp{30,31,32,33,34,35,36}
-    py38-aiohttp-master
     py38-aiohttp{30,31,32,33,34,35,36}
 skipsdist = True
 

++++++ pr_174.patch ++++++
>From ab7e43b0575f0ed6d194b1e10e7c5ca4e672607a Mon Sep 17 00:00:00 2001
From: David Buxton <[email protected]>
Date: Sat, 24 Oct 2020 13:28:56 +0100
Subject: [PATCH] Fix compatibility with aiohttp==3.7.0

The new version of aiohttp has made `limit` a required argument for the
StreamReader class. This change adds an explicit limit of 2 ** 16 which
is the same as what aiohttp uses internally.

Using `limit` as a keyword (rather than a positional argument) keeps
compatibility with previous versions of aiohttp.

Fixes #173
---
 aioresponses/compat.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/aioresponses/compat.py b/aioresponses/compat.py
index 321a33a..d2624ad 100644
--- a/aioresponses/compat.py
+++ b/aioresponses/compat.py
@@ -45,7 +45,7 @@ def stream_reader_factory(  # noqa
         loop: 'Optional[asyncio.AbstractEventLoop]' = None
     ):
         protocol = ResponseHandler(loop=loop)
-        return StreamReader(protocol, loop=loop)
+        return StreamReader(protocol, limit=2 ** 16, loop=loop)
 
 else:
 

Reply via email to