Skip to content

Commit 692b302

Browse files
committed
zstandard: add compress()/decompress() convenience functions
People have requested these utility functions in the past. Now seems like as good a time as any to add them.
1 parent 72734e0 commit 692b302

File tree

5 files changed

+78
-4
lines changed

5 files changed

+78
-4
lines changed

docs/misc_apis.rst

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,26 @@ https://github.com/facebook/zstd/blob/master/doc/zstd_compression_format.md.
2222
:members:
2323
:undoc-members:
2424

25-
estimate_decompression_context_size()
26-
=====================================
25+
``estimate_decompression_context_size()``
26+
=========================================
2727

2828
.. autofunction:: zstandard.estimate_decompression_context_size
2929

30-
open()
31-
======
30+
``open()``
31+
==========
3232

3333
.. autofunction:: zstandard.open
3434

35+
``compress()``
36+
==============
37+
38+
.. autofunction:: zstandard.compress
39+
40+
``decompress()``
41+
================
42+
43+
.. autofunction:: zstandard.decompress
44+
3545
Constants
3646
=========
3747

docs/news.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,9 @@ Changes
229229
defined via Python docstrings instead of spread across Sphinx ReST
230230
files and source code.
231231
* ``ZstdCompressionParameters`` now exposes a ``strategy`` property.
232+
* There are now ``compress()`` and ``decompress()`` convenience functions
233+
on the ``zstandard`` module. These are simply wrappers around the
234+
corresponding APIs on ``ZstdCompressor`` and ``ZstdDecompressor``.
232235

233236
0.14.1 (released 2020-12-05)
234237
============================

tests/test_utility.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import unittest
2+
3+
import zstandard as zstd
4+
5+
6+
class TestCompress(unittest.TestCase):
7+
def test_simple(self):
8+
frame = zstd.compress(b"foobar")
9+
10+
fp = zstd.get_frame_parameters(frame)
11+
self.assertEqual(fp.content_size, 6)
12+
self.assertFalse(fp.has_checksum)
13+
14+
zstd.compress(b"foobar" * 16384, level=7)
15+
16+
17+
class TestDecompress(unittest.TestCase):
18+
def test_simple(self):
19+
source = b"foobar" * 8192
20+
frame = zstd.compress(source)
21+
self.assertEqual(zstd.decompress(frame), source)

zstandard/__init__.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import os
1919
import platform
2020

21+
from typing import ByteString
22+
2123
# Some Python implementations don't support C extensions. That's why we have
2224
# a CFFI implementation in the first place. The code here import one of our
2325
# "backends" then re-exports the symbols from this module. For convenience,
@@ -170,3 +172,39 @@ def open(
170172
)
171173
else:
172174
return fh
175+
176+
177+
def compress(data: ByteString, level: int = 3) -> bytes:
178+
"""Compress source data using the zstd compression format.
179+
180+
This performs one-shot compression using basic/default compression
181+
settings.
182+
183+
This method is provided for convenience and is equivalent to calling
184+
``ZstdCompressor(level=level).compress(data)``.
185+
186+
If you find yourself calling this function in a tight loop,
187+
performance will be greater if you construct a single ``ZstdCompressor``
188+
and repeatedly call ``compress()`` on it.
189+
"""
190+
cctx = ZstdCompressor(level=level)
191+
192+
return cctx.compress(data)
193+
194+
195+
def decompress(data: ByteString, max_output_size: int = 0) -> bytes:
196+
"""Decompress a zstd frame into its original data.
197+
198+
This performs one-shot decompression using basic/default compression
199+
settings.
200+
201+
This method is provided for convenience and is equivalent to calling
202+
``ZstdDecompressor().decompress(data, max_output_size=max_output_size)``.
203+
204+
If you find yourself calling this function in a tight loop, performance
205+
will be greater if you construct a single ``ZstdDecompressor`` and
206+
repeatedly call ``decompress()`` on it.
207+
"""
208+
dctx = ZstdDecompressor()
209+
210+
return dctx.decompress(data, max_output_size=max_output_size)

zstandard/__init__.pyi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,3 +457,5 @@ def open(
457457
newline: Optional[str] = None,
458458
closefd: bool = None,
459459
): ...
460+
def compress(data: ByteString, level: int = ...) -> bytes: ...
461+
def decompress(data: ByteString, max_output_size: int = ...) -> bytes: ...

0 commit comments

Comments
 (0)