[Python-checkins] cpython: Issue #28115: Command-line interface of the zipfile module now uses argparse.

serhiy.storchaka python-checkins at python.org
Sun Oct 23 08:09:19 EDT 2016


https://hg.python.org/cpython/rev/fa275e570d52
changeset:   104656:fa275e570d52
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Sun Oct 23 13:32:12 2016 +0300
summary:
  Issue #28115: Command-line interface of the zipfile module now uses argparse.
Added support of long options.

files:
  Lib/test/test_zipfile.py |  58 +++++++++++----------
  Lib/zipfile.py           |  73 +++++++++++++--------------
  Misc/NEWS                |   3 +
  3 files changed, 69 insertions(+), 65 deletions(-)


diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py
--- a/Lib/test/test_zipfile.py
+++ b/Lib/test/test_zipfile.py
@@ -2055,8 +2055,9 @@
 
     def test_test_command(self):
         zip_name = findfile('zipdir.zip')
-        out = self.zipfilecmd('-t', zip_name)
-        self.assertEqual(out.rstrip(), b'Done testing')
+        for opt in '-t', '--test':
+            out = self.zipfilecmd(opt, zip_name)
+            self.assertEqual(out.rstrip(), b'Done testing')
         zip_name = findfile('testtar.tar')
         rc, out, err = self.zipfilecmd_failure('-t', zip_name)
         self.assertEqual(out, b'')
@@ -2067,9 +2068,10 @@
         with zipfile.ZipFile(zip_name, 'r') as tf:
             tf.printdir(t)
         expected = t.getvalue().encode('ascii', 'backslashreplace')
-        out = self.zipfilecmd('-l', zip_name,
-                              PYTHONIOENCODING='ascii:backslashreplace')
-        self.assertEqual(out, expected)
+        for opt in '-l', '--list':
+            out = self.zipfilecmd(opt, zip_name,
+                                  PYTHONIOENCODING='ascii:backslashreplace')
+            self.assertEqual(out, expected)
 
     def test_create_command(self):
         self.addCleanup(unlink, TESTFN)
@@ -2081,31 +2083,33 @@
             f.write('test 2')
         files = [TESTFN, TESTFNDIR]
         namelist = [TESTFN, TESTFNDIR + '/', TESTFNDIR + '/file.txt']
-        try:
-            out = self.zipfilecmd('-c', TESTFN2, *files)
-            self.assertEqual(out, b'')
-            with zipfile.ZipFile(TESTFN2) as zf:
-                self.assertEqual(zf.namelist(), namelist)
-                self.assertEqual(zf.read(namelist[0]), b'test 1')
-                self.assertEqual(zf.read(namelist[2]), b'test 2')
-        finally:
-            unlink(TESTFN2)
+        for opt in '-c', '--create':
+            try:
+                out = self.zipfilecmd(opt, TESTFN2, *files)
+                self.assertEqual(out, b'')
+                with zipfile.ZipFile(TESTFN2) as zf:
+                    self.assertEqual(zf.namelist(), namelist)
+                    self.assertEqual(zf.read(namelist[0]), b'test 1')
+                    self.assertEqual(zf.read(namelist[2]), b'test 2')
+            finally:
+                unlink(TESTFN2)
 
     def test_extract_command(self):
         zip_name = findfile('zipdir.zip')
-        with temp_dir() as extdir:
-            out = self.zipfilecmd('-e', zip_name, extdir)
-            self.assertEqual(out, b'')
-            with zipfile.ZipFile(zip_name) as zf:
-                for zi in zf.infolist():
-                    path = os.path.join(extdir,
-                                zi.filename.replace('/', os.sep))
-                    if zi.is_dir():
-                        self.assertTrue(os.path.isdir(path))
-                    else:
-                        self.assertTrue(os.path.isfile(path))
-                        with open(path, 'rb') as f:
-                            self.assertEqual(f.read(), zf.read(zi))
+        for opt in '-e', '--extract':
+            with temp_dir() as extdir:
+                out = self.zipfilecmd(opt, zip_name, extdir)
+                self.assertEqual(out, b'')
+                with zipfile.ZipFile(zip_name) as zf:
+                    for zi in zf.infolist():
+                        path = os.path.join(extdir,
+                                    zi.filename.replace('/', os.sep))
+                        if zi.is_dir():
+                            self.assertTrue(os.path.isdir(path))
+                        else:
+                            self.assertTrue(os.path.isfile(path))
+                            with open(path, 'rb') as f:
+                                self.assertEqual(f.read(), zf.read(zi))
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/Lib/zipfile.py b/Lib/zipfile.py
--- a/Lib/zipfile.py
+++ b/Lib/zipfile.py
@@ -1950,51 +1950,45 @@
         return (fname, archivename)
 
 
