From b8a3b0b871dd4fbfca35e31b9297fd45ed32dbc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Mon, 18 Sep 2023 21:29:59 +0200 Subject: [PATCH] Support brotlicffi alternatively to brotli (#7611) ## What do these changes do? Support the brotlicffi implementation as an alternative to brotli. This is necessary since the current version of brotli (as of 1.1.0) does not work on PyPy. This uses the approach of preferring brotlicffi over brotli in imports, and listing brotli or brotlicffi depending on the Python implementation in dependencies, as recommended in brotlicffi documentation: https://pypi.org/project/brotlicffi/1.1.0.0/#using-brotlicffi-in-projects --- .mypy.ini | 3 +++ CHANGES/7611.feature | 1 + aiohttp/compression_utils.py | 5 ++++- docs/client_quickstart.rst | 3 ++- docs/glossary.rst | 7 +++++++ docs/index.rst | 3 ++- docs/spelling_wordlist.txt | 1 + requirements/runtime-deps.in | 3 ++- setup.cfg | 3 ++- tests/test_http_parser.py | 5 ++++- tests/test_web_functional.py | 6 +++++- 11 files changed, 33 insertions(+), 7 deletions(-) create mode 100644 CHANGES/7611.feature diff --git a/.mypy.ini b/.mypy.ini index 103f1a601a1..895ea60e335 100644 --- a/.mypy.ini +++ b/.mypy.ini @@ -35,6 +35,9 @@ ignore_missing_imports = True [mypy-brotli] ignore_missing_imports = True +[mypy-brotlicffi] +ignore_missing_imports = True + [mypy-gunicorn.*] ignore_missing_imports = True diff --git a/CHANGES/7611.feature b/CHANGES/7611.feature new file mode 100644 index 00000000000..ce1b4b2ac1a --- /dev/null +++ b/CHANGES/7611.feature @@ -0,0 +1 @@ +Support using ``brotlicffi`` Python package alternatively to ``brotli``, as the latter does not work on PyPy. diff --git a/aiohttp/compression_utils.py b/aiohttp/compression_utils.py index 8abc4fa7c3c..52791fe5015 100644 --- a/aiohttp/compression_utils.py +++ b/aiohttp/compression_utils.py @@ -4,7 +4,10 @@ from typing import Optional, cast try: - import brotli + try: + import brotlicffi as brotli + except ImportError: + import brotli HAS_BROTLI = True except ImportError: # pragma: no cover diff --git a/docs/client_quickstart.rst b/docs/client_quickstart.rst index 92334a5f4b4..50b1c252f22 100644 --- a/docs/client_quickstart.rst +++ b/docs/client_quickstart.rst @@ -187,7 +187,8 @@ The ``gzip`` and ``deflate`` transfer-encodings are automatically decoded for you. You can enable ``brotli`` transfer-encodings support, -just install `Brotli `_. +just install `Brotli `_ +or `brotlicffi `_. JSON Request ============ diff --git a/docs/glossary.rst b/docs/glossary.rst index 4bfe7c55126..392ef740cd1 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -40,6 +40,13 @@ https://pypi.org/project/Brotli/ + brotlicffi + + An alternative implementation of :term:`Brotli` built using the CFFI + library. This implementation supports PyPy correctly. + + https://pypi.org/project/brotlicffi/ + callable Any object that can be called. Use :func:`callable` to check diff --git a/docs/index.rst b/docs/index.rst index 62e03c5baa9..a7a7d477c72 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -158,7 +158,8 @@ Dependencies $ pip install aiodns -- *Optional* :term:`Brotli` for brotli (:rfc:`7932`) client compression support. +- *Optional* :term:`Brotli` or :term:`brotlicffi` for brotli (:rfc:`7932`) + client compression support. .. code-block:: bash diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt index 4c732ddd1d4..62ad5957fe5 100644 --- a/docs/spelling_wordlist.txt +++ b/docs/spelling_wordlist.txt @@ -40,6 +40,7 @@ boolean botocore brotli Brotli +brotlicffi brotlipy bugfix Bugfixes diff --git a/requirements/runtime-deps.in b/requirements/runtime-deps.in index 9450a699447..50d5aa423d7 100644 --- a/requirements/runtime-deps.in +++ b/requirements/runtime-deps.in @@ -6,4 +6,5 @@ yarl >= 1.0, < 2.0 frozenlist >= 1.1.1 aiosignal >= 1.1.2 aiodns >= 1.1; sys_platform=="linux" or sys_platform=="darwin" -Brotli +Brotli; platform_python_implementation == 'CPython' +brotlicffi; platform_python_implementation != 'CPython' diff --git a/setup.cfg b/setup.cfg index b098ead7a1d..8fa44a86565 100644 --- a/setup.cfg +++ b/setup.cfg @@ -62,7 +62,8 @@ install_requires = speedups = # required c-ares (aiodns' backend) will not build on windows aiodns >= 1.1; sys_platform=="linux" or sys_platform=="darwin" - Brotli + Brotli; platform_python_implementation == 'CPython' + brotlicffi; platform_python_implementation != 'CPython' [options.packages.find] exclude = diff --git a/tests/test_http_parser.py b/tests/test_http_parser.py index 367cf14da95..6b0ec24103e 100644 --- a/tests/test_http_parser.py +++ b/tests/test_http_parser.py @@ -22,7 +22,10 @@ ) try: - import brotli + try: + import brotlicffi as brotli + except ImportError: + import brotli except ImportError: brotli = None diff --git a/tests/test_web_functional.py b/tests/test_web_functional.py index 5641d2c9096..05ca6afb8bf 100644 --- a/tests/test_web_functional.py +++ b/tests/test_web_functional.py @@ -8,7 +8,6 @@ from typing import Any, Optional from unittest import mock -import brotli import pytest from multidict import CIMultiDictProxy, MultiDict from yarl import URL @@ -19,6 +18,11 @@ from aiohttp.test_utils import make_mocked_coro from aiohttp.typedefs import Handler +try: + import brotlicffi as brotli +except ImportError: + import brotli + try: import ssl except ImportError: