When running the test suite under python3.8 I get the following errors:
E AssertionError: expected call not found.
E Expected: mock(<aiohttp.client.ClientSession object at 0x7ffff2e41a60>, <ANY>, TraceRequestExceptionParams(method='GET', url=URL('http://example.com'), headers=<CIMultiDict()>, exception=Exception()))
E Actual: mock(<aiohttp.client.ClientSession object at 0x7ffff2e41a60>, namespace(trace_request_ctx=None), TraceRequestExceptionParams(method='GET', url=URL('http://example.com'), headers=<CIMultiDict()>, exception=AttributeError("'_asyncio.Future' object has no attribute 'transport'")))
and
TypeError: unsupported operand type(s) for +: '_asyncio.Future' and '_asyncio.Future'
Full failure log
____________________ test_request_tracing_exception[pyloop] ____________________
loop = <_UnixSelectorEventLoop running=False closed=False debug=False>
async def test_request_tracing_exception(loop) -> None:
on_request_end = mock.Mock(side_effect=make_mocked_coro(mock.Mock()))
on_request_exception = mock.Mock(
side_effect=make_mocked_coro(mock.Mock())
)
trace_config = aiohttp.TraceConfig()
trace_config.on_request_end.append(on_request_end)
trace_config.on_request_exception.append(on_request_exception)
with mock.patch("aiohttp.client.TCPConnector.connect") as connect_patched:
error = Exception()
f = loop.create_future()
f.set_exception(error)
connect_patched.return_value = f
session = aiohttp.ClientSession(
loop=loop,
trace_configs=[trace_config]
)
try:
await session.get('http://example.com')
except Exception:
pass
> on_request_exception.assert_called_once_with(
session,
mock.ANY,
aiohttp.TraceRequestExceptionParams(
hdrs.METH_GET,
URL("http://example.com"),
CIMultiDict(),
error
)
)
E AssertionError: expected call not found.
E Expected: mock(<aiohttp.client.ClientSession object at 0x7ffff2e41a60>, <ANY>, TraceRequestExceptionParams(method='GET', url=URL('http://example.com'), headers=<CIMultiDict()>, exception=Exception()))
E Actual: mock(<aiohttp.client.ClientSession object at 0x7ffff2e41a60>, namespace(trace_request_ctx=None), TraceRequestExceptionParams(method='GET', url=URL('http://example.com'), headers=<CIMultiDict()>, exception=AttributeError("'_asyncio.Future' object has no attribute 'transport'")))
E
E pytest introspection follows:
E
E Args:
E assert (<aiohttp.cli...transport'"))) == (<aiohttp.cli...=Exception()))
E At index 2 diff: TraceRequestExceptionParams(method='GET', url=URL('http://example.com'), headers=<CIMultiDict()>, exception=AttributeError("'_asyncio.Future' object has no attribute 'transport'")) != TraceRequestExceptionParams(method='GET', url=URL('http://example.com'), headers=<CIMultiDict()>, exception=Exception())
E Use -v to get the full diff
test_client_session.py:637: AssertionError
__________________ TestPartReader.test_read_incomplete_chunk ___________________
self = <test_multipart.TestPartReader object at 0x7ffff3232c70>
async def test_read_incomplete_chunk(self) -> None:
loop = asyncio.get_event_loop()
stream = Stream(b'')
def prepare(data):
f = loop.create_future()
f.set_result(data)
return f
with mock.patch.object(stream, 'read', side_effect=[
prepare(b'Hello, '),
prepare(b'World'),
prepare(b'!\r\n--:'),
prepare(b'')
]):
obj = aiohttp.BodyPartReader(
BOUNDARY, {}, stream)
> c1 = await obj.read_chunk(8)
test_multipart.py:177:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/nix/store/79whj744pzw595azw1zbhf1i7r9di70g-python3.8-aiohttp-3.6.2/lib/python3.8/site-packages/aiohttp/multipart.py:303: in read_chunk
chunk = await self._read_chunk_from_stream(size)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <aiohttp.multipart.BodyPartReader object at 0x7ffff3191fd0>, size = 8
async def _read_chunk_from_stream(self, size: int) -> bytes:
# Reads content chunk of body part with unknown length.
# The Content-Length header for body part is not necessary.
assert size >= len(self._boundary) + 2, \
'Chunk size must be greater or equal than boundary length + 2'
first_chunk = self._prev_chunk is None
if first_chunk:
self._prev_chunk = await self._content.read(size)
chunk = await self._content.read(size)
self._content_eof += int(self._content.at_eof())
assert self._content_eof < 3, "Reading after EOF"
assert self._prev_chunk is not None
> window = self._prev_chunk + chunk
E TypeError: unsupported operand type(s) for +: '_asyncio.Future' and '_asyncio.Future'
/nix/store/79whj744pzw595azw1zbhf1i7r9di70g-python3.8-aiohttp-3.6.2/lib/python3.8/site-packages/aiohttp/multipart.py:336: TypeError
___________ TestPartReader.test_read_boundary_with_incomplete_chunk ____________
self = <test_multipart.TestPartReader object at 0x7ffff31f9460>
async def test_read_boundary_with_incomplete_chunk(self) -> None:
loop = asyncio.get_event_loop()
stream = Stream(b'')
def prepare(data):
f = loop.create_future()
f.set_result(data)
return f
with mock.patch.object(stream, 'read', side_effect=[
prepare(b'Hello, World'),
prepare(b'!\r\n'),
prepare(b'--:'),
prepare(b'')
]):
obj = aiohttp.BodyPartReader(
BOUNDARY, {}, stream)
> c1 = await obj.read_chunk(12)
test_multipart.py:219:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/nix/store/79whj744pzw595azw1zbhf1i7r9di70g-python3.8-aiohttp-3.6.2/lib/python3.8/site-packages/aiohttp/multipart.py:303: in read_chunk
chunk = await self._read_chunk_from_stream(size)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <aiohttp.multipart.BodyPartReader object at 0x7ffff318b700>, size = 12
async def _read_chunk_from_stream(self, size: int) -> bytes:
# Reads content chunk of body part with unknown length.
# The Content-Length header for body part is not necessary.
assert size >= len(self._boundary) + 2, \
'Chunk size must be greater or equal than boundary length + 2'
first_chunk = self._prev_chunk is None
if first_chunk:
self._prev_chunk = await self._content.read(size)
chunk = await self._content.read(size)
self._content_eof += int(self._content.at_eof())
assert self._content_eof < 3, "Reading after EOF"
assert self._prev_chunk is not None
> window = self._prev_chunk + chunk
E TypeError: unsupported operand type(s) for +: '_asyncio.Future' and '_asyncio.Future'
/nix/store/79whj744pzw595azw1zbhf1i7r9di70g-python3.8-aiohttp-3.6.2/lib/python3.8/site-packages/aiohttp/multipart.py:336: TypeError
These pass under python3.7
passes
fails
cd tests
pytest -k "not get_valid_log_format_exc \
and not test_access_logger_atoms \
and not aiohttp_request_coroutine \
and not server_close_keepalive_connection \
and not connector \
and not client_disconnect \
and not handle_keepalive_on_closed_connection \
and not proxy_https_bad_response \
and not partially_applied_handler \
and not middleware" \
--ignore=test_connector.py
python3.8.1
aiohttp==3.6.2
- system: `"x86_64-linux"`
- host os: `Linux 5.4.12, NixOS, 20.03pre209478.d5e9b7d5a7c (Markhor)`
- multi-user?: `yes`
- sandbox: `yes`
- version: `nix-env (Nix) 2.3.2`
- channels(root): `"nixos-20.03pre209574.2628f20267d"`
- channels(jon): `"home-manager, nixpkgs-20.03pre209574.2628f20267d"`
- nixpkgs: `/home/jon/.nix-defexpr/channels/nixpkgs`
This is Python 3.8.1 regression, Python 3.8.0 doesn't show this error.
Master and 3.7 branches are fixed.
@asvetlov do you happen to have a reference to the Python issue upstream?
I just tested against 3.8.2rc2 and the same tests still fail.
=================================== FAILURES ===================================
____________________ test_request_tracing_exception[pyloop] ____________________
loop = <_UnixSelectorEventLoop running=False closed=False debug=False>
async def test_request_tracing_exception(loop) -> None:
on_request_end = mock.Mock(side_effect=make_mocked_coro(mock.Mock()))
on_request_exception = mock.Mock(
side_effect=make_mocked_coro(mock.Mock())
)
trace_config = aiohttp.TraceConfig()
trace_config.on_request_end.append(on_request_end)
trace_config.on_request_exception.append(on_request_exception)
with mock.patch("aiohttp.client.TCPConnector.connect") as connect_patched:
error = Exception()
f = loop.create_future()
f.set_exception(error)
connect_patched.return_value = f
session = aiohttp.ClientSession(
loop=loop,
trace_configs=[trace_config]
)
try:
await session.get('http://example.com')
except Exception:
pass
> on_request_exception.assert_called_once_with(
session,
mock.ANY,
aiohttp.TraceRequestExceptionParams(
hdrs.METH_GET,
URL("http://example.com"),
CIMultiDict(),
error
)
)
E AssertionError: expected call not found.
E Expected: mock(<aiohttp.client.ClientSession object at 0x7ffff27a4eb0>, <ANY>, TraceRequestExceptionParams(method='GET', url=URL('http://example.com'), headers=<CIMultiDict()>, exception=Exception()))
E Actual: mock(<aiohttp.client.ClientSession object at 0x7ffff27a4eb0>, namespace(trace_request_ctx=None), TraceRequestExceptionParams(method='GET', url=URL('http://example.com'), headers=<CIMultiDict()>, exception=AttributeError("'_asyncio.Future' object has no attribute 'transport'")))
E
E pytest introspection follows:
E
E Args:
E assert (<aiohttp.cli...transport'"))) == (<aiohttp.cli...=Exception()))
E At index 2 diff: TraceRequestExceptionParams(method='GET', url=URL('http://example.com'), headers=<CIMultiDict()>, exception=AttributeError("'_asyncio.Future' object has no attribute 'transport'")) != TraceRequestExceptionParams(method='GET', url=URL('http://example.com'), headers=<CIMultiDict()>, exception=Exception())
E Use -v to get the full diff
test_client_session.py:637: AssertionError
__________________ TestPartReader.test_read_incomplete_chunk ___________________
self = <test_multipart.TestPartReader object at 0x7ffff2bf3340>
async def test_read_incomplete_chunk(self) -> None:
loop = asyncio.get_event_loop()
stream = Stream(b'')
def prepare(data):
f = loop.create_future()
f.set_result(data)
return f
with mock.patch.object(stream, 'read', side_effect=[
prepare(b'Hello, '),
prepare(b'World'),
prepare(b'!\r\n--:'),
prepare(b'')
]):
obj = aiohttp.BodyPartReader(
BOUNDARY, {}, stream)
> c1 = await obj.read_chunk(8)
test_multipart.py:177:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/nix/store/fvfhyb748kybvb78f656j7v8qsyhyl91-python3.8-aiohttp-3.6.2/lib/python3.8/site-packages/aiohttp/multipart.py:303: in read_chunk
chunk = await self._read_chunk_from_stream(size)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <aiohttp.multipart.BodyPartReader object at 0x7ffff2b8d7f0>, size = 8
async def _read_chunk_from_stream(self, size: int) -> bytes:
# Reads content chunk of body part with unknown length.
# The Content-Length header for body part is not necessary.
assert size >= len(self._boundary) + 2, \
'Chunk size must be greater or equal than boundary length + 2'
first_chunk = self._prev_chunk is None
if first_chunk:
self._prev_chunk = await self._content.read(size)
chunk = await self._content.read(size)
self._content_eof += int(self._content.at_eof())
assert self._content_eof < 3, "Reading after EOF"
assert self._prev_chunk is not None
> window = self._prev_chunk + chunk
E TypeError: unsupported operand type(s) for +: '_asyncio.Future' and '_asyncio.Future'
/nix/store/fvfhyb748kybvb78f656j7v8qsyhyl91-python3.8-aiohttp-3.6.2/lib/python3.8/site-packages/aiohttp/multipart.py:336: TypeError
___________ TestPartReader.test_read_boundary_with_incomplete_chunk ____________
self = <test_multipart.TestPartReader object at 0x7ffff2b7e1c0>
async def test_read_boundary_with_incomplete_chunk(self) -> None:
loop = asyncio.get_event_loop()
stream = Stream(b'')
def prepare(data):
f = loop.create_future()
f.set_result(data)
return f
with mock.patch.object(stream, 'read', side_effect=[
prepare(b'Hello, World'),
prepare(b'!\r\n'),
prepare(b'--:'),
prepare(b'')
]):
obj = aiohttp.BodyPartReader(
BOUNDARY, {}, stream)
> c1 = await obj.read_chunk(12)
test_multipart.py:219:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/nix/store/fvfhyb748kybvb78f656j7v8qsyhyl91-python3.8-aiohttp-3.6.2/lib/python3.8/site-packages/aiohttp/multipart.py:303: in read_chunk
chunk = await self._read_chunk_from_stream(size)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <aiohttp.multipart.BodyPartReader object at 0x7ffff2aec430>, size = 12
async def _read_chunk_from_stream(self, size: int) -> bytes:
# Reads content chunk of body part with unknown length.
# The Content-Length header for body part is not necessary.
assert size >= len(self._boundary) + 2, \
'Chunk size must be greater or equal than boundary length + 2'
first_chunk = self._prev_chunk is None
if first_chunk:
self._prev_chunk = await self._content.read(size)
chunk = await self._content.read(size)
self._content_eof += int(self._content.at_eof())
assert self._content_eof < 3, "Reading after EOF"
assert self._prev_chunk is not None
> window = self._prev_chunk + chunk
E TypeError: unsupported operand type(s) for +: '_asyncio.Future' and '_asyncio.Future'
/nix/store/fvfhyb748kybvb78f656j7v8qsyhyl91-python3.8-aiohttp-3.6.2/lib/python3.8/site-packages/aiohttp/multipart.py:336: TypeError
I just built Python 3.8.2 with aiohttp 3.6.2 and got a few test failures, too. I wonder if something other than the 3.8 regression is wrong, then?
=================================== FAILURES ===================================
____________________ test_request_tracing_exception[pyloop] ____________________
loop = <_UnixSelectorEventLoop running=False closed=False debug=False>
async def test_request_tracing_exception(loop) -> None:
on_request_end = mock.Mock(side_effect=make_mocked_coro(mock.Mock()))
on_request_exception = mock.Mock(
side_effect=make_mocked_coro(mock.Mock())
)
trace_config = aiohttp.TraceConfig()
trace_config.on_request_end.append(on_request_end)
trace_config.on_request_exception.append(on_request_exception)
with mock.patch("aiohttp.client.TCPConnector.connect") as connect_patched:
error = Exception()
f = loop.create_future()
f.set_exception(error)
connect_patched.return_value = f
session = aiohttp.ClientSession(
loop=loop,
trace_configs=[trace_config]
)
try:
await session.get('http://example.com')
except Exception:
pass
> on_request_exception.assert_called_once_with(
session,
mock.ANY,
aiohttp.TraceRequestExceptionParams(
hdrs.METH_GET,
URL("http://example.com"),
CIMultiDict(),
error
)
)
E AssertionError: expected call not found.
E Expected: mock(<aiohttp.client.ClientSession object at 0x7ffff31a1940>, <ANY>, TraceRequestExceptionParams(method='GET', url=URL('http://example.com'), headers=<CIMultiDict()>, exception=Exception()))
E Actual: mock(<aiohttp.client.ClientSession object at 0x7ffff31a1940>, namespace(trace_request_ctx=None), TraceRequestExceptionParams(method='GET', url=URL('http://example.com'), headers=<CIMultiDict()>, exception=AttributeError("'_asyncio.Future' object has no attribute 'transport'")))
E
E pytest introspection follows:
E
E Args:
E assert (<aiohttp.cli...transport'"))) == (<aiohttp.cli...=Exception()))
E At index 2 diff: TraceRequestExceptionParams(method='GET', url=URL('http://example.com'), headers=<CIMultiDict()>, exception=AttributeError("'_asyncio.Future' object has no attribute 'transport'")) != TraceRequestExceptionParams(method='GET', url=URL('http://example.com'), headers=<CIMultiDict()>, exception=Exception())
E Use -v to get the full diff
test_client_session.py:637: AssertionError
__________________ TestPartReader.test_read_incomplete_chunk ___________________
self = <test_multipart.TestPartReader object at 0x7ffff33ae160>
async def test_read_incomplete_chunk(self) -> None:
loop = asyncio.get_event_loop()
stream = Stream(b'')
def prepare(data):
f = loop.create_future()
f.set_result(data)
return f
with mock.patch.object(stream, 'read', side_effect=[
prepare(b'Hello, '),
prepare(b'World'),
prepare(b'!\r\n--:'),
prepare(b'')
]):
obj = aiohttp.BodyPartReader(
BOUNDARY, {}, stream)
> c1 = await obj.read_chunk(8)
test_multipart.py:177:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/nix/store/bj2s3scy0ininq4rphfwdc9sayyz3i0l-python3.8-aiohttp-3.6.2/lib/python3.8/site-packages/aiohttp/multipart.py:303: in read_chunk
chunk = await self._read_chunk_from_stream(size)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <aiohttp.multipart.BodyPartReader object at 0x7ffff33a0f40>, size = 8
async def _read_chunk_from_stream(self, size: int) -> bytes:
# Reads content chunk of body part with unknown length.
# The Content-Length header for body part is not necessary.
assert size >= len(self._boundary) + 2, \
'Chunk size must be greater or equal than boundary length + 2'
first_chunk = self._prev_chunk is None
if first_chunk:
self._prev_chunk = await self._content.read(size)
chunk = await self._content.read(size)
self._content_eof += int(self._content.at_eof())
assert self._content_eof < 3, "Reading after EOF"
assert self._prev_chunk is not None
> window = self._prev_chunk + chunk
E TypeError: unsupported operand type(s) for +: '_asyncio.Future' and '_asyncio.Future'
/nix/store/bj2s3scy0ininq4rphfwdc9sayyz3i0l-python3.8-aiohttp-3.6.2/lib/python3.8/site-packages/aiohttp/multipart.py:336: TypeError
___________ TestPartReader.test_read_boundary_with_incomplete_chunk ____________
self = <test_multipart.TestPartReader object at 0x7ffff33ae340>
async def test_read_boundary_with_incomplete_chunk(self) -> None:
loop = asyncio.get_event_loop()
stream = Stream(b'')
def prepare(data):
f = loop.create_future()
f.set_result(data)
return f
with mock.patch.object(stream, 'read', side_effect=[
prepare(b'Hello, World'),
prepare(b'!\r\n'),
prepare(b'--:'),
prepare(b'')
]):
obj = aiohttp.BodyPartReader(
BOUNDARY, {}, stream)
> c1 = await obj.read_chunk(12)
test_multipart.py:219:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/nix/store/bj2s3scy0ininq4rphfwdc9sayyz3i0l-python3.8-aiohttp-3.6.2/lib/python3.8/site-packages/aiohttp/multipart.py:303: in read_chunk
chunk = await self._read_chunk_from_stream(size)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <aiohttp.multipart.BodyPartReader object at 0x7ffff33b3460>, size = 12
async def _read_chunk_from_stream(self, size: int) -> bytes:
# Reads content chunk of body part with unknown length.
# The Content-Length header for body part is not necessary.
assert size >= len(self._boundary) + 2, \
'Chunk size must be greater or equal than boundary length + 2'
first_chunk = self._prev_chunk is None
if first_chunk:
self._prev_chunk = await self._content.read(size)
chunk = await self._content.read(size)
self._content_eof += int(self._content.at_eof())
assert self._content_eof < 3, "Reading after EOF"
assert self._prev_chunk is not None
> window = self._prev_chunk + chunk
E TypeError: unsupported operand type(s) for +: '_asyncio.Future' and '_asyncio.Future'
/nix/store/bj2s3scy0ininq4rphfwdc9sayyz3i0l-python3.8-aiohttp-3.6.2/lib/python3.8/site-packages/aiohttp/multipart.py:336: TypeError
Still failing with python 3.8.3 (and aiohttp 3.6.2). I don't expect people should need to wait for python 3.9 (assuming 3.9 will be OK).
Most helpful comment
I just built Python 3.8.2 with aiohttp 3.6.2 and got a few test failures, too. I wonder if something other than the 3.8 regression is wrong, then?