-def main(args = None):
-    import textwrap
-    USAGE=textwrap.dedent("""\
-        Usage:
-            zipfile.py -l zipfile.zip        # Show listing of a zipfile
-            zipfile.py -t zipfile.zip        # Test if a zipfile is valid
-            zipfile.py -e zipfile.zip target # Extract zipfile into target dir
-            zipfile.py -c zipfile.zip src ... # Create zipfile from sources
-        """)
-    if args is None:
-        args = sys.argv[1:]
+def main(args=None):
+    import argparse
 
-    if not args or args[0] not in ('-l', '-c', '-e', '-t'):
-        print(USAGE, file=sys.stderr)
-        sys.exit(1)
+    description = 'A simple command line interface for zipfile module.'
+    parser = argparse.ArgumentParser(description=description)
+    group = parser.add_mutually_exclusive_group()
+    group.add_argument('-l', '--list', metavar='<zipfile>',
+                       help='Show listing of a zipfile')
+    group.add_argument('-e', '--extract', nargs=2,
+                       metavar=('<zipfile>', '<output_dir>'),
+                       help='Extract zipfile into target dir')
+    group.add_argument('-c', '--create', nargs='+',
+                       metavar=('<name>', '<file>'),
+                       help='Create zipfile from sources')
+    group.add_argument('-t', '--test', metavar='<zipfile>',
+                       help='Test if a zipfile is valid')
+    args = parser.parse_args(args)
 
-    if args[0] == '-l':
-        if len(args) != 2:
-            print(USAGE, file=sys.stderr)
-            sys.exit(1)
-        with ZipFile(args[1], 'r') as zf:
-            zf.printdir()
-
-    elif args[0] == '-t':
-        if len(args) != 2:
-            print(USAGE, file=sys.stderr)
-            sys.exit(1)
-        with ZipFile(args[1], 'r') as zf:
+    if args.test is not None:
+        src = args.test
+        with ZipFile(src, 'r') as zf:
             badfile = zf.testzip()
         if badfile:
             print("The following enclosed file is corrupted: {!r}".format(badfile))
         print("Done testing")
 
-    elif args[0] == '-e':
-        if len(args) != 3:
-            print(USAGE, file=sys.stderr)
-            sys.exit(1)
+    elif args.list is not None:
+        src = args.list
+        with ZipFile(src, 'r') as zf:
+            zf.printdir()
 
-        with ZipFile(args[1], 'r') as zf:
-            zf.extractall(args[2])
+    elif args.extract is not None:
+        src, curdir = args.extract
+        with ZipFile(src, 'r') as zf:
+            zf.extractall(curdir)
 
-    elif args[0] == '-c':
-        if len(args) < 3:
-            print(USAGE, file=sys.stderr)
-            sys.exit(1)
+    elif args.create is not None:
+        zip_name = args.create.pop(0)
+        files = args.create
 
         def addToZip(zf, path, zippath):
             if os.path.isfile(path):
@@ -2007,8 +2001,8 @@
                              os.path.join(path, nm), os.path.join(zippath, nm))
             # else: ignore
 
-        with ZipFile(args[1], 'w') as zf:
-            for path in args[2:]:
+        with ZipFile(zip_name, 'w') as zf:
+            for path in files:
                 zippath = os.path.basename(path)
                 if not zippath:
                     zippath = os.path.basename(os.path.dirname(path))
@@ -2016,5 +2010,8 @@
                     zippath = ''
                 addToZip(zf, path, zippath)
 
+    else:
+        parser.exit(2, parser.format_usage())
+
 if __name__ == "__main__":
     main()
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -97,6 +97,9 @@
 Library
 -------
 
+- Issue #28115: Command-line interface of the zipfile module now uses argparse.
+  Added support of long options.
+
 - Issue #18219: Optimize csv.DictWriter for large number of columns.
   Patch by Mariatta Wijaya.
 

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list