commit python-aioresponses for openSUSE:Factory
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 <jayvdb@gmail.com> + +- 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 <allisson@gmail.com> Andrew Grinevich <andrew.grinevich@pandadoc.com> Anthony Lukach <anthonylukach@gmail.com> +Ben Greiner <code@bnavigator.de> Brett Wandel <brett.wandel@interferex.com> Bryce Drennan <github@accounts.brycedrennan.com> Colin-b <Colin-b@users.noreply.github.com> 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 <david@gasmark6.com> 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:
participants (1)
-
root