Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support python 3.11 and aiohttp 3.8 #224

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
45 changes: 20 additions & 25 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,31 +22,6 @@ jobs:
fail-fast: false
matrix:
include:
- python-minor-version: 6
aiohttp-version: aiohttp30
os: ubuntu-20.04
- python-minor-version: 6
aiohttp-version: aiohttp31
os: ubuntu-20.04
- python-minor-version: 6
aiohttp-version: aiohttp32
os: ubuntu-20.04
- python-minor-version: 6
aiohttp-version: aiohttp33
os: ubuntu-20.04
- python-minor-version: 6
aiohttp-version: aiohttp34
os: ubuntu-20.04
- python-minor-version: 6
aiohttp-version: aiohttp35
os: ubuntu-20.04
- python-minor-version: 6
aiohttp-version: aiohttp36
os: ubuntu-20.04
- python-minor-version: 6
aiohttp-version: aiohttp37
os: ubuntu-20.04

- python-minor-version: 7
aiohttp-version: aiohttp33
os: ubuntu-latest
Expand All @@ -62,6 +37,9 @@ jobs:
- python-minor-version: 7
aiohttp-version: aiohttp37
os: ubuntu-latest
- python-minor-version: 7
aiohttp-version: aiohttp38
os: ubuntu-latest

- python-minor-version: 8
aiohttp-version: aiohttp33
Expand All @@ -78,6 +56,9 @@ jobs:
- python-minor-version: 8
aiohttp-version: aiohttp37
os: ubuntu-latest
- python-minor-version: 8
aiohttp-version: aiohttp38
os: ubuntu-latest

- python-minor-version: 9
aiohttp-version: aiohttp35
Expand All @@ -88,6 +69,20 @@ jobs:
- python-minor-version: 9
aiohttp-version: aiohttp37
os: ubuntu-latest
- python-minor-version: 9
aiohttp-version: aiohttp38
os: ubuntu-latest

- python-minor-version: 10
aiohttp-version: aiohttp37
os: ubuntu-latest
- python-minor-version: 10
aiohttp-version: aiohttp38
os: ubuntu-latest

- python-minor-version: 11
aiohttp-version: aiohttp38
os: ubuntu-latest
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ Before you submit a pull request, check that it meets these guidelines:
2. If the pull request adds functionality, the docs should be updated. Put
your new functionality into a function with a docstring, and add the
feature to the list in README.rst.
3. The pull request should work for Python 3.5, 3.6, 3.7 and for PyPy. Check
3. The pull request should work for Python 3.7+ and for PyPy. Check
https://travis-ci.org/pnuckowski/aioresponses/pull_requests
and make sure that the tests pass for all supported Python versions.

Expand Down
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ Installing

Supported versions
------------------
- Python 3.5.3+
- aiohttp>=2.0.0,<4.0.0
- Python 3.7+
- aiohttp>=3.3.0,<4.0.0

Usage
--------
Expand Down
19 changes: 6 additions & 13 deletions aioresponses/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from urllib.parse import parse_qsl, urlencode

from aiohttp import __version__ as aiohttp_version, StreamReader
from aiohttp.client_proto import ResponseHandler
from multidict import MultiDict
from pkg_resources import parse_version
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The package throws the following warning when running locally

DeprecationWarning: pkg_resources is deprecated as an API

The official documentation suggests the use of importlib.resources, importlib.metadata as a replacement. More info here: https://setuptools.pypa.io/en/stable/pkg_resources.html

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All that's being used here is parse_version with literal version strings. I'd suggest packaging.version.parse instead of anything from importlib.

@pnuckowski Is anything else blocking this from being merged and released? I got bit by this today and the PR has been sitting for a long time now.

Failing that, does anyone know of a fork that includes Python 3.11 support?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@brettdh I'm wondering the same thing :-S

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can confirm that all unit tests pass in Python 3.11.4 after changing this line (and one other like it, in tests/test_aioresponses.py) to this:

from packaging.version import parse as parse_version

Using a private fork for now, but hoping that can get fixed, merged, and released soon.

from yarl import URL
Expand All @@ -16,20 +17,12 @@

AIOHTTP_VERSION = parse_version(aiohttp_version)

if AIOHTTP_VERSION >= parse_version('3.0.0'):
from aiohttp.client_proto import ResponseHandler


def stream_reader_factory( # noqa
loop: 'Optional[asyncio.AbstractEventLoop]' = None
):
protocol = ResponseHandler(loop=loop)
return StreamReader(protocol, limit=2 ** 16, loop=loop)

else:

def stream_reader_factory(loop=None):
return StreamReader()
def stream_reader_factory( # noqa
loop: 'Optional[asyncio.AbstractEventLoop]' = None
) -> StreamReader:
protocol = ResponseHandler(loop=loop)
return StreamReader(protocol, limit=2 ** 16, loop=loop)


def merge_params(
Expand Down
47 changes: 19 additions & 28 deletions aioresponses/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,8 @@
)
from aiohttp.helpers import TimerNoop
from multidict import CIMultiDict, CIMultiDictProxy
from pkg_resources import parse_version

