Skip to content

Commit d0148cf

Browse files
committed
Use compression.zstd (PEP-784)
1 parent 6a796c8 commit d0148cf

File tree

7 files changed

+147
-114
lines changed

7 files changed

+147
-114
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@ python -m pip install "pymongo[snappy]"
139139
```
140140

141141
Wire protocol compression with zstandard requires
142-
[zstandard](https://pypi.org/project/zstandard):
142+
[backports.zstd](https://pypi.org/project/backports.zstd)
143+
when used with Python versions before 3.14:
143144

144145
```bash
145146
python -m pip install "pymongo[zstd]"

doc/changelog.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ PyMongo 4.16 brings a number of changes including:
1616
Python 3.10+. The minimum version is ``2.6.1`` to account for `CVE-2023-29483 <https://www.cve.org/CVERecord?id=CVE-2023-29483>`_.
1717
- Removed support for Eventlet.
1818
Eventlet is actively being sunset by its maintainers and has compatibility issues with PyMongo's dnspython dependency.
19+
- Use Zstandard support from the standard library for Python 3.14+, and use ``backports.zstd`` for older versions.
1920

2021
Changes in Version 4.15.3 (2025/10/07)
2122
--------------------------------------

pymongo/asynchronous/mongo_client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -422,8 +422,8 @@ def __init__(
422422
with the server. Currently supported options are "snappy", "zlib"
423423
and "zstd". Support for snappy requires the
424424
`python-snappy <https://pypi.org/project/python-snappy/>`_ package.
425-
zlib support requires the Python standard library zlib module. zstd
426-
requires the `zstandard <https://pypi.org/project/zstandard/>`_
425+
zlib support requires the Python standard library zlib module. For
426+
Python before 3.14 zstd requires the `backports.zstd <https://pypi.org/project/backports.zstd/>`_
427427
package. By default no compression is used. Compression support
428428
must also be enabled on the server. MongoDB 3.6+ supports snappy
429429
and zlib compression. MongoDB 4.2+ adds support for zstd.

pymongo/compression_support.py

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# limitations under the License.
1414
from __future__ import annotations
1515

16+
import sys
1617
import warnings
1718
from typing import Any, Iterable, Optional, Union
1819

@@ -44,7 +45,10 @@ def _have_zlib() -> bool:
4445

4546
def _have_zstd() -> bool:
4647
try:
47-
import zstandard # noqa: F401
48+
if sys.version_info >= (3, 14):
49+
from compression import zstd
50+
else:
51+
from backports import zstd # noqa: F401
4852

4953
return True
5054
except ImportError:
@@ -79,11 +83,18 @@ def validate_compressors(dummy: Any, value: Union[str, Iterable[str]]) -> list[s
7983
)
8084
elif compressor == "zstd" and not _have_zstd():
8185
compressors.remove(compressor)
82-
warnings.warn(
83-
"Wire protocol compression with zstandard is not available. "
84-
"You must install the zstandard module for zstandard support.",
85-
stacklevel=2,
86-
)
86+
if sys.version_info >= (3, 14):
87+
warnings.warn(
88+
"Wire protocol compression with zstandard is not available. "
89+
"The compression.zstd module is not available.",
90+
stacklevel=2,
91+
)
92+
else:
93+
warnings.warn(
94+
"Wire protocol compression with zstandard is not available. "
95+
"You must install the backports.zstd module for zstandard support.",
96+
stacklevel=2,
97+
)
8798
return compressors
8899

89100

@@ -144,12 +155,12 @@ class ZstdContext:
144155

145156
@staticmethod
146157
def compress(data: bytes) -> bytes:
147-
# ZstdCompressor is not thread safe.
148-
# TODO: Use a pool?
149-
150-
import zstandard
158+
if sys.version_info >= (3, 14):
159+
from compression import zstd
160+
else:
161+
from backports import zstd
151162

152-
return zstandard.ZstdCompressor().compress(data)
163+
return zstd.compress(data)
153164

154165

155166
def decompress(data: bytes | memoryview, compressor_id: int) -> bytes:
@@ -166,10 +177,11 @@ def decompress(data: bytes | memoryview, compressor_id: int) -> bytes:
166177

167178
return zlib.decompress(data)
168179
elif compressor_id == ZstdContext.compressor_id:
169-
# ZstdDecompressor is not thread safe.
170-
# TODO: Use a pool?
171-
import zstandard
180+
if sys.version_info >= (3, 14):
181+
from compression import zstd
182+
else:
183+
from backports import zstd
172184

173-
return zstandard.ZstdDecompressor().decompress(data)
185+
return zstd.decompress(data)
174186
else:
175187
raise ValueError("Unknown compressorId %d" % (compressor_id,))

pymongo/synchronous/mongo_client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -422,8 +422,8 @@ def __init__(
422422
with the server. Currently supported options are "snappy", "zlib"
423423
and "zstd". Support for snappy requires the
424424
`python-snappy <https://pypi.org/project/python-snappy/>`_ package.
425-
zlib support requires the Python standard library zlib module. zstd
426-
requires the `zstandard <https://pypi.org/project/zstandard/>`_
425+
zlib support requires the Python standard library zlib module. For
426+
Python before 3.14 zstd requires the `backports.zstd <https://pypi.org/project/backports.zstd/>`_
427427
package. By default no compression is used. Compression support
428428
must also be enabled on the server. MongoDB 3.6+ supports snappy
429429
and zlib compression. MongoDB 4.2+ adds support for zstd.

requirements/zstd.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
zstandard
1+
backports.zstd>=1.0.0;python_version<'3.14'

0 commit comments

Comments
 (0)