Hello community, here is the log from the commit of package python-aioresponses for openSUSE:Factory checked in at 2019-03-01 16:47:48 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-aioresponses (Old) and /work/SRC/openSUSE:Factory/.python-aioresponses.new.28833 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "python-aioresponses" Fri Mar 1 16:47:48 2019 rev:2 rq:680045 version:0.6.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-aioresponses/python-aioresponses.changes 2018-11-29 22:58:27.811649638 +0100 +++ /work/SRC/openSUSE:Factory/.python-aioresponses.new.28833/python-aioresponses.changes 2019-03-01 16:47:50.713789531 +0100 @@ -1,0 +2,11 @@ +Thu Feb 28 07:25:43 UTC 2019 - John Vandenberg <jayvdb@gmail.com> + +- Remove unnecessary build dependencies +- Update to v0.6.0 + * Move internal stuff and CallbackResult class to the core module + * Add CallbackResult class for returning responses from callbacks + * Expose build_response method + * Add Python 3.7 for tox + * Add callbacks to provide dynamic responses + +------------------------------------------------------------------- Old: ---- aioresponses-0.5.0.tar.gz New: ---- aioresponses-0.6.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-aioresponses.spec ++++++ --- /var/tmp/diff_new_pack.omhrDH/_old 2019-03-01 16:47:51.513789227 +0100 +++ /var/tmp/diff_new_pack.omhrDH/_new 2019-03-01 16:47:51.513789227 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-aioresponses # -# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -19,7 +19,7 @@ %{?!python_module:%define python_module() python3-%{**}} %define skip_python2 1 Name: python-aioresponses -Version: 0.5.0 +Version: 0.6.0 Release: 0 Summary: Python module for mocking out requests made by ClientSession from aiohttp License: MIT @@ -29,16 +29,11 @@ Patch0: disable-online-test.patch BuildRequires: %{python_module Sphinx >= 1.5.6} BuildRequires: %{python_module asynctest >= 0.12.2} -BuildRequires: %{python_module coverage >= 4.5.1} BuildRequires: %{python_module ddt >= 1.2.0} BuildRequires: %{python_module devel >= 3.5.3} -BuildRequires: %{python_module flake8 >= 3.5.0} BuildRequires: %{python_module pbr} BuildRequires: %{python_module pytest >= 3.8.1} -BuildRequires: %{python_module pytest-cov >= 2.6.0} -BuildRequires: %{python_module pytest-html >= 1.19.0} BuildRequires: %{python_module setuptools} -BuildRequires: %{python_module tox >= 3.4.0} BuildRequires: %{python_module typing} BuildRequires: %{python_module watchdog >= 0.9.0} BuildRequires: fdupes ++++++ aioresponses-0.5.0.tar.gz -> aioresponses-0.6.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aioresponses-0.5.0/.travis.yml new/aioresponses-0.6.0/.travis.yml --- old/aioresponses-0.5.0/.travis.yml 2018-09-27 21:41:11.000000000 +0200 +++ new/aioresponses-0.6.0/.travis.yml 2019-01-08 12:24:15.000000000 +0100 @@ -23,6 +23,8 @@ env: TOXENV=py35-aiohttp33 - python: 3.5 env: TOXENV=py35-aiohttp34 + - python: 3.5 + env: TOXENV=py35-aiohttp35 - python: 3.6 env: TOXENV=py36-aiohttp20 @@ -42,6 +44,8 @@ env: TOXENV=py36-aiohttp33 - python: 3.6 env: TOXENV=py36-aiohttp34 + - python: 3.6 + env: TOXENV=py36-aiohttp35 # - python: 3.6 # env: TOXENV=py36-aiohttpmaster # diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aioresponses-0.5.0/AUTHORS new/aioresponses-0.6.0/AUTHORS --- old/aioresponses-0.5.0/AUTHORS 2018-10-29 21:37:20.000000000 +0100 +++ new/aioresponses-0.6.0/AUTHORS 2019-01-21 22:04:41.000000000 +0100 @@ -1,12 +1,14 @@ Alexey Sveshnikov <a.sveshnikov@rambler-co.ru> Alexey Sveshnikov <alexey.sveshnikov@gmail.com> Allisson Azevedo <allisson@gmail.com> +Andrew Grinevich <andrew.grinevich@pandadoc.com> Anthony Lukach <anthonylukach@gmail.com> Brett Wandel <brett.wandel@interferex.com> Bryce Drennan <github@accounts.brycedrennan.com> Joongi Kim <me@daybreaker.info> Jordi Soucheiron <jordi@soucheiron.cat> Jordi Soucheiron <jsoucheiron@users.noreply.github.com> +Joshua Coats <joshu@fearchar.net> Lee Treveil <leetreveil@gmail.com> Lukasz Jernas <lukasz.jernas@allegrogroup.com> Marat Sharafutdinov <decaz89@gmail.com> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aioresponses-0.5.0/ChangeLog new/aioresponses-0.6.0/ChangeLog --- old/aioresponses-0.5.0/ChangeLog 2018-10-29 21:37:20.000000000 +0100 +++ new/aioresponses-0.6.0/ChangeLog 2019-01-21 22:04:41.000000000 +0100 @@ -1,6 +1,27 @@ CHANGES ======= +0.6.0 +----- + +* Move internal stuff and `CallbackResult` class to the core module +* Add `CallbackResult` class for returning responses from callbacks +* Expose `build_response` method +* Add Python 3.7 for tox +* Add callbacks to provide dynamic responses + +0.5.2 +----- + +* catch exceptions more narrowly on http.RESPONSES +* flake8 line length fix +* Provide default Reason Phrase from aiohttp.http.RESPONSES + +0.5.1 +----- + +* aiohttp==3.5 compatibility added + 0.5.0 ----- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aioresponses-0.5.0/Makefile new/aioresponses-0.6.0/Makefile --- old/aioresponses-0.5.0/Makefile 2018-10-29 21:32:41.000000000 +0100 +++ new/aioresponses-0.6.0/Makefile 2019-01-20 00:09:08.000000000 +0100 @@ -26,7 +26,7 @@ help: @python -c "$$PRINT_HELP_PYSCRIPT" < $(MAKEFILE_LIST) -clean: clean-build clean-pyc ## remove all build, test, coverage and Python artifacts +clean: clean-build clean-pyc clean-test ## remove all build, test, coverage and Python artifacts clean-build: ## remove build artifacts diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aioresponses-0.5.0/PKG-INFO new/aioresponses-0.6.0/PKG-INFO --- old/aioresponses-0.5.0/PKG-INFO 2018-10-29 21:37:28.000000000 +0100 +++ new/aioresponses-0.6.0/PKG-INFO 2019-01-21 22:04:43.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: aioresponses -Version: 0.5.0 +Version: 0.6.0 Summary: Mock out requests made by ClientSession from aiohttp package Home-page: https://github.com/pnuckowski/aioresponses Author: Paweł Nuckowski @@ -198,6 +198,28 @@ # will throw an exception. + **aioresponses allows to use callbacks to provide dynamic responses** + + .. code:: python + + import asyncio + import aiohttp + from aioresponses import CallbackResult, aioresponses + + def callback(url, **kwargs): + return CallbackResult(status=418) + + @aioresponses() + def test_callback(m, test_client): + loop = asyncio.get_event_loop() + session = ClientSession() + m.get('http://example.com', callback=callback) + + resp = loop.run_until_complete(session.get('http://example.com')) + + assert resp.status == 418 + + **aioresponses can be used in a pytest fixture** .. code:: python @@ -211,8 +233,6 @@ yield m - - Features -------- * Easy to mock out HTTP requests made by *aiohttp.ClientSession* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aioresponses-0.5.0/README.rst new/aioresponses-0.6.0/README.rst --- old/aioresponses-0.5.0/README.rst 2018-09-27 22:21:33.000000000 +0200 +++ new/aioresponses-0.6.0/README.rst 2019-01-21 22:02:56.000000000 +0100 @@ -190,6 +190,28 @@ # will throw an exception. +**aioresponses allows to use callbacks to provide dynamic responses** + +.. code:: python + + import asyncio + import aiohttp + from aioresponses import CallbackResult, aioresponses + + def callback(url, **kwargs): + return CallbackResult(status=418) + + @aioresponses() + def test_callback(m, test_client): + loop = asyncio.get_event_loop() + session = ClientSession() + m.get('http://example.com', callback=callback) + + resp = loop.run_until_complete(session.get('http://example.com')) + + assert resp.status == 418 + + **aioresponses can be used in a pytest fixture** .. code:: python @@ -203,8 +225,6 @@ yield m - - Features -------- * Easy to mock out HTTP requests made by *aiohttp.ClientSession* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aioresponses-0.5.0/aioresponses/__init__.py new/aioresponses-0.6.0/aioresponses/__init__.py --- old/aioresponses-0.5.0/aioresponses/__init__.py 2018-03-27 21:32:22.000000000 +0200 +++ new/aioresponses-0.6.0/aioresponses/__init__.py 2019-01-21 22:02:56.000000000 +0100 @@ -1,8 +1,9 @@ # -*- coding: utf-8 -*- -from .core import aioresponses +from .core import CallbackResult, aioresponses __version__ = '0.4.1' __all__ = [ + 'CallbackResult', 'aioresponses', ] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aioresponses-0.5.0/aioresponses/compat.py new/aioresponses-0.6.0/aioresponses/compat.py --- old/aioresponses-0.5.0/aioresponses/compat.py 2018-09-27 18:47:02.000000000 +0200 +++ new/aioresponses-0.6.0/aioresponses/compat.py 2019-01-21 22:02:56.000000000 +0100 @@ -1,8 +1,9 @@ # -*- coding: utf-8 -*- +import asyncio # noqa import re from distutils.version import StrictVersion -from typing import Union, Dict # noqa -from urllib.parse import urlencode, parse_qsl +from typing import Dict, Optional, Tuple, Union # noqa +from urllib.parse import parse_qsl, urlencode from aiohttp import __version__ as aiohttp_version, StreamReader from multidict import MultiDict @@ -19,11 +20,12 @@ if AIOHTTP_VERSION >= StrictVersion('3.0.0'): from aiohttp.client_proto import ResponseHandler - def stream_reader_factory(): - protocol = ResponseHandler() + def stream_reader_factory( + loop: 'Optional[asyncio.AbstractEventLoop]' = None + ): + protocol = ResponseHandler(loop=loop) return StreamReader(protocol) - else: # pragma: no cover def stream_reader_factory(): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aioresponses-0.5.0/aioresponses/core.py new/aioresponses-0.6.0/aioresponses/core.py --- old/aioresponses-0.5.0/aioresponses/core.py 2018-10-29 21:27:42.000000000 +0100 +++ new/aioresponses-0.6.0/aioresponses/core.py 2019-01-21 22:02:56.000000000 +0100 @@ -4,23 +4,49 @@ from collections import namedtuple from distutils.version import StrictVersion from functools import wraps -from typing import Dict, Tuple, Union, Optional, List # noqa +from typing import Callable, Dict, Tuple, Union, Optional, List # noqa from unittest.mock import Mock, patch -from aiohttp import ClientConnectionError, ClientResponse, ClientSession, hdrs +from aiohttp import ( + ClientConnectionError, + ClientResponse, + ClientSession, + hdrs, + http +) from aiohttp.helpers import TimerNoop from multidict import CIMultiDict from .compat import ( + AIOHTTP_VERSION, URL, Pattern, stream_reader_factory, merge_params, normalize_url, - AIOHTTP_VERSION ) +class CallbackResult: + + def __init__(self, method: str = hdrs.METH_GET, + status: int = 200, + body: str = '', + content_type: str = 'application/json', + payload: Dict = None, + headers: Dict = None, + response_class: 'ClientResponse' = None, + reason: Optional[str] = None): + self.method = method + self.status = status + self.body = body + self.content_type = content_type + self.payload = payload + self.headers = headers + self.response_class = response_class + self.reason = reason + + class RequestMatch(object): url_or_pattern = None # type: Union[URL, Pattern] @@ -34,7 +60,9 @@ content_type: str = 'application/json', response_class: 'ClientResponse' = None, timeout: bool = False, - repeat: bool = False): + repeat: bool = False, + reason: Optional[str] = None, + callback: Optional[Callable] = None): if isinstance(url, Pattern): self.url_or_pattern = url self.match_func = self.match_regexp @@ -43,18 +71,22 @@ self.match_func = self.match_str self.method = method.lower() self.status = status - if payload is not None: - body = json.dumps(payload) - if not isinstance(body, bytes): - body = str.encode(body) self.body = body + self.payload = payload self.exception = exception if timeout: self.exception = asyncio.TimeoutError('Connection timeout test') self.headers = headers self.content_type = content_type - self.response_class = response_class or ClientResponse + self.response_class = response_class self.repeat = repeat + self.reason = reason + if self.reason is None: + try: + self.reason = http.RESPONSES[self.status][0] + except (IndexError, KeyError): + self.reason = '' + self.callback = callback def match_str(self, url: URL) -> bool: return self.url_or_pattern == url @@ -67,11 +99,32 @@ return False return self.match_func(url) - async def build_response( - self, url: URL - ) -> 'Union[ClientResponse, Exception]': - if isinstance(self.exception, Exception): - return self.exception + def _build_raw_headers(self, headers: Dict) -> Tuple: + """ + Convert a dict of headers to a tuple of tuples + + Mimics the format of ClientResponse. + """ + raw_headers = [] + for k, v in headers.items(): + raw_headers.append((k.encode('utf8'), v.encode('utf8'))) + return tuple(raw_headers) + + def _build_response(self, url: 'Union[URL, str]', + method: str = hdrs.METH_GET, + status: int = 200, + body: str = '', + content_type: str = 'application/json', + payload: Dict = None, + headers: Dict = None, + response_class: 'ClientResponse' = None, + reason: Optional[str] = None) -> ClientResponse: + if response_class is None: + response_class = ClientResponse + if payload is not None: + body = json.dumps(payload) + if not isinstance(body, bytes): + body = str.encode(body) kwargs = {} if AIOHTTP_VERSION >= StrictVersion('3.1.0'): loop = Mock() @@ -81,42 +134,52 @@ kwargs['writer'] = Mock() kwargs['continue100'] = None kwargs['timer'] = TimerNoop() - if AIOHTTP_VERSION >= StrictVersion('3.3.0'): - pass - else: + if AIOHTTP_VERSION < StrictVersion('3.3.0'): kwargs['auto_decompress'] = True kwargs['traces'] = [] kwargs['loop'] = loop kwargs['session'] = None - resp = self.response_class(self.method, url, **kwargs) - # we need to initialize headers manually - headers = CIMultiDict({hdrs.CONTENT_TYPE: self.content_type}) - if self.headers: - headers.update(self.headers) - raw_headers = self._build_raw_headers(headers) + # We need to initialize headers manually + _headers = CIMultiDict({hdrs.CONTENT_TYPE: content_type}) + if headers: + _headers.update(headers) + raw_headers = self._build_raw_headers(_headers) + resp = response_class(method, url, **kwargs) if AIOHTTP_VERSION >= StrictVersion('3.3.0'): # Reified attributes - resp._headers = headers + resp._headers = _headers resp._raw_headers = raw_headers else: - resp.headers = headers + resp.headers = _headers resp.raw_headers = raw_headers - resp.status = self.status + resp.status = status + resp.reason = reason resp.content = stream_reader_factory() - resp.content.feed_data(self.body) + resp.content.feed_data(body) resp.content.feed_eof() return resp - def _build_raw_headers(self, headers: Dict) -> Tuple: - """ - Convert a dict of headers to a tuple of tuples - - Mimics the format of ClientResponse. - """ - raw_headers = [] - for k, v in headers.items(): - raw_headers.append((k.encode('utf8'), v.encode('utf8'))) - return tuple(raw_headers) + async def build_response( + self, url: URL, **kwargs: Dict + ) -> 'Union[ClientResponse, Exception]': + if isinstance(self.exception, Exception): + return self.exception + if callable(self.callback): + result = self.callback(url, **kwargs) + else: + result = None + result = self if result is None else result + resp = self._build_response( + url=url, + method=result.method, + status=result.status, + body=result.body, + content_type=result.content_type, + payload=result.payload, + headers=result.headers, + response_class=result.response_class, + reason=result.reason) + return resp RequestCall = namedtuple('RequestCall', ['args', 'kwargs']) @@ -211,7 +274,9 @@ headers: Dict = None, response_class: 'ClientResponse' = None, repeat: bool = False, - timeout: bool = False) -> None: + timeout: bool = False, + reason: Optional[str] = None, + callback: Optional[Callable] = None) -> None: self._matches.append(RequestMatch( url, method=method, @@ -224,12 +289,16 @@ response_class=response_class, repeat=repeat, timeout=timeout, + reason=reason, + callback=callback, )) - async def match(self, method: str, url: URL) -> Optional['ClientResponse']: + async def match( + self, method: str, url: URL, **kwargs: Dict + ) -> Optional['ClientResponse']: for i, matcher in enumerate(self._matches): if matcher.match(method, url): - response = await matcher.build_response(url) + response = await matcher.build_response(url, **kwargs) break else: return None @@ -253,7 +322,7 @@ orig_self, method, url, *args, **kwargs )) - response = await self.match(method, url) + response = await self.match(method, url, **kwargs) if response is None: raise ClientConnectionError( 'Connection refused: {} {}'.format(method, url) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aioresponses-0.5.0/aioresponses.egg-info/PKG-INFO new/aioresponses-0.6.0/aioresponses.egg-info/PKG-INFO --- old/aioresponses-0.5.0/aioresponses.egg-info/PKG-INFO 2018-10-29 21:37:20.000000000 +0100 +++ new/aioresponses-0.6.0/aioresponses.egg-info/PKG-INFO 2019-01-21 22:04:41.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: aioresponses -Version: 0.5.0 +Version: 0.6.0 Summary: Mock out requests made by ClientSession from aiohttp package Home-page: https://github.com/pnuckowski/aioresponses Author: Paweł Nuckowski @@ -198,6 +198,28 @@ # will throw an exception. + **aioresponses allows to use callbacks to provide dynamic responses** + + .. code:: python + + import asyncio + import aiohttp + from aioresponses import CallbackResult, aioresponses + + def callback(url, **kwargs): + return CallbackResult(status=418) + + @aioresponses() + def test_callback(m, test_client): + loop = asyncio.get_event_loop() + session = ClientSession() + m.get('http://example.com', callback=callback) + + resp = loop.run_until_complete(session.get('http://example.com')) + + assert resp.status == 418 + + **aioresponses can be used in a pytest fixture** .. code:: python @@ -211,8 +233,6 @@ yield m - - Features -------- * Easy to mock out HTTP requests made by *aiohttp.ClientSession* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aioresponses-0.5.0/aioresponses.egg-info/pbr.json new/aioresponses-0.6.0/aioresponses.egg-info/pbr.json --- old/aioresponses-0.5.0/aioresponses.egg-info/pbr.json 2018-10-29 21:37:20.000000000 +0100 +++ new/aioresponses-0.6.0/aioresponses.egg-info/pbr.json 2019-01-21 22:04:41.000000000 +0100 @@ -1 +1 @@ -{"git_version": "589cf62", "is_release": false} \ No newline at end of file +{"git_version": "566461a", "is_release": false} \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aioresponses-0.5.0/tests/test_aioresponses.py new/aioresponses-0.6.0/tests/test_aioresponses.py --- old/aioresponses-0.5.0/tests/test_aioresponses.py 2018-09-27 18:47:03.000000000 +0200 +++ new/aioresponses-0.6.0/tests/test_aioresponses.py 2019-01-21 22:02:56.000000000 +0100 @@ -5,6 +5,7 @@ from unittest.mock import patch from aiohttp import hdrs +from aiohttp import http from aiohttp.client import ClientSession from aiohttp.client_reqrep import ClientResponse from asynctest import fail_on @@ -12,13 +13,20 @@ from ddt import ddt, data try: - from aiohttp.errors import ClientConnectionError, HttpProcessingError + from aiohttp.errors import ( + ClientConnectionError, + ClientResponseError, + HttpProcessingError, + ) except ImportError: - from aiohttp.client_exceptions import ClientConnectionError + from aiohttp.client_exceptions import ( + ClientConnectionError, + ClientResponseError, + ) from aiohttp.http_exceptions import HttpProcessingError from aioresponses.compat import URL -from aioresponses import aioresponses +from aioresponses import CallbackResult, aioresponses @ddt @@ -102,6 +110,15 @@ @aioresponses() @asyncio.coroutine + 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.raise_for_status() + self.assertEqual(cm.exception.message, http.RESPONSES[400][0]) + + @aioresponses() + @asyncio.coroutine def test_returned_instance_and_params_handling(self, m): expected_url = 'http://example.com/api?foo=bar&x=42#fragment' m.get(expected_url) @@ -297,3 +314,17 @@ with self.assertRaises(asyncio.TimeoutError): self.run_async(self.request(self.url)) + + @aioresponses() + def test_callback(self, m): + body = b'New body' + + def callback(url, **kwargs): + self.assertEqual(str(url), self.url) + self.assertEqual(kwargs, {'allow_redirects': True}) + return CallbackResult(body=body) + + m.get(self.url, callback=callback) + response = self.run_async(self.request(self.url)) + data = self.run_async(response.read()) + assert data == body diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aioresponses-0.5.0/tox.ini new/aioresponses-0.6.0/tox.ini --- old/aioresponses-0.5.0/tox.ini 2018-09-27 21:41:11.000000000 +0200 +++ new/aioresponses-0.6.0/tox.ini 2019-01-21 22:02:56.000000000 +0100 @@ -3,9 +3,11 @@ flake8, coverage, py35-aiohttp-master - py35-aiohttp{20,21,22,23,30,31,32,33,34} + py35-aiohttp{20,21,22,23,30,31,32,33,34,35} py36-aiohttp-master - py36-aiohttp{20,21,22,23,30,31,32,33,34} + py36-aiohttp{20,21,22,23,30,31,32,33,34,35} + py37-aiohttp-master + py37-aiohttp{20,21,22,23,30,31,32,33,34,35} skipsdist = True [testenv:flake8] @@ -31,12 +33,14 @@ aiohttp32: aiohttp>=3.2,<3.3 aiohttp33: aiohttp>=3.3,<3.4 aiohttp34: aiohttp>=3.4,<3.5 + aiohttp35: aiohttp>=3.5,<3.6 aiohttp-master: https://github.com/aio-libs/aiohttp/archive/master.tar.gz -r{toxinidir}/requirements-dev.txt basepython = py35: python3.5 py36: python3.6 + py37: python3.7 commands = python setup.py test