commit 1739805a29f6e5097630854f1002304e170a6045
Author: Andrew Svetlov <andrew.svetlov@gmail.com>
Date:   Fri Dec 11 10:37:45 2020 +0200

    Backport #3803: Replace brotlipy with Brotli (#5335)
    
    (cherry picked from commit 506d07548a15c4301affa0c8b8e23fd7826eb977)

diff --git a/CHANGES/3803.feature b/CHANGES/3803.feature
new file mode 100644
index 000000000..b2a465619
--- /dev/null
+++ b/CHANGES/3803.feature
@@ -0,0 +1 @@
+Use Brotli instead of brotlipy
diff --git a/aiohttp/http_parser.py b/aiohttp/http_parser.py
index 71ba815ae..854e6796e 100644
--- a/aiohttp/http_parser.py
+++ b/aiohttp/http_parser.py
@@ -812,6 +812,8 @@ class HttpPayloadParser:
 class DeflateBuffer:
     """DeflateStream decompress stream and feed data into specified stream."""
 
+    decompressor: Any
+
     def __init__(self, out: StreamReader, encoding: Optional[str]) -> None:
         self.out = out
         self.size = 0
@@ -822,9 +824,27 @@ class DeflateBuffer:
             if not HAS_BROTLI:  # pragma: no cover
                 raise ContentEncodingError(
                     "Can not decode content-encoding: brotli (br). "
-                    "Please install `brotlipy`"
+                    "Please install `Brotli`"
                 )
-            self.decompressor = brotli.Decompressor()
+
+            class BrotliDecoder:
+                # Supports both 'brotlipy' and 'Brotli' packages
+                # since they share an import name. The top branches
+                # are for 'brotlipy' and bottom branches for 'Brotli'
+                def __init__(self) -> None:
+                    self._obj = brotli.Decompressor()
+
+                def decompress(self, data: bytes) -> bytes:
+                    if hasattr(self._obj, "decompress"):
+                        return self._obj.decompress(data)
+                    return self._obj.process(data)
+
+                def flush(self) -> bytes:
+                    if hasattr(self._obj, "flush"):
+                        return self._obj.flush()
+                    return b""
+
+            self.decompressor = BrotliDecoder()
         else:
             zlib_mode = 16 + zlib.MAX_WBITS if encoding == "gzip" else zlib.MAX_WBITS
             self.decompressor = zlib.decompressobj(wbits=zlib_mode)
diff --git a/docs/client_quickstart.rst b/docs/client_quickstart.rst
index fe770243e..e96dca453 100644
--- a/docs/client_quickstart.rst
+++ b/docs/client_quickstart.rst
@@ -174,7 +174,7 @@ The ``gzip`` and ``deflate`` transfer-encodings are automatically
 decoded for you.
 
 You can enable ``brotli`` transfer-encodings support,
-just install  `brotlipy <https://github.com/python-hyper/brotlipy>`_.
+just install  `brotli <https://github.com/python-hyper/Brotli>`_.
 
 JSON Request
 ============
diff --git a/docs/index.rst b/docs/index.rst
index 13fe723b4..4091c0019 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -52,7 +52,7 @@ Installing speedups altogether
 ------------------------------
 
 The following will get you ``aiohttp`` along with :term:`chardet`,
-:term:`aiodns` and ``brotlipy`` in one bundle. No need to type
+:term:`aiodns` and ``Brotli`` in one bundle. No need to type
 separate commands anymore!
 
 .. code-block:: bash
diff --git a/requirements/base.txt b/requirements/base.txt
index ffd04d12a..859407200 100644
--- a/requirements/base.txt
+++ b/requirements/base.txt
@@ -4,7 +4,7 @@ aiodns==2.0.0; sys_platform=="linux" or sys_platform=="darwin" and python_versio
 async-generator==1.10
 async-timeout==3.0.1
 attrs==20.3.0
-brotlipy==0.7.0
+brotli==1.0.7
 cchardet==2.1.7
 chardet==4.0.0
 gunicorn==20.0.4
diff --git a/setup.py b/setup.py
index 428df5d4e..1c6b1cfad 100644
--- a/setup.py
+++ b/setup.py
@@ -137,7 +137,7 @@ args = dict(
     extras_require={
         "speedups": [
             "aiodns",
-            "brotlipy",
+            "Brotli",
             "cchardet",
         ],
     },