Skip to content

Commit 3e28eed

Browse files
matrixiseJulienPalard
authored andcommitted
bpo-34969: Add --fast, --best on the gzip CLI (GH-9833)
1 parent fe62d87 commit 3e28eed

File tree

4 files changed

+63
-14
lines changed

4 files changed

+63
-14
lines changed

Doc/library/gzip.rst

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -222,25 +222,26 @@ Once executed the :mod:`gzip` module keeps the input file(s).
222222
.. versionchanged:: 3.8
223223

224224
Add a new command line interface with a usage.
225+
By default, when you will execute the CLI, the default compression level is 6.
225226

226227
Command line options
227228
^^^^^^^^^^^^^^^^^^^^
228229

229230
.. cmdoption:: file
230231

231-
.. code-block:: shell-session
232+
If *file* is not specified, read from :attr:`sys.stdin`.
232233

233-
$ python -m gzip file
234+
.. cmdoption:: --fast
234235

235-
If *file* is not specified, read from :attr:`sys.stdin`.
236+
Indicates the fastest compression method (less compression).
236237

237-
.. cmdoption:: -d, --decompress
238+
.. cmdoption:: --best
238239

239-
Decompress the given file
240+
Indicates the slowest compression method (best compression).
240241

241-
.. code-block:: shell-session
242+
.. cmdoption:: -d, --decompress
242243

243-
$ python -m gzip -d file.gz
244+
Decompress the given file.
244245

245246
.. cmdoption:: -h, --help
246247

Lib/gzip.py

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@
1717

1818
READ, WRITE = 1, 2
1919

20-
def open(filename, mode="rb", compresslevel=9,
20+
_COMPRESS_LEVEL_FAST = 1
21+
_COMPRESS_LEVEL_TRADEOFF = 6
22+
_COMPRESS_LEVEL_BEST = 9
23+
24+
25+
def open(filename, mode="rb", compresslevel=_COMPRESS_LEVEL_BEST,
2126
encoding=None, errors=None, newline=None):
2227
"""Open a gzip-compressed file in binary or text mode.
2328
@@ -121,7 +126,7 @@ class GzipFile(_compression.BaseStream):
121126
myfileobj = None
122127

123128
def __init__(self, filename=None, mode=None,
124-
compresslevel=9, fileobj=None, mtime=None):
129+
compresslevel=_COMPRESS_LEVEL_BEST, fileobj=None, mtime=None):
125130
"""Constructor for the GzipFile class.
126131
127132
At least one of fileobj and filename must be given a
@@ -515,7 +520,7 @@ def _rewind(self):
515520
super()._rewind()
516521
self._new_member = True
517522

518-
def compress(data, compresslevel=9):
523+
def compress(data, compresslevel=_COMPRESS_LEVEL_BEST):
519524
"""Compress data in one shot and return the compressed string.
520525
Optional argument is the compression level, in range of 0-9.
521526
"""
@@ -537,10 +542,21 @@ def main():
537542
parser = ArgumentParser(description=
538543
"A simple command line interface for the gzip module: act like gzip, "
539544
"but do not delete the input file.")
540-
parser.add_argument("-d", "--decompress", action="store_true",
545+
group = parser.add_mutually_exclusive_group()
546+
group.add_argument('--fast', action='store_true', help='compress faster')
547+
group.add_argument('--best', action='store_true', help='compress better')
548+
group.add_argument("-d", "--decompress", action="store_true",
541549
help="act like gunzip instead of gzip")
550+
542551
parser.add_argument("args", nargs="*", default=["-"], metavar='file')
543552
args = parser.parse_args()
553+
554+
compresslevel = _COMPRESS_LEVEL_TRADEOFF
555+
if args.fast:
556+
compresslevel = _COMPRESS_LEVEL_FAST
557+
elif args.best:
558+
compresslevel = _COMPRESS_LEVEL_BEST
559+
544560
for arg in args.args:
545561
if args.decompress:
546562
if arg == "-":
@@ -555,7 +571,8 @@ def main():
555571
else:
556572
if arg == "-":
557573
f = sys.stdin.buffer
558-
g = GzipFile(filename="", mode="wb", fileobj=sys.stdout.buffer)
574+
g = GzipFile(filename="", mode="wb", fileobj=sys.stdout.buffer,
575+
compresslevel=compresslevel)
559576
else:
560577
f = builtins.open(arg, "rb")
561578
g = open(arg + ".gz", "wb")

Lib/test/test_gzip.py

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from subprocess import PIPE, Popen
1313
from test import support
1414
from test.support import _4G, bigmemtest
15-
from test.support.script_helper import assert_python_ok
15+
from test.support.script_helper import assert_python_ok, assert_python_failure
1616

1717
gzip = support.import_module('gzip')
1818

@@ -746,10 +746,38 @@ def test_compress_infile_outfile(self):
746746
rc, out, err = assert_python_ok('-m', 'gzip', local_testgzip)
747747

748748
self.assertTrue(os.path.exists(gzipname))
749-
self.assertEqual(rc, 0)
750749
self.assertEqual(out, b'')
751750
self.assertEqual(err, b'')
752751

752+
@create_and_remove_directory(TEMPDIR)
753+
def test_compress_infile_outfile(self):
754+
for compress_level in ('--fast', '--best'):
755+
with self.subTest(compress_level=compress_level):
756+
local_testgzip = os.path.join(TEMPDIR, 'testgzip')
757+
gzipname = local_testgzip + '.gz'
758+
self.assertFalse(os.path.exists(gzipname))
759+
760+
with open(local_testgzip, 'wb') as fp:
761+
fp.write(self.data)
762+
763+
rc, out, err = assert_python_ok('-m', 'gzip', compress_level, local_testgzip)
764+
765+
self.assertTrue(os.path.exists(gzipname))
766+
self.assertEqual(out, b'')
767+
self.assertEqual(err, b'')
768+
os.remove(gzipname)
769+
self.assertFalse(os.path.exists(gzipname))
770+
771+
def test_compress_fast_best_are_exclusive(self):
772+
rc, out, err = assert_python_failure('-m', 'gzip', '--fast', '--best')
773+
self.assertIn(b"error: argument --best: not allowed with argument --fast", err)
774+
self.assertEqual(out, b'')
775+
776+
def test_decompress_cannot_have_flags_compression(self):
777+
rc, out, err = assert_python_failure('-m', 'gzip', '--fast', '-d')
778+
self.assertIn(b'error: argument -d/--decompress: not allowed with argument --fast', err)
779+
self.assertEqual(out, b'')
780+
753781

754782
def test_main(verbose=None):
755783
support.run_unittest(TestGzip, TestOpen, TestCommandLine)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
gzip: Add --fast, --best on the gzip CLI, these parameters will be used for the
2+
fast compression method (quick) or the best method compress (slower, but smaller
3+
file). Also, change the default compression level to 6 (tradeoff).

0 commit comments

Comments
 (0)