Skip to content

Commit 2611896

Browse files
committed
Issue #21906: Make Tools/scripts/md5sum.py work in Python 3.
Patch by Zachary Ware.
1 parent 222020d commit 2611896

File tree

3 files changed

+77
-13
lines changed

3 files changed

+77
-13
lines changed

Lib/test/test_tools.py

Lines changed: 67 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
import tempfile
1717
import textwrap
1818
from test import support
19-
from test.script_helper import assert_python_ok, temp_dir
19+
from test.script_helper import assert_python_ok, assert_python_failure
2020

2121
if not sysconfig.is_python_build():
2222
# XXX some installers do contain the tools, should we detect that
@@ -61,7 +61,7 @@ def lstriplines(self, data):
6161

6262
def test_selftest(self):
6363
self.maxDiff = None
64-
with temp_dir() as directory:
64+
with support.temp_dir() as directory:
6565
data_path = os.path.join(directory, '_test.py')
6666
with open(self.script) as f:
6767
closed = f.read()
@@ -367,7 +367,7 @@ class TestSundryScripts(unittest.TestCase):
367367
# added for a script it should be added to the whitelist below.
368368

369369
# scripts that have independent tests.
370-
whitelist = ['reindent.py', 'pdeps.py', 'gprof2html']
370+
whitelist = ['reindent.py', 'pdeps.py', 'gprof2html', 'md5sum.py']
371371
# scripts that can't be imported without running
372372
blacklist = ['make_ctype.py']
373373
# scripts that use windows-only modules
@@ -450,16 +450,74 @@ def test_gprof(self):
450450
self.assertTrue(wmock.open.called)
451451

452452

453+
class MD5SumTests(unittest.TestCase):
454+
455+
@classmethod
456+
def setUpClass(cls):
457+
cls.script = os.path.join(scriptsdir, 'md5sum.py')
458+
os.mkdir(support.TESTFN)
459+
cls.fodder = os.path.join(support.TESTFN, 'md5sum.fodder')
460+
with open(cls.fodder, 'wb') as f:
461+
f.write(b'md5sum\r\ntest file\r\n')
462+
cls.fodder_md5 = b'd38dae2eb1ab346a292ef6850f9e1a0d'
463+
cls.fodder_textmode_md5 = b'a8b07894e2ca3f2a4c3094065fa6e0a5'
464+
465+
@classmethod
466+
def tearDownClass(cls):
467+
support.rmtree(support.TESTFN)
468+
469+
def test_noargs(self):
470+
rc, out, err = assert_python_ok(self.script)
471+
self.assertEqual(rc, 0)
472+
self.assertTrue(
473+
out.startswith(b'd41d8cd98f00b204e9800998ecf8427e <stdin>'))
474+
self.assertFalse(err)
475+
476+
def test_checksum_fodder(self):
477+
rc, out, err = assert_python_ok(self.script, self.fodder)
478+
self.assertEqual(rc, 0)
479+
self.assertTrue(out.startswith(self.fodder_md5))
480+
for part in self.fodder.split(os.path.sep):
481+
self.assertIn(part.encode(), out)
482+
self.assertFalse(err)
483+
484+
def test_dash_l(self):
485+
rc, out, err = assert_python_ok(self.script, '-l', self.fodder)
486+
self.assertEqual(rc, 0)
487+
self.assertIn(self.fodder_md5, out)
488+
parts = self.fodder.split(os.path.sep)
489+
self.assertIn(parts[-1].encode(), out)
490+
self.assertNotIn(parts[-2].encode(), out)
491+
492+
def test_dash_t(self):
493+
rc, out, err = assert_python_ok(self.script, '-t', self.fodder)
494+
self.assertEqual(rc, 0)
495+
self.assertTrue(out.startswith(self.fodder_textmode_md5))
496+
self.assertNotIn(self.fodder_md5, out)
497+
498+
def test_dash_s(self):
499+
rc, out, err = assert_python_ok(self.script, '-s', '512', self.fodder)
500+
self.assertEqual(rc, 0)
501+
self.assertIn(self.fodder_md5, out)
502+
503+
def test_multiple_files(self):
504+
rc, out, err = assert_python_ok(self.script, self.fodder, self.fodder)
505+
self.assertEqual(rc, 0)
506+
lines = out.splitlines()
507+
self.assertEqual(len(lines), 2)
508+
self.assertEqual(*lines)
509+
510+
def test_usage(self):
511+
rc, out, err = assert_python_failure(self.script, '-h')
512+
self.assertEqual(rc, 2)
513+
self.assertEqual(out, b'')
514+
self.assertGreater(err, b'')
515+
516+
453517
# Run the tests in Tools/parser/test_unparse.py
454518
with support.DirsOnSysPath(os.path.join(basepath, 'parser')):
455519
from test_unparse import UnparseTestCase
456520
from test_unparse import DirectoryTestCase
457521

458-
459-
def test_main():
460-
support.run_unittest(*[obj for obj in globals().values()
461-
if isinstance(obj, type)])
462-
463-
464522
if __name__ == '__main__':
465523
unittest.main()

Misc/NEWS

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
+++++++++++
1+
+++++++++++
22
Python News
33
+++++++++++
44

@@ -227,6 +227,9 @@ Windows
227227
Tools/Demos
228228
-----------
229229

230+
- Issue #21906: Make Tools/scripts/md5sum.py work in Python 3.
231+
Patch by Zachary Ware.
232+
230233
- Issue #21629: Fix Argument Clinic's "--converters" feature.
231234

232235

Tools/scripts/md5sum.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,23 @@
99
rmode = 'rb'
1010

1111
usage = """
12-
usage: sum5 [-b] [-t] [-l] [-s bufsize] [file ...]
12+
usage: md5sum.py [-b] [-t] [-l] [-s bufsize] [file ...]
1313
-b : read files in binary mode (default)
1414
-t : read files in text mode (you almost certainly don't want this!)
1515
-l : print last pathname component only
1616
-s bufsize: read buffer size (default %d)
1717
file ... : files to sum; '-' or no files means stdin
1818
""" % bufsize
1919

20+
import io
2021
import sys
2122
import os
2223
import getopt
2324
from hashlib import md5
2425

2526
def sum(*files):
2627
sts = 0
27-
if files and isinstance(files[-1], file):
28+
if files and isinstance(files[-1], io.IOBase):
2829
out, files = files[-1], files[:-1]
2930
else:
3031
out = sys.stdout
@@ -53,12 +54,14 @@ def printsum(filename, out=sys.stdout):
5354
return sts
5455

5556
def printsumfp(fp, filename, out=sys.stdout):
56-
m = md5.new()
57+
m = md5()
5758
try:
5859
while 1:
5960
data = fp.read(bufsize)
6061
if not data:
6162
break
63+
if isinstance(data, str):
64+
data = data.encode(fp.encoding)
6265
m.update(data)
6366
except IOError as msg:
6467
sys.stderr.write('%s: I/O error: %s\n' % (filename, msg))

0 commit comments

Comments
 (0)