bpo-34022: Stop forcing of hash-based invalidation with SOURCE_DATE_EPOCH (GH-9607)

Unconditional forcing of ``CHECKED_HASH`` invalidation was introduced in
3.7.0 in bpo-29708.  The change is bad, as it unconditionally overrides
*invalidation_mode*, even if it was passed as an explicit argument to
``py_compile.compile()`` or ``compileall``.  An environment variable
should *never* override an explicit argument to a library function.
That change leads to multiple test failures if the ``SOURCE_DATE_EPOCH``
environment variable is set.

This changes ``py_compile.compile()`` to only look at
``SOURCE_DATE_EPOCH`` if no explicit *invalidation_mode* was specified.
I also made various relevant tests run with explicit control over the
value of ``SOURCE_DATE_EPOCH``.

While looking at this, I noticed that ``zipimport`` does not work
with hash-based .pycs _at all_, though I left the fixes for
subsequent commits.
diff --git a/Lib/compileall.py b/Lib/compileall.py
index 7259212..7be23a6 100644
--- a/Lib/compileall.py
+++ b/Lib/compileall.py
@@ -53,7 +53,7 @@
 
 def compile_dir(dir, maxlevels=10, ddir=None, force=False, rx=None,
                 quiet=0, legacy=False, optimize=-1, workers=1,
-                invalidation_mode=py_compile.PycInvalidationMode.TIMESTAMP):
+                invalidation_mode=None):
     """Byte-compile all modules in the given directory tree.
 
     Arguments (only dir is required):
@@ -96,7 +96,7 @@
 
 def compile_file(fullname, ddir=None, force=False, rx=None, quiet=0,
                  legacy=False, optimize=-1,
-                 invalidation_mode=py_compile.PycInvalidationMode.TIMESTAMP):
+                 invalidation_mode=None):
     """Byte-compile one file.
 
     Arguments (only fullname is required):
@@ -182,7 +182,7 @@
 
 def compile_path(skip_curdir=1, maxlevels=0, force=False, quiet=0,
                  legacy=False, optimize=-1,
-                 invalidation_mode=py_compile.PycInvalidationMode.TIMESTAMP):
+                 invalidation_mode=None):
     """Byte-compile all module on sys.path.
 
     Arguments (all optional):
@@ -255,9 +255,12 @@
                         type=int, help='Run compileall concurrently')
     invalidation_modes = [mode.name.lower().replace('_', '-')
                           for mode in py_compile.PycInvalidationMode]
-    parser.add_argument('--invalidation-mode', default='timestamp',
+    parser.add_argument('--invalidation-mode',
                         choices=sorted(invalidation_modes),
-                        help='How the pycs will be invalidated at runtime')
+                        help=('set .pyc invalidation mode; defaults to '
+                              '"checked-hash" if the SOURCE_DATE_EPOCH '
+                              'environment variable is set, and '
+                              '"timestamp" otherwise.'))
 
     args = parser.parse_args()
     compile_dests = args.compile_dest
@@ -286,8 +289,11 @@
     if args.workers is not None:
         args.workers = args.workers or None
 
-    ivl_mode = args.invalidation_mode.replace('-', '_').upper()
-    invalidation_mode = py_compile.PycInvalidationMode[ivl_mode]
+    if args.invalidation_mode:
+        ivl_mode = args.invalidation_mode.replace('-', '_').upper()
+        invalidation_mode = py_compile.PycInvalidationMode[ivl_mode]
+    else:
+        invalidation_mode = None
 
     success = True
     try: