Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES/11623.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Switched to `backports.zstd` for Python <3.14 and fixed zstd decompression for chunked zstd streams -- by :user:`ZhaoMJ`.
1 change: 1 addition & 0 deletions CONTRIBUTORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ Mikhail Burshteyn
Mikhail Kashkin
Mikhail Lukyanchenko
Mikhail Nacharov
Mingjie Zhao
Misha Behersky
Mitchell Ferree
Morgan Delahaye-Prat
Expand Down
18 changes: 7 additions & 11 deletions aiohttp/compression_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,14 @@
HAS_BROTLI = False

try:
from compression.zstd import ( # type: ignore[import-not-found] # noqa: I900
ZstdDecompressor,
)
if sys.version_info >= (3, 14):
from compression.zstd import ZstdDecompressor # noqa: I900
else: # TODO(PY314): Remove mentions of backports.zstd across codebase
from backports.zstd import ZstdDecompressor

HAS_ZSTD = True
except ImportError:
try:
from zstandard import ZstdDecompressor

HAS_ZSTD = True
except ImportError:
HAS_ZSTD = False
HAS_ZSTD = False


MAX_SYNC_CHUNK_SIZE = 1024
Expand Down Expand Up @@ -298,12 +294,12 @@ def __init__(self) -> None:
if not HAS_ZSTD:
raise RuntimeError(
"The zstd decompression is not available. "
"Please install `zstandard` module"
"Please install `backports.zstd` module"
)
self._obj = ZstdDecompressor()

def decompress_sync(self, data: bytes) -> bytes:
return self._obj.decompress(data) # type: ignore[no-any-return]
return self._obj.decompress(data)

def flush(self) -> bytes:
return b""
2 changes: 1 addition & 1 deletion aiohttp/http_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -938,7 +938,7 @@ def __init__(self, out: StreamReader, encoding: str | None) -> None:
if not HAS_ZSTD:
raise ContentEncodingError(
"Can not decode content-encoding: zstandard (zstd). "
"Please install `zstandard`"
"Please install `backports.zstd`"
)
self.decompressor = ZSTDDecompressor()
else:
Expand Down
2 changes: 1 addition & 1 deletion docs/client_quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ just install `Brotli <https://pypi.org/project/Brotli/>`_
or `brotlicffi <https://pypi.org/project/brotlicffi/>`_.

You can enable ``zstd`` transfer-encodings support,
install `zstandard <https://pypi.org/project/zstandard/>`_.
install `backports.zstd <https://pypi.org/project/backports.zstd/>`_.
If you are using Python >= 3.14, no dependency should be required.

JSON Request
Expand Down
8 changes: 4 additions & 4 deletions requirements/base-ft.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ aiosignal==1.4.0
# via -r requirements/runtime-deps.in
async-timeout==5.0.1 ; python_version < "3.11"
# via -r requirements/runtime-deps.in
backports-zstd==0.5.0 ; platform_python_implementation == "CPython" and python_version < "3.14"
# via -r requirements/runtime-deps.in
brotli==1.1.0 ; platform_python_implementation == "CPython"
# via -r requirements/runtime-deps.in
cffi==2.0.0
Expand All @@ -30,7 +32,7 @@ multidict==6.7.0
# yarl
packaging==25.0
# via gunicorn
propcache==0.4.0
propcache==0.4.1
# via
# -r requirements/runtime-deps.in
# yarl
Expand All @@ -42,7 +44,5 @@ typing-extensions==4.15.0
# via
# aiosignal
# multidict
yarl==1.21.0
# via -r requirements/runtime-deps.in
zstandard==0.25.0 ; platform_python_implementation == "CPython" and python_version < "3.14"
yarl==1.22.0
# via -r requirements/runtime-deps.in
8 changes: 4 additions & 4 deletions requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ aiosignal==1.4.0
# via -r requirements/runtime-deps.in
async-timeout==5.0.1 ; python_version < "3.11"
# via -r requirements/runtime-deps.in
backports-zstd==0.5.0 ; platform_python_implementation == "CPython" and python_version < "3.14"
# via -r requirements/runtime-deps.in
brotli==1.1.0 ; platform_python_implementation == "CPython"
# via -r requirements/runtime-deps.in
cffi==2.0.0
Expand All @@ -30,7 +32,7 @@ multidict==6.7.0
# yarl
packaging==25.0
# via gunicorn
propcache==0.4.0
propcache==0.4.1
# via
# -r requirements/runtime-deps.in
# yarl
Expand All @@ -44,7 +46,5 @@ typing-extensions==4.15.0
# multidict
uvloop==0.21.0 ; platform_system != "Windows" and implementation_name == "cpython"
# via -r requirements/base.in
yarl==1.21.0
# via -r requirements/runtime-deps.in
zstandard==0.25.0 ; platform_python_implementation == "CPython" and python_version < "3.14"
yarl==1.22.0
# via -r requirements/runtime-deps.in
12 changes: 6 additions & 6 deletions requirements/constraints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ async-timeout==5.0.1 ; python_version < "3.11"
# valkey
babel==2.17.0
# via sphinx
backports-zstd==0.5.0 ; implementation_name == "cpython"
# via
# -r requirements/lint.in
# -r requirements/runtime-deps.in
blockbuster==1.5.25
# via
# -r requirements/lint.in
Expand Down Expand Up @@ -145,7 +149,7 @@ pluggy==1.6.0
# pytest-cov
pre-commit==4.3.0
# via -r requirements/lint.in
propcache==0.4.0
propcache==0.4.1
# via
# -r requirements/runtime-deps.in
# yarl
Expand Down Expand Up @@ -293,16 +297,12 @@ wait-for-it==2.3.0
# via -r requirements/test-common.in
wheel==0.46.0
# via pip-tools
yarl==1.21.0
yarl==1.22.0
# via -r requirements/runtime-deps.in
zlib-ng==1.0.0
# via
# -r requirements/lint.in
# -r requirements/test-common.in
zstandard==0.25.0 ; implementation_name == "cpython"
# via
# -r requirements/lint.in
# -r requirements/runtime-deps.in

# The following packages are considered to be unsafe in a requirements file:
pip==25.2
Expand Down
12 changes: 6 additions & 6 deletions requirements/dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ async-timeout==5.0.1 ; python_version < "3.11"
# valkey
babel==2.17.0
# via sphinx
backports-zstd==0.5.0 ; platform_python_implementation == "CPython" and python_version < "3.14"
# via
# -r requirements/lint.in
# -r requirements/runtime-deps.in
blockbuster==1.5.25
# via
# -r requirements/lint.in
Expand Down Expand Up @@ -142,7 +146,7 @@ pluggy==1.6.0
# pytest-cov
pre-commit==4.3.0
# via -r requirements/lint.in
propcache==0.4.0
propcache==0.4.1
# via
# -r requirements/runtime-deps.in
# yarl
Expand Down Expand Up @@ -284,16 +288,12 @@ wait-for-it==2.3.0
# via -r requirements/test-common.in
wheel==0.46.0
# via pip-tools
yarl==1.21.0
yarl==1.22.0
# via -r requirements/runtime-deps.in
zlib-ng==1.0.0
# via
# -r requirements/lint.in
# -r requirements/test-common.in
zstandard==0.25.0 ; platform_python_implementation == "CPython" and python_version < "3.14"
# via
# -r requirements/lint.in
# -r requirements/runtime-deps.in

# The following packages are considered to be unsafe in a requirements file:
pip==25.2
Expand Down
2 changes: 1 addition & 1 deletion requirements/lint.in
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
aiodns
backports.zstd; implementation_name == "cpython"
blockbuster
freezegun
isal
Expand All @@ -14,4 +15,3 @@ trustme
uvloop; platform_system != "Windows"
valkey
zlib_ng
zstandard; implementation_name == "cpython"
2 changes: 1 addition & 1 deletion requirements/lint.txt
Original file line number Diff line number Diff line change
Expand Up @@ -123,5 +123,5 @@ virtualenv==20.34.0
# via pre-commit
zlib-ng==1.0.0
# via -r requirements/lint.in
zstandard==0.25.0 ; implementation_name == "cpython"
backports.zstd==0.5.0 ; implementation_name == "cpython"
# via -r requirements/lint.in
2 changes: 1 addition & 1 deletion requirements/runtime-deps.in
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ aiodns >= 3.3.0
aiohappyeyeballs >= 2.5.0
aiosignal >= 1.4.0
async-timeout >= 4.0, < 6.0 ; python_version < "3.11"
backports.zstd; platform_python_implementation == 'CPython' and python_version < "3.14"
Brotli; platform_python_implementation == 'CPython'
brotlicffi; platform_python_implementation != 'CPython'
frozenlist >= 1.1.1
multidict >=4.5, < 7.0
propcache >= 0.2.0
yarl >= 1.17.0, < 2.0
zstandard; platform_python_implementation == 'CPython' and python_version < "3.14"
8 changes: 4 additions & 4 deletions requirements/runtime-deps.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ aiosignal==1.4.0
# via -r requirements/runtime-deps.in
async-timeout==5.0.1 ; python_version < "3.11"
# via -r requirements/runtime-deps.in
backports-zstd==0.5.0 ; platform_python_implementation == "CPython" and python_version < "3.14"
# via -r requirements/runtime-deps.in
brotli==1.1.0 ; platform_python_implementation == "CPython"
# via -r requirements/runtime-deps.in
cffi==2.0.0
Expand All @@ -26,7 +28,7 @@ multidict==6.7.0
# via
# -r requirements/runtime-deps.in
# yarl
propcache==0.4.0
propcache==0.4.1
# via
# -r requirements/runtime-deps.in
# yarl
Expand All @@ -38,7 +40,5 @@ typing-extensions==4.15.0
# via
# aiosignal
# multidict
yarl==1.21.0
# via -r requirements/runtime-deps.in
zstandard==0.25.0 ; platform_python_implementation == "CPython" and python_version < "3.14"
yarl==1.22.0
# via -r requirements/runtime-deps.in
8 changes: 4 additions & 4 deletions requirements/test-ft.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ annotated-types==0.7.0
# via pydantic
async-timeout==5.0.1 ; python_version < "3.11"
# via -r requirements/runtime-deps.in
backports-zstd==0.5.0 ; platform_python_implementation == "CPython" and python_version < "3.14"
# via -r requirements/runtime-deps.in
blockbuster==1.5.25
# via -r requirements/test-common.in
brotli==1.1.0 ; platform_python_implementation == "CPython"
Expand Down Expand Up @@ -77,7 +79,7 @@ pluggy==1.6.0
# via
# pytest
# pytest-cov
propcache==0.4.0
propcache==0.4.1
# via
# -r requirements/runtime-deps.in
# yarl
Expand Down Expand Up @@ -142,9 +144,7 @@ typing-inspection==0.4.2
# via pydantic
wait-for-it==2.3.0
# via -r requirements/test-common.in
yarl==1.21.0
yarl==1.22.0
# via -r requirements/runtime-deps.in
zlib-ng==1.0.0
# via -r requirements/test-common.in
zstandard==0.25.0 ; platform_python_implementation == "CPython" and python_version < "3.14"
# via -r requirements/runtime-deps.in
8 changes: 4 additions & 4 deletions requirements/test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ annotated-types==0.7.0
# via pydantic
async-timeout==5.0.1 ; python_version < "3.11"
# via -r requirements/runtime-deps.in
backports-zstd==0.5.0 ; platform_python_implementation == "CPython" and python_version < "3.14"
# via -r requirements/runtime-deps.in
blockbuster==1.5.25
# via -r requirements/test-common.in
brotli==1.1.0 ; platform_python_implementation == "CPython"
Expand Down Expand Up @@ -77,7 +79,7 @@ pluggy==1.6.0
# via
# pytest
# pytest-cov
propcache==0.4.0
propcache==0.4.1
# via
# -r requirements/runtime-deps.in
# yarl
Expand Down Expand Up @@ -144,9 +146,7 @@ uvloop==0.21.0 ; platform_system != "Windows" and implementation_name == "cpytho
# via -r requirements/base.in
wait-for-it==2.3.0
# via -r requirements/test-common.in
yarl==1.21.0
yarl==1.22.0
# via -r requirements/runtime-deps.in
zlib-ng==1.0.0
# via -r requirements/test-common.in
zstandard==0.25.0 ; platform_python_implementation == "CPython" and python_version < "3.14"
# via -r requirements/runtime-deps.in
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ speedups =
aiodns >= 3.3.0
Brotli; platform_python_implementation == 'CPython'
brotlicffi; platform_python_implementation != 'CPython'
zstandard; platform_python_implementation == 'CPython' and python_version < "3.14"
backports.zstd; platform_python_implementation == 'CPython' and python_version < "3.14"

[options.packages.find]
exclude =
Expand Down
14 changes: 7 additions & 7 deletions tests/test_http_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@
except ImportError:
brotli = None

if sys.version_info >= (3, 14):
import compression.zstd as zstandard # noqa: I900
else:
try:
import zstandard
except ImportError:
zstandard = None # type: ignore[assignment]
try:
if sys.version_info >= (3, 14):
import compression.zstd as zstandard # noqa: I900
else:
import backports.zstd as zstandard
except ImportError:
zstandard = None # type: ignore[assignment]

REQUEST_PARSERS = [HttpRequestParserPy]
RESPONSE_PARSERS = [HttpResponseParserPy]
Expand Down
Loading