bpo-40275: Move requires_hashdigest() to test.support.hashlib_helper (GH-19716)

Add a new test.support.hashlib_helper submodule.
diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py
index 69ee63b..ce60156 100644
--- a/Lib/test/test_imaplib.py
+++ b/Lib/test/test_imaplib.py
@@ -11,8 +11,8 @@
 import socket
 
 from test.support import (reap_threads, verbose, transient_internet,
-                          run_with_tz, run_with_locale, cpython_only,
-                          requires_hashdigest)
+                          run_with_tz, run_with_locale, cpython_only)
+from test.support import hashlib_helper
 import unittest
 from unittest import mock
 from datetime import datetime, timezone, timedelta
@@ -385,7 +385,7 @@
         self.assertEqual(code, 'OK')
         self.assertEqual(server.response, b'ZmFrZQ==\r\n')  # b64 encoded 'fake'
 
-    @requires_hashdigest('md5')
+    @hashlib_helper.requires_hashdigest('md5')
     def test_login_cram_md5_bytes(self):
         class AuthHandler(SimpleIMAPHandler):
             capabilities = 'LOGINDISABLED AUTH=CRAM-MD5'
@@ -403,7 +403,7 @@
         ret, _ = client.login_cram_md5("tim", b"tanstaaftanstaaf")
         self.assertEqual(ret, "OK")
 
-    @requires_hashdigest('md5')
+    @hashlib_helper.requires_hashdigest('md5')
     def test_login_cram_md5_plain_text(self):
         class AuthHandler(SimpleIMAPHandler):
             capabilities = 'LOGINDISABLED AUTH=CRAM-MD5'
@@ -849,7 +849,7 @@
                              b'ZmFrZQ==\r\n')  # b64 encoded 'fake'
 
     @reap_threads
-    @requires_hashdigest('md5')
+    @hashlib_helper.requires_hashdigest('md5')
     def test_login_cram_md5(self):
 
         class AuthHandler(SimpleIMAPHandler):