from .compat import (
AIOHTTP_VERSION,
URL,
Pattern,
stream_reader_factory,
Expand Down Expand Up @@ -149,26 +147,22 @@ def _build_response(self, url: 'Union[URL, str]',
body = str.encode(body)
if request_headers is None:
request_headers = {}
loop = Mock()
loop.get_debug = Mock()
loop.get_debug.return_value = True
kwargs = {} # type: Dict[str, Any]
if AIOHTTP_VERSION >= parse_version('3.1.0'):
loop = Mock()
loop.get_debug = Mock()
loop.get_debug.return_value = True
kwargs['request_info'] = RequestInfo(
url=url,
method=method,
headers=CIMultiDictProxy(CIMultiDict(**request_headers)),
)
kwargs['writer'] = Mock()
kwargs['continue100'] = None
kwargs['timer'] = TimerNoop()
if AIOHTTP_VERSION < parse_version('3.3.0'):
kwargs['auto_decompress'] = True
kwargs['traces'] = []
kwargs['loop'] = loop
kwargs['session'] = None
else:
loop = None
kwargs['request_info'] = RequestInfo(
url=url,
method=method,
headers=CIMultiDictProxy(CIMultiDict(**request_headers)),
)
kwargs['writer'] = Mock()
kwargs['continue100'] = None
kwargs['timer'] = TimerNoop()
kwargs['traces'] = []
kwargs['loop'] = loop
kwargs['session'] = None

# We need to initialize headers manually
_headers = CIMultiDict({hdrs.CONTENT_TYPE: content_type})
if headers:
Expand All @@ -179,13 +173,10 @@ def _build_response(self, url: 'Union[URL, str]',
for hdr in _headers.getall(hdrs.SET_COOKIE, ()):
resp.cookies.load(hdr)

if AIOHTTP_VERSION >= parse_version('3.3.0'):
# Reified attributes
resp._headers = _headers
resp._raw_headers = raw_headers
else:
resp.headers = _headers
resp.raw_headers = raw_headers
# Reified attributes
resp._headers = _headers
resp._raw_headers = raw_headers

resp.status = status
resp.reason = reason
resp.content = stream_reader_factory(loop)
Expand Down
4 changes: 2 additions & 2 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ flake8==3.8.3
tox==3.19.0
coverage==5.2.1
Sphinx==1.5.6
pytest==6.0.1
pytest==7.1.3
pytest-cov==2.10.1
pytest-html==2.1.1
ddt==1.4.1
typing
asynctest==0.13.0
yarl==1.7.2
yarl==1.8.2
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
aiohttp>=2.0.0,<4.0.0
aiohttp>=3.3.0,<4.0.0
3 changes: 2 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ classifier =
License :: OSI Approved :: MIT License
Natural Language :: English
Programming Language :: Python :: 3
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11

[files]
packages =
Expand Down
6 changes: 1 addition & 5 deletions tests/test_aioresponses.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ async def test_raising_exception(self):
callback=lambda *_, **__: callback_called.set())
with self.assertRaises(HttpProcessingError):
await self.session.get(url)

await callback_called.wait()

async def test_multiple_requests(self):
Expand Down Expand Up @@ -742,8 +742,6 @@ async def test_redirect_missing_location_header(self, rsps):
self.assertEqual(str(response.url), self.url)

@aioresponses()
@skipIf(condition=AIOHTTP_VERSION < parse_version('3.1.0'),
reason='aiohttp<3.1.0 does not add request info on response')
async def test_request_info(self, rsps):
rsps.get(self.url, status=200)

Expand All @@ -754,8 +752,6 @@ async def test_request_info(self, rsps):
assert request_info.headers == {}

@aioresponses()
@skipIf(condition=AIOHTTP_VERSION < parse_version('3.1.0'),
reason='aiohttp<3.1.0 does not add request info on response')
async def test_request_info_with_original_request_headers(self, rsps):
headers = {"Authorization": "Bearer access-token"}
rsps.get(self.url, status=200)
Expand Down
20 changes: 6 additions & 14 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
envlist =
flake8,
coverage,
py36-aiohttp{30,31,32,33,34,35,36,37}
py37-aiohttp{33,34,35,36,37}
py38-aiohttp{33,34,35,36,37}
py39-aiohttp{37}
py37-aiohttp{33,34,35,36,37,38}
py38-aiohttp{33,34,35,36,37,38}
py39-aiohttp{37,38}
py310-aiohttp{37,38}
py31-aiohttp38
skipsdist = True

[testenv:flake8]
Expand All @@ -20,21 +21,12 @@ setenv =
passenv = PYTEST_ADDOPTS

deps =
aiohttp20: aiohttp>=2.0,<2.1
aiohttp20: yarl<1.2.0
aiohttp21: aiohttp>=2.1,<2.2
aiohttp21: yarl<1.2.0
aiohttp22: aiohttp>=2.2,<2.3
aiohttp22: yarl<1.2.0
aiohttp23: aiohttp>=2.3,<2.4
aiohttp30: aiohttp>=3.0,<3.1
aiohttp31: aiohttp>=3.1,<3.2
aiohttp32: aiohttp>=3.2,<3.3
aiohttp33: aiohttp>=3.3,<3.4
aiohttp34: aiohttp>=3.4,<3.5
aiohttp35: aiohttp>=3.5,<3.6
aiohttp36: aiohttp>=3.6,<3.7
aiohttp37: aiohttp>=3.7,<3.8
aiohttp38: aiohttp>=3.8,<3.9
-r{toxinidir}/requirements-dev.txt

commands = python -m pytest {posargs}