summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_hashlib.py
diff options
context:
space:
mode:
authorChristian Heimes <christian@python.org>2022-03-22 09:37:00 (GMT)
committerGitHub <noreply@github.com>2022-03-22 09:37:00 (GMT)
commit4f97d64c831c94660ceb01f34d51fa236ad968b0 (patch)
treead8b4e06cddb3112553a98679f3a6b4be6e34606 /Lib/test/test_hashlib.py
parent3751b6b030b4a3b88959b4f3c4ef2e58d325e497 (diff)
downloadcpython-4f97d64c831c94660ceb01f34d51fa236ad968b0.zip
cpython-4f97d64c831c94660ceb01f34d51fa236ad968b0.tar.gz
cpython-4f97d64c831c94660ceb01f34d51fa236ad968b0.tar.bz2
bpo-45150: Add hashlib.file_digest() for efficient file hashing (GH-31930)
Diffstat (limited to 'Lib/test/test_hashlib.py')
-rw-r--r--Lib/test/test_hashlib.py54
1 files changed, 54 insertions, 0 deletions
diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py
index ea31f8b..daf6e38 100644
--- a/Lib/test/test_hashlib.py
+++ b/Lib/test/test_hashlib.py
@@ -10,6 +10,7 @@ import array
from binascii import unhexlify
import hashlib
import importlib
+import io
import itertools
import os
import sys
@@ -20,6 +21,7 @@ import warnings
from test import support
from test.support import _4G, bigmemtest
from test.support.import_helper import import_fresh_module
+from test.support import os_helper
from test.support import threading_helper
from test.support import warnings_helper
from http.client import HTTPException
@@ -371,6 +373,31 @@ class HashLibTestCase(unittest.TestCase):
if not shake:
self.assertEqual(len(digest), m.digest_size)
+ if not shake and kwargs.get("key") is None:
+ # skip shake and blake2 extended parameter tests
+ self.check_file_digest(name, data, hexdigest)
+
+ def check_file_digest(self, name, data, hexdigest):
+ hexdigest = hexdigest.lower()
+ digests = [name]
+ digests.extend(self.constructors_to_test[name])
+
+ with open(os_helper.TESTFN, "wb") as f:
+ f.write(data)
+
+ try:
+ for digest in digests:
+ buf = io.BytesIO(data)
+ buf.seek(0)
+ self.assertEqual(
+ hashlib.file_digest(buf, digest).hexdigest(), hexdigest
+ )
+ with open(os_helper.TESTFN, "rb") as f:
+ digestobj = hashlib.file_digest(f, digest)
+ self.assertEqual(digestobj.hexdigest(), hexdigest)
+ finally:
+ os.unlink(os_helper.TESTFN)
+
def check_no_unicode(self, algorithm_name):
# Unicode objects are not allowed as input.
constructors = self.constructors_to_test[algorithm_name]
@@ -1117,6 +1144,33 @@ class KDFTests(unittest.TestCase):
self.assertNotIn("blake2b512", hashlib.algorithms_available)
self.assertNotIn("sha3-512", hashlib.algorithms_available)
+ def test_file_digest(self):
+ data = b'a' * 65536
+ d1 = hashlib.sha256()
+ self.addCleanup(os.unlink, os_helper.TESTFN)
+ with open(os_helper.TESTFN, "wb") as f:
+ for _ in range(10):
+ d1.update(data)
+ f.write(data)
+
+ with open(os_helper.TESTFN, "rb") as f:
+ d2 = hashlib.file_digest(f, hashlib.sha256)
+
+ self.assertEqual(d1.hexdigest(), d2.hexdigest())
+ self.assertEqual(d1.name, d2.name)
+ self.assertIs(type(d1), type(d2))
+
+ with self.assertRaises(ValueError):
+ hashlib.file_digest(None, "sha256")
+
+ with self.assertRaises(ValueError):
+ with open(os_helper.TESTFN, "r") as f:
+ hashlib.file_digest(f, "sha256")
+
+ with self.assertRaises(ValueError):
+ with open(os_helper.TESTFN, "wb") as f:
+ hashlib.file_digest(f, "sha256")
+
if __name__ == "__main__":
unittest.main()