summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Doc/library/gzip.rst16
-rw-r--r--Lib/gzip.py19
-rw-r--r--Lib/test/test_gzip.py20
-rw-r--r--Misc/ACKS1
-rw-r--r--Misc/NEWS3
5 files changed, 58 insertions, 1 deletions
diff --git a/Doc/library/gzip.rst b/Doc/library/gzip.rst
index b99ac740fd..0401cd8211 100644
--- a/Doc/library/gzip.rst
+++ b/Doc/library/gzip.rst
@@ -82,6 +82,17 @@ The module defines the following items:
The *filename* argument is required; *mode* defaults to ``'rb'`` and
*compresslevel* defaults to ``9``.
+.. function:: compress(data, compresslevel=9)
+
+ Compress the *data*, returning a :class:`bytes` object containing
+ the compressed data. *compresslevel* has the same meaning as in
+ the :class:`GzipFile` constructor above.
+
+.. function:: decompress(data)
+
+ Decompress the *data*, returning a :class:`bytes` object containing the
+ uncompressed data.
+
.. _gzip-usage-examples:
@@ -112,6 +123,11 @@ Example of how to GZIP compress an existing file::
f_out.close()
f_in.close()
+Example of how to GZIP compress a binary string::
+
+ import gzip
+ s_in = b"Lots of content here"
+ s_out = gzip.compress(s_in)
.. seealso::
diff --git a/Lib/gzip.py b/Lib/gzip.py
index fab55a3015..83311cc0de 100644
--- a/Lib/gzip.py
+++ b/Lib/gzip.py
@@ -10,7 +10,7 @@ import zlib
import builtins
import io
-__all__ = ["GzipFile","open"]
+__all__ = ["GzipFile", "open", "compress", "decompress"]
FTEXT, FHCRC, FEXTRA, FNAME, FCOMMENT = 1, 2, 4, 8, 16
@@ -476,6 +476,23 @@ class GzipFile(io.BufferedIOBase):
return b''.join(bufs) # Return resulting line
+def compress(data, compresslevel=9):
+ """Compress data in one shot and return the compressed string.
+ Optional argument is the compression level, in range of 1-9.
+ """
+ buf = io.BytesIO()
+ with GzipFile(fileobj=buf, mode='wb', compresslevel=compresslevel) as f:
+ f.write(data)
+ return buf.getvalue()
+
+def decompress(data):
+ """Decompress a gzip compressed string in one shot.
+ Return the decompressed string.
+ """
+ with GzipFile(fileobj=io.BytesIO(data)) as f:
+ return f.read()
+
+
def _test():
# Act like gzip; with -d, act like gunzip.
# The input file is not deleted, however, nor are any other gzip
diff --git a/Lib/test/test_gzip.py b/Lib/test/test_gzip.py
index 7eade6f60a..a95af058a3 100644
--- a/Lib/test/test_gzip.py
+++ b/Lib/test/test_gzip.py
@@ -265,6 +265,26 @@ class TestGzip(unittest.TestCase):
d = f.read()
self.assertEqual(d, data1 * 50, "Incorrect data in file")
+ # Testing compress/decompress shortcut functions
+
+ def test_compress(self):
+ for data in [data1, data2]:
+ for args in [(), (1,), (6,), (9,)]:
+ datac = gzip.compress(data, *args)
+ self.assertEqual(type(datac), bytes)
+ with gzip.GzipFile(fileobj=io.BytesIO(datac), mode="rb") as f:
+ self.assertEqual(f.read(), data)
+
+ def test_decompress(self):
+ for data in (data1, data2):
+ buf = io.BytesIO()
+ with gzip.GzipFile(fileobj=buf, mode="wb") as f:
+ f.write(data)
+ self.assertEqual(gzip.decompress(buf.getvalue()), data)
+ # Roundtrip with compress
+ datac = gzip.compress(data)
+ self.assertEqual(gzip.decompress(datac), data)
+
def test_main(verbose=None):
support.run_unittest(TestGzip)
diff --git a/Misc/ACKS b/Misc/ACKS
index 26feba34e9..45cd1b70cd 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -634,6 +634,7 @@ Neale Pickett
Jim St. Pierre
Dan Pierson
Martijn Pieters
+Anand B. Pillai
François Pinard
Zach Pincus
Michael Piotrowski
diff --git a/Misc/NEWS b/Misc/NEWS
index 42a04f7c59..4e11922867 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -95,6 +95,9 @@ Extensions
Library
-------
+- Issue #3488: Provide convenient shorthand functions ``gzip.compress``
+ and ``gzip.decompress``. Original patch by Anand B. Pillai.
+
- Issue #8807: poplib.POP3_SSL class now accepts a context parameter, which is a
ssl.SSLContext object allowing bundling SSL configuration options,
certificates and private keys into a single (potentially long-lived)