Kaydet (Commit) 8c933105 authored tarafından Serhiy Storchaka's avatar Serhiy Storchaka

Issue #28115: Command-line interface of the zipfile module now uses argparse.

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