diff --git a/CHANGES.rst b/CHANGES.rst index 290462927e9..10767df118d 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -10,6 +10,219 @@ .. towncrier release notes start + +3.9.4 (2024-04-11) +================== + +Bug fixes +--------- + +- The asynchronous internals now set the underlying causes + when assigning exceptions to the future objects + -- by :user:`webknjaz`. + + + *Related issues and pull requests on GitHub:* + :issue:`8089`. + + + +- Treated values of ``Accept-Encoding`` header as case-insensitive when checking + for gzip files -- by :user:`steverep`. + + + *Related issues and pull requests on GitHub:* + :issue:`8104`. + + + +- Improved the DNS resolution performance on cache hit -- by :user:`bdraco`. + + This is achieved by avoiding an :mod:`asyncio` task creation in this case. + + + *Related issues and pull requests on GitHub:* + :issue:`8163`. + + +- Changed the type annotations to allow ``dict`` on :meth:`aiohttp.MultipartWriter.append`, + :meth:`aiohttp.MultipartWriter.append_json` and + :meth:`aiohttp.MultipartWriter.append_form` -- by :user:`cakemanny` + + + *Related issues and pull requests on GitHub:* + :issue:`7741`. + + + +- Ensure websocket transport is closed when client does not close it + -- by :user:`bdraco`. + + The transport could remain open if the client did not close it. This + change ensures the transport is closed when the client does not close + it. + + + *Related issues and pull requests on GitHub:* + :issue:`8200`. + + + +- Leave websocket transport open if receive times out or is cancelled + -- by :user:`bdraco`. + + This restores the behavior prior to the change in #7978. + + + *Related issues and pull requests on GitHub:* + :issue:`8251`. + + + +- Fixed content not being read when an upgrade request was not supported with the pure Python implementation. + -- by :user:`bdraco`. + + + *Related issues and pull requests on GitHub:* + :issue:`8252`. + + + +- Fixed a race condition with incoming connections during server shutdown -- by :user:`Dreamsorcerer`. + + + *Related issues and pull requests on GitHub:* + :issue:`8271`. + + + +- Fixed ``multipart/form-data`` compliance with :rfc:`7578` -- by :user:`Dreamsorcerer`. + + + *Related issues and pull requests on GitHub:* + :issue:`8280`. + + + +- Fixed blocking I/O in the event loop while processing files in a POST request + -- by :user:`bdraco`. + + + *Related issues and pull requests on GitHub:* + :issue:`8283`. + + + +- Escaped filenames in static view -- by :user:`bdraco`. + + + *Related issues and pull requests on GitHub:* + :issue:`8317`. + + + +- Fixed the pure python parser to mark a connection as closing when a + response has no length -- by :user:`Dreamsorcerer`. + + + *Related issues and pull requests on GitHub:* + :issue:`8320`. + + + + +Features +-------- + +- Upgraded *llhttp* to 9.2.1, and started rejecting obsolete line folding + in Python parser to match -- by :user:`Dreamsorcerer`. + + + *Related issues and pull requests on GitHub:* + :issue:`8146`, :issue:`8292`. + + + + +Deprecations (removal in next major release) +-------------------------------------------- + +- Deprecated ``content_transfer_encoding`` parameter in :py:meth:`FormData.add_field() + ` -- by :user:`Dreamsorcerer`. + + + *Related issues and pull requests on GitHub:* + :issue:`8280`. + + + + +Improved documentation +---------------------- + +- Added a note about canceling tasks to avoid delaying server shutdown -- by :user:`Dreamsorcerer`. + + + *Related issues and pull requests on GitHub:* + :issue:`8267`. + + + + +Contributor-facing changes +-------------------------- + +- The pull request template is now asking the contributors to + answer a question about the long-term maintenance challenges + they envision as a result of merging their patches + -- by :user:`webknjaz`. + + + *Related issues and pull requests on GitHub:* + :issue:`8099`. + + + +- Updated CI and documentation to use NPM clean install and upgrade + node to version 18 -- by :user:`steverep`. + + + *Related issues and pull requests on GitHub:* + :issue:`8116`. + + + +- A pytest fixture ``hello_txt`` was introduced to aid + static file serving tests in + :file:`test_web_sendfile_functional.py`. It dynamically + provisions ``hello.txt`` file variants shared across the + tests in the module. + + -- by :user:`steverep` + + + *Related issues and pull requests on GitHub:* + :issue:`8136`. + + + + +Packaging updates and notes for downstreams +------------------------------------------- + +- Added an ``internal`` pytest marker for tests which should be skipped + by packagers (use ``-m 'not internal'`` to disable them) -- by :user:`Dreamsorcerer`. + + + *Related issues and pull requests on GitHub:* + :issue:`8299`. + + + + +---- + + 3.9.3 (2024-01-29) ================== @@ -1709,3 +1922,132 @@ Misc ---- - #3341, #3351 + + + + +---- + + +3.1.3 (2018-04-12) +================== + +- Fix cancellation broadcast during DNS resolve (`#2910 `_) + + + + +---- + + +3.1.2 (2018-04-05) +================== + +- Make ``LineTooLong`` exception more detailed about actual data size (`#2863 `_) + +- Call ``on_chunk_sent`` when write_eof takes as a param the last chunk (`#2909 `_) + + + + +---- + + +3.1.1 (2018-03-27) +================== + +- Support *asynchronous iterators* (and *asynchronous generators* as + well) in both client and server API as request / response BODY + payloads. (`#2802 `_) + + + + +---- + + +3.1.0 (2018-03-21) +================== + +Welcome to aiohttp 3.1 release. + +This is an *incremental* release, fully backward compatible with *aiohttp 3.0*. + +But we have added several new features. + +The most visible one is ``app.add_routes()`` (an alias for existing +``app.router.add_routes()``. The addition is very important because +all *aiohttp* docs now uses ``app.add_routes()`` call in code +snippets. All your existing code still do register routes / resource +without any warning but you've got the idea for a favorite way: noisy +``app.router.add_get()`` is replaced by ``app.add_routes()``. + +The library does not make a preference between decorators:: + + routes = web.RouteTableDef() + + @routes.get('/') + async def hello(request): + return web.Response(text="Hello, world") + + app.add_routes(routes) + +and route tables as a list:: + + async def hello(request): + return web.Response(text="Hello, world") + + app.add_routes([web.get('/', hello)]) + +Both ways are equal, user may decide basing on own code taste. + +Also we have a lot of minor features, bug fixes and documentation +updates, see below. + +Features +-------- + +- Relax JSON content-type checking in the ``ClientResponse.json()`` to allow + "application/xxx+json" instead of strict "application/json". (`#2206 `_) +- Bump C HTTP parser to version 2.8 (`#2730 `_) +- Accept a coroutine as an application factory in ``web.run_app`` and gunicorn + worker. (`#2739 `_) +- Implement application cleanup context (``app.cleanup_ctx`` property). (`#2747 `_) +- Make ``writer.write_headers`` a coroutine. (`#2762 `_) +- Add tracking signals for getting request/response bodies. (`#2767 `_) +- Deprecate ClientResponseError.code in favor of .status to keep similarity + with response classes. (`#2781 `_) +- Implement ``app.add_routes()`` method. (`#2787 `_) +- Implement ``web.static()`` and ``RouteTableDef.static()`` API. (`#2795 `_) +- Install a test event loop as default by ``asyncio.set_event_loop()``. The + change affects aiohttp test utils but backward compatibility is not broken + for 99.99% of use cases. (`#2804 `_) +- Refactor ``ClientResponse`` constructor: make logically required constructor + arguments mandatory, drop ``_post_init()`` method. (`#2820 `_) +- Use ``app.add_routes()`` in server docs everywhere (`#2830 `_) +- Websockets refactoring, all websocket writer methods are converted into + coroutines. (`#2836 `_) +- Provide ``Content-Range`` header for ``Range`` requests (`#2844 `_) + + +Bugfixes +-------- + +- Fix websocket client return EofStream. (`#2784 `_) +- Fix websocket demo. (`#2789 `_) +- Property ``BaseRequest.http_range`` now returns a python-like slice when + requesting the tail of the range. It's now indicated by a negative value in + ``range.start`` rather then in ``range.stop`` (`#2805 `_) +- Close a connection if an unexpected exception occurs while sending a request + (`#2827 `_) +- Fix firing DNS tracing events. (`#2841 `_) + + +Improved Documentation +---------------------- + +- Document behavior when cchardet detects encodings that are unknown to Python. + (`#2732 `_) +- Add diagrams for tracing request life style. (`#2748 `_) +- Drop removed functionality for passing ``StreamReader`` as data at client + side. (`#2793 `_) diff --git a/CHANGES/7741.bugfix.rst b/CHANGES/7741.bugfix.rst deleted file mode 100644 index 9134e920c14..00000000000 --- a/CHANGES/7741.bugfix.rst +++ /dev/null @@ -1,3 +0,0 @@ -Changed the type annotations to allow ``dict`` on :meth:`aiohttp.MultipartWriter.append`, -:meth:`aiohttp.MultipartWriter.append_json` and -:meth:`aiohttp.MultipartWriter.append_form` -- by :user:`cakemanny` diff --git a/CHANGES/8010.doc b/CHANGES/8010.doc deleted file mode 100644 index db1b0aa3225..00000000000 --- a/CHANGES/8010.doc +++ /dev/null @@ -1,2 +0,0 @@ -On the `CHANGES/README.rst `_ page, -a link to the ``Towncrier philosophy`` has been fixed. diff --git a/CHANGES/8089.bugfix.rst b/CHANGES/8089.bugfix.rst deleted file mode 100644 index 7f47448478d..00000000000 --- a/CHANGES/8089.bugfix.rst +++ /dev/null @@ -1,3 +0,0 @@ -The asynchronous internals now set the underlying causes -when assigning exceptions to the future objects --- by :user:`webknjaz`. diff --git a/CHANGES/8099.contrib.rst b/CHANGES/8099.contrib.rst deleted file mode 100644 index 827ecfa5827..00000000000 --- a/CHANGES/8099.contrib.rst +++ /dev/null @@ -1,4 +0,0 @@ -The pull request template is now asking the contributors to -answer a question about the long-term maintenance challenges -they envision as a result of merging their patches --- by :user:`webknjaz`. diff --git a/CHANGES/8104.bugfix.rst b/CHANGES/8104.bugfix.rst deleted file mode 100644 index 1ebe6f06d9d..00000000000 --- a/CHANGES/8104.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Treated values of ``Accept-Encoding`` header as case-insensitive when checking for gzip files -- by :user:`steverep`. diff --git a/CHANGES/8116.contrib.rst b/CHANGES/8116.contrib.rst deleted file mode 100644 index c1c7f2ca3bf..00000000000 --- a/CHANGES/8116.contrib.rst +++ /dev/null @@ -1 +0,0 @@ -Updated CI and documentation to use NPM clean install and upgrade node to version 18 -- by :user:`steverep`. diff --git a/CHANGES/8136.contrib.rst b/CHANGES/8136.contrib.rst deleted file mode 100644 index 69718a4e0ab..00000000000 --- a/CHANGES/8136.contrib.rst +++ /dev/null @@ -1,7 +0,0 @@ -A pytest fixture ``hello_txt`` was introduced to aid -static file serving tests in -:file:`test_web_sendfile_functional.py`. It dynamically -provisions ``hello.txt`` file variants shared across the -tests in the module. - --- by :user:`steverep` diff --git a/CHANGES/8146.feature.rst b/CHANGES/8146.feature.rst deleted file mode 100644 index 9b0cc54206e..00000000000 --- a/CHANGES/8146.feature.rst +++ /dev/null @@ -1 +0,0 @@ -Upgraded *llhttp* to 9.2 -- by :user:`Dreamsorcerer`. diff --git a/CHANGES/8163.bugfix.rst b/CHANGES/8163.bugfix.rst deleted file mode 100644 index 8bfb10260c6..00000000000 --- a/CHANGES/8163.bugfix.rst +++ /dev/null @@ -1,5 +0,0 @@ -Improved the DNS resolution performance on cache hit --- by :user:`bdraco`. - -This is achieved by avoiding an :mod:`asyncio` task creation -in this case. diff --git a/CHANGES/8200.bugfix.rst b/CHANGES/8200.bugfix.rst deleted file mode 100644 index e4492a8a84c..00000000000 --- a/CHANGES/8200.bugfix.rst +++ /dev/null @@ -1,6 +0,0 @@ -Ensure websocket transport is closed when client does not close it --- by :user:`bdraco`. - -The transport could remain open if the client did not close it. This -change ensures the transport is closed when the client does not close -it. diff --git a/CHANGES/8251.bugfix.rst b/CHANGES/8251.bugfix.rst deleted file mode 100644 index 6fc6507cfe2..00000000000 --- a/CHANGES/8251.bugfix.rst +++ /dev/null @@ -1,4 +0,0 @@ -Leave websocket transport open if receive times out or is cancelled --- by :user:`bdraco`. - -This restores the behavior prior to the change in #7978. diff --git a/CHANGES/8252.bugfix.rst b/CHANGES/8252.bugfix.rst deleted file mode 100644 index e932eb9c7ed..00000000000 --- a/CHANGES/8252.bugfix.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed content not being read when an upgrade request was not supported with the pure Python implementation. --- by :user:`bdraco`. diff --git a/CHANGES/8267.doc.rst b/CHANGES/8267.doc.rst deleted file mode 100644 index 69f11d37560..00000000000 --- a/CHANGES/8267.doc.rst +++ /dev/null @@ -1 +0,0 @@ -Added a note about canceling tasks to avoid delaying server shutdown -- by :user:`Dreamsorcerer`. diff --git a/CHANGES/8271.bugfix.rst b/CHANGES/8271.bugfix.rst deleted file mode 100644 index 9d572ba2fe6..00000000000 --- a/CHANGES/8271.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed a race condition with incoming connections during server shutdown -- by :user:`Dreamsorcerer`. diff --git a/CHANGES/8280.bugfix.rst b/CHANGES/8280.bugfix.rst deleted file mode 100644 index 3aebe36fe9e..00000000000 --- a/CHANGES/8280.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed ``multipart/form-data`` compliance with :rfc:`7578` -- by :user:`Dreamsorcerer`. diff --git a/CHANGES/8280.deprecation.rst b/CHANGES/8280.deprecation.rst deleted file mode 100644 index 302dbb2fe2a..00000000000 --- a/CHANGES/8280.deprecation.rst +++ /dev/null @@ -1,2 +0,0 @@ -Deprecated ``content_transfer_encoding`` parameter in :py:meth:`FormData.add_field() -` -- by :user:`Dreamsorcerer`. diff --git a/CHANGES/8283.bugfix.rst b/CHANGES/8283.bugfix.rst deleted file mode 100644 index d456d59ba8e..00000000000 --- a/CHANGES/8283.bugfix.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed blocking I/O in the event loop while processing files in a POST request --- by :user:`bdraco`. diff --git a/CHANGES/8292.feature.rst b/CHANGES/8292.feature.rst deleted file mode 100644 index 6ca82503143..00000000000 --- a/CHANGES/8292.feature.rst +++ /dev/null @@ -1 +0,0 @@ -Upgraded to LLHTTP 9.2.1, and started rejecting obsolete line folding in Python parser to match -- by :user:`Dreamsorcerer`. diff --git a/CHANGES/8299.packaging.rst b/CHANGES/8299.packaging.rst deleted file mode 100644 index 05abc8237e2..00000000000 --- a/CHANGES/8299.packaging.rst +++ /dev/null @@ -1,2 +0,0 @@ -Added an ``internal`` pytest marker for tests which should be skipped -by packagers (use ``-m 'not internal'`` to disable them) -- by :user:`Dreamsorcerer`. diff --git a/CHANGES/8317.bugfix.rst b/CHANGES/8317.bugfix.rst deleted file mode 100644 index b24ef2aeb81..00000000000 --- a/CHANGES/8317.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Escaped filenames in static view -- by :user:`bdraco`. diff --git a/CHANGES/8320.bugfix.rst b/CHANGES/8320.bugfix.rst deleted file mode 100644 index 027074f743b..00000000000 --- a/CHANGES/8320.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed the pure python parser to mark a connection as closing when a response has no length -- by :user:`Dreamsorcerer`. diff --git a/aiohttp/multipart.py b/aiohttp/multipart.py index 30f4a9ce514..fe3ad6bacaa 100644 --- a/aiohttp/multipart.py +++ b/aiohttp/multipart.py @@ -574,11 +574,7 @@ class MultipartReader: #: Body part reader class for non multipart/* content types. part_reader_cls = BodyPartReader - def __init__( - self, - headers: Mapping[str, str], - content: StreamReader, - ) -> None: + def __init__(self, headers: Mapping[str, str], content: StreamReader) -> None: self._mimetype = parse_mimetype(headers[CONTENT_TYPE]) assert self._mimetype.type == "multipart", "multipart/* content type expected" if "boundary" not in self._mimetype.parameters: diff --git a/examples/fake_server.py b/examples/fake_server.py index 9feb0a9eea2..860cbc1e753 100755 --- a/examples/fake_server.py +++ b/examples/fake_server.py @@ -5,8 +5,9 @@ import ssl from typing import Dict, List, Union -from aiohttp import ClientSession, TCPConnector, resolver, test_utils, web +from aiohttp import ClientSession, TCPConnector, test_utils, web from aiohttp.abc import AbstractResolver, ResolveResult +from aiohttp.resolver import DefaultResolver class FakeResolver(AbstractResolver): @@ -15,7 +16,7 @@ class FakeResolver(AbstractResolver): def __init__(self, fakes: Dict[str, int]) -> None: """fakes -- dns -> port dict""" self._fakes = fakes - self._resolver = resolver.DefaultResolver() + self._resolver = DefaultResolver() async def resolve( self, diff --git a/tests/test_client_session.py b/tests/test_client_session.py index c0ce9c1658d..5dd902dbe2c 100644 --- a/tests/test_client_session.py +++ b/tests/test_client_session.py @@ -843,6 +843,11 @@ async def test_build_url_returns_expected_url( assert session._build_url(url) == expected_url -async def test_instantiation_with_invalid_timeout_value(): +async def test_instantiation_with_invalid_timeout_value(loop): + loop.set_debug(False) + logs = [] + loop.set_exception_handler(lambda loop, ctx: logs.append(ctx)) with pytest.raises(ValueError, match="timeout parameter cannot be .*"): ClientSession(timeout=1) + # should not have "Unclosed client session" warning + assert not logs diff --git a/tests/test_resolver.py b/tests/test_resolver.py index 614f4beb89e..5e454dde334 100644 --- a/tests/test_resolver.py +++ b/tests/test_resolver.py @@ -31,7 +31,6 @@ class FakeAIODNSAddrInfoNode(NamedTuple): class FakeAIODNSAddrInfoIPv4Result: - def __init__(self, hosts: Collection[str]) -> None: self.nodes = [ FakeAIODNSAddrInfoNode(socket.AF_INET, (h.encode(), 0)) for h in hosts @@ -39,7 +38,6 @@ def __init__(self, hosts: Collection[str]) -> None: class FakeAIODNSAddrInfoIPv6Result: - def __init__(self, hosts: Collection[str]) -> None: self.nodes = [ FakeAIODNSAddrInfoNode( @@ -51,7 +49,6 @@ def __init__(self, hosts: Collection[str]) -> None: class FakeAIODNSNameInfoIPv6Result: - def __init__(self, host: str) -> None: self.node = host self.service = None