From 25bce3d42166b845a0d5f69322ef84765a80cedc Mon Sep 17 00:00:00 2001 From: Brad Solomon Date: Sun, 12 May 2019 17:11:42 -0400 Subject: [PATCH 1/9] Docs: Add bz2 usage examples - Adds an "Examples of usage" section inspired by the one found in the gzip docs - Corrects the descriptions for ``compresslevel`` and ``data``: - ``compresslevel`` must be an `int`, not any number. For instance, passing a float will raise ``TypeError`` - Notes that `data` must be bytes-like --- Doc/library/bz2.rst | 82 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 77 insertions(+), 5 deletions(-) diff --git a/Doc/library/bz2.rst b/Doc/library/bz2.rst index 946cc67dd301fc..b5630dea7f4cb0 100644 --- a/Doc/library/bz2.rst +++ b/Doc/library/bz2.rst @@ -83,7 +83,7 @@ All of the classes in this module may safely be accessed from multiple threads. The *buffering* argument is ignored. Its use is deprecated since Python 3.0. - If *mode* is ``'w'`` or ``'a'``, *compresslevel* can be a number between + If *mode* is ``'w'`` or ``'a'``, *compresslevel* can be an integer between ``1`` and ``9`` specifying the level of compression: ``1`` produces the least compression, and ``9`` (default) produces the most compression. @@ -148,7 +148,7 @@ Incremental (de)compression incrementally. For one-shot compression, use the :func:`compress` function instead. - *compresslevel*, if given, must be a number between ``1`` and ``9``. The + *compresslevel*, if given, must be an integer between ``1`` and ``9``. The default is ``9``. .. method:: compress(data) @@ -234,9 +234,9 @@ One-shot (de)compression .. function:: compress(data, compresslevel=9) - Compress *data*. + Compress *data*, a :term:`bytes-like object `. - *compresslevel*, if given, must be a number between ``1`` and ``9``. The + *compresslevel*, if given, must be an integer between ``1`` and ``9``. The default is ``9``. For incremental compression, use a :class:`BZ2Compressor` instead. @@ -244,7 +244,7 @@ One-shot (de)compression .. function:: decompress(data) - Decompress *data*. + Decompress *data*, a :term:`bytes-like object `. If *data* is the concatenation of multiple compressed streams, decompress all of the streams. @@ -254,3 +254,75 @@ One-shot (de)compression .. versionchanged:: 3.3 Support for multi-stream inputs was added. +.. _bz2-usage-examples: + +Examples of usage +----------------- + +Below are some examples of typical usage of the :mod:`bz2` module. + +Using :func:`compress` and :func:`decompress` to demonstrate round-trip compression: + + >>> import bz2 + + >>> data = b"""\ + ... Donec rhoncus quis sapien sit amet molestie. Fusce scelerisque vel augue + ... nec ullamcorper. Nam rutrum pretium placerat. Aliquam vel tristique lorem, + ... sit amet cursus ante. In interdum laoreet mi, sit amet ultrices purus + ... pulvinar a. Nam gravida euismod magna, non varius justo tincidunt feugiat. + ... Aliquam pharetra lacus non risus vehicula rutrum. Maecenas aliquam leo + ... felis. Pellentesque semper nunc sit amet nibh ullamcorper, ac elementum + ... dolor luctus. Curabitur lacinia mi ornare consectetur vestibulum. """ + + >>> c = bz2.compress(data) + >>> len(data) / len(c) # Data compression ratio + 1.5212121212121212 + + >>> d = bz2.decompress(c) + >>> data == d # Check equality to original object after round-trip + True + +Using :class:`BZ2Compressor` for incremental compression: + + >>> import bz2 + >>> import os + >>> + >>> def gen_data(chunks=10, chunksize=1000): + ... """Yield incremental blocks of ``chunksize`` bytes.""" + ... for _ in range(chunks): + ... yield os.urandom(chunksize) + ... + >>> comp = bz2.BZ2Compressor() + >>> out = b"" + >>> for chunk in gen_data(): + ... # Provide data to the compressor object + ... out = out + comp.compress(chunk) + ... + >>> # Finish the compression process. Call this once you have + >>> # finished providing data to the compressor. + >>> out = out + comp.flush() + +Writing and reading a bzip2-compressed file in binary mode: + + >>> import bz2 + + >>> data = b"""\ + ... Donec rhoncus quis sapien sit amet molestie. Fusce scelerisque vel augue + ... nec ullamcorper. Nam rutrum pretium placerat. Aliquam vel tristique lorem, + ... sit amet cursus ante. In interdum laoreet mi, sit amet ultrices purus + ... pulvinar a. Nam gravida euismod magna, non varius justo tincidunt feugiat. + ... Aliquam pharetra lacus non risus vehicula rutrum. Maecenas aliquam leo + ... felis. Pellentesque semper nunc sit amet nibh ullamcorper, ac elementum + ... dolor luctus. Curabitur lacinia mi ornare consectetur vestibulum. """ + + >>> with bz2.open("myfile.bz2", "wb") as f: + ... # Write compressed data to file + ... f.write(data) + ... 502 + + >>> with bz2.open("myfile.bz2", "rb") as f: + ... # Decompress data from file + ... content = f.read() + + >>> content == data # Check equality to original object after round-trip + True From de7cc5c27d8754773b8a0b04e8c3044431b014e7 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Sun, 12 May 2019 18:41:55 -0700 Subject: [PATCH 2/9] remove wrongly placed 502 return value --- Doc/library/bz2.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/Doc/library/bz2.rst b/Doc/library/bz2.rst index b5630dea7f4cb0..08a64d27dfafa4 100644 --- a/Doc/library/bz2.rst +++ b/Doc/library/bz2.rst @@ -318,7 +318,6 @@ Writing and reading a bzip2-compressed file in binary mode: >>> with bz2.open("myfile.bz2", "wb") as f: ... # Write compressed data to file ... f.write(data) - ... 502 >>> with bz2.open("myfile.bz2", "rb") as f: ... # Decompress data from file From 77514c8047a5c490fc4c6f68d6d48cf1eabaa853 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Sun, 12 May 2019 18:49:49 -0700 Subject: [PATCH 3/9] fix for the previous doctest "fix" :) --- Doc/library/bz2.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/bz2.rst b/Doc/library/bz2.rst index 08a64d27dfafa4..19f7d27e0818b1 100644 --- a/Doc/library/bz2.rst +++ b/Doc/library/bz2.rst @@ -317,7 +317,7 @@ Writing and reading a bzip2-compressed file in binary mode: >>> with bz2.open("myfile.bz2", "wb") as f: ... # Write compressed data to file - ... f.write(data) + ... bytes_written = f.write(data) >>> with bz2.open("myfile.bz2", "rb") as f: ... # Decompress data from file From 83b5a7033c1741c63b59c46fc88ae70927a8256f Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Sun, 12 May 2019 18:50:49 -0700 Subject: [PATCH 4/9] call the unused value "unused" to avoid confusion. --- Doc/library/bz2.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/bz2.rst b/Doc/library/bz2.rst index 19f7d27e0818b1..4f00c4d8c9b340 100644 --- a/Doc/library/bz2.rst +++ b/Doc/library/bz2.rst @@ -317,7 +317,7 @@ Writing and reading a bzip2-compressed file in binary mode: >>> with bz2.open("myfile.bz2", "wb") as f: ... # Write compressed data to file - ... bytes_written = f.write(data) + ... unused = f.write(data) >>> with bz2.open("myfile.bz2", "rb") as f: ... # Decompress data from file From 0ece31c4839edd0da806afb462712d26d4e23435 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Sun, 12 May 2019 18:54:33 -0700 Subject: [PATCH 5/9] remove trailing whitespace. --- Doc/library/bz2.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/bz2.rst b/Doc/library/bz2.rst index 4f00c4d8c9b340..1569950aa26b78 100644 --- a/Doc/library/bz2.rst +++ b/Doc/library/bz2.rst @@ -286,18 +286,18 @@ Using :class:`BZ2Compressor` for incremental compression: >>> import bz2 >>> import os - >>> + >>> >>> def gen_data(chunks=10, chunksize=1000): ... """Yield incremental blocks of ``chunksize`` bytes.""" ... for _ in range(chunks): ... yield os.urandom(chunksize) - ... + ... >>> comp = bz2.BZ2Compressor() >>> out = b"" >>> for chunk in gen_data(): ... # Provide data to the compressor object ... out = out + comp.compress(chunk) - ... + ... >>> # Finish the compression process. Call this once you have >>> # finished providing data to the compressor. >>> out = out + comp.flush() From cf6f7f21ba3498d8fcb57dc2978827a06ca52689 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Sun, 12 May 2019 19:08:32 -0700 Subject: [PATCH 6/9] remove `` from within docstring in example code. --- Doc/library/bz2.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/bz2.rst b/Doc/library/bz2.rst index 1569950aa26b78..0c42c9640bd06c 100644 --- a/Doc/library/bz2.rst +++ b/Doc/library/bz2.rst @@ -288,7 +288,7 @@ Using :class:`BZ2Compressor` for incremental compression: >>> import os >>> >>> def gen_data(chunks=10, chunksize=1000): - ... """Yield incremental blocks of ``chunksize`` bytes.""" + ... """Yield incremental blocks of chunksize bytes.""" ... for _ in range(chunks): ... yield os.urandom(chunksize) ... From 8d5a83e27220f795b5bbff5d5a897670d56df22d Mon Sep 17 00:00:00 2001 From: Brad Solomon Date: Sun, 12 May 2019 22:13:19 -0400 Subject: [PATCH 7/9] Remove trailing space from bytestring This modifies the compression ratio by a hair. --- Doc/library/bz2.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/bz2.rst b/Doc/library/bz2.rst index 0c42c9640bd06c..5b401596840cfd 100644 --- a/Doc/library/bz2.rst +++ b/Doc/library/bz2.rst @@ -272,11 +272,11 @@ Using :func:`compress` and :func:`decompress` to demonstrate round-trip compress ... pulvinar a. Nam gravida euismod magna, non varius justo tincidunt feugiat. ... Aliquam pharetra lacus non risus vehicula rutrum. Maecenas aliquam leo ... felis. Pellentesque semper nunc sit amet nibh ullamcorper, ac elementum - ... dolor luctus. Curabitur lacinia mi ornare consectetur vestibulum. """ + ... dolor luctus. Curabitur lacinia mi ornare consectetur vestibulum.""" >>> c = bz2.compress(data) >>> len(data) / len(c) # Data compression ratio - 1.5212121212121212 + 1.513595166163142 >>> d = bz2.decompress(c) >>> data == d # Check equality to original object after round-trip @@ -313,7 +313,7 @@ Writing and reading a bzip2-compressed file in binary mode: ... pulvinar a. Nam gravida euismod magna, non varius justo tincidunt feugiat. ... Aliquam pharetra lacus non risus vehicula rutrum. Maecenas aliquam leo ... felis. Pellentesque semper nunc sit amet nibh ullamcorper, ac elementum - ... dolor luctus. Curabitur lacinia mi ornare consectetur vestibulum. """ + ... dolor luctus. Curabitur lacinia mi ornare consectetur vestibulum.""" >>> with bz2.open("myfile.bz2", "wb") as f: ... # Write compressed data to file From c9475e92fbab086dd774553c06a458a87ded9517 Mon Sep 17 00:00:00 2001 From: Brad Solomon Date: Sun, 12 May 2019 22:28:51 -0400 Subject: [PATCH 8/9] Use 'nonrandom' data in compression example Compressing random data (low compression ratio) is a less realistic and less useful example. --- Doc/library/bz2.rst | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Doc/library/bz2.rst b/Doc/library/bz2.rst index 5b401596840cfd..a1179fb8f919b4 100644 --- a/Doc/library/bz2.rst +++ b/Doc/library/bz2.rst @@ -285,12 +285,11 @@ Using :func:`compress` and :func:`decompress` to demonstrate round-trip compress Using :class:`BZ2Compressor` for incremental compression: >>> import bz2 - >>> import os >>> >>> def gen_data(chunks=10, chunksize=1000): ... """Yield incremental blocks of chunksize bytes.""" ... for _ in range(chunks): - ... yield os.urandom(chunksize) + ... yield b"z" * chunksize ... >>> comp = bz2.BZ2Compressor() >>> out = b"" @@ -302,6 +301,10 @@ Using :class:`BZ2Compressor` for incremental compression: >>> # finished providing data to the compressor. >>> out = out + comp.flush() +The example above uses a very "nonrandom" stream of data +(a stream of `b"z"` chunks). Random data tends to compress poorly, +while ordered, repetitive data usually yields a high compression ratio. + Writing and reading a bzip2-compressed file in binary mode: >>> import bz2 From 1a10b20f54a083480117c4ffbfb22d99d85ecbf9 Mon Sep 17 00:00:00 2001 From: Brad Solomon Date: Sun, 12 May 2019 22:29:50 -0400 Subject: [PATCH 9/9] Remove empty prompt Per https://devguide.python.org/documenting/. --- Doc/library/bz2.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/bz2.rst b/Doc/library/bz2.rst index a1179fb8f919b4..277de601cb7b6f 100644 --- a/Doc/library/bz2.rst +++ b/Doc/library/bz2.rst @@ -285,7 +285,7 @@ Using :func:`compress` and :func:`decompress` to demonstrate round-trip compress Using :class:`BZ2Compressor` for incremental compression: >>> import bz2 - >>> + >>> def gen_data(chunks=10, chunksize=1000): ... """Yield incremental blocks of chunksize bytes.""" ... for _ in range(chunks):