bpo-42135: Deprecate implementations of find_module() and find_loader() (GH-25169)

diff --git a/Lib/importlib/__init__.py b/Lib/importlib/__init__.py
index 03ff714..a510f08 100644
--- a/Lib/importlib/__init__.py
+++ b/Lib/importlib/__init__.py
@@ -78,8 +78,8 @@ def find_loader(name, path=None):
     This function is deprecated in favor of importlib.util.find_spec().
 
     """
-    warnings.warn('Deprecated since Python 3.4. '
-                  'Use importlib.util.find_spec() instead.',
+    warnings.warn('Deprecated since Python 3.4 and slated for removal in '
+                  'Python 3.10; use importlib.util.find_spec() instead',
                   DeprecationWarning, stacklevel=2)
     try:
         loader = sys.modules[name].__loader__
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py
index ab52e77..527bc9c 100644
--- a/Lib/importlib/_bootstrap.py
+++ b/Lib/importlib/_bootstrap.py
@@ -761,6 +761,9 @@ def find_module(cls, fullname, path=None):
         This method is deprecated.  Use find_spec() instead.
 
         """
+        _warnings.warn("BuiltinImporter.find_module() is deprecated and "
+                       "slated for removal in Python 3.12; use find_spec() instead",
+                       DeprecationWarning)
         spec = cls.find_spec(fullname, path)
         return spec.loader if spec is not None else None
 
@@ -834,6 +837,9 @@ def find_module(cls, fullname, path=None):
         This method is deprecated.  Use find_spec() instead.
 
         """
+        _warnings.warn("FrozenImporter.find_module() is deprecated and "
+                       "slated for removal in Python 3.12; use find_spec() instead",
+                       DeprecationWarning)
         return cls if _imp.is_frozen(fullname) else None
 
     @staticmethod
diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py
index d351ee0..34f554a 100644
--- a/Lib/importlib/_bootstrap_external.py
+++ b/Lib/importlib/_bootstrap_external.py
@@ -533,6 +533,9 @@ def _find_module_shim(self, fullname):
     This method is deprecated in favor of finder.find_spec().
 
     """
+    _warnings.warn("find_module() is deprecated and "
+                   "slated for removal in Python 3.12; use find_spec() instead",
+                   DeprecationWarning)
     # Call find_loader(). If it returns a string (indicating this
     # is a namespace package portion), generate a warning and
     # return None.
@@ -801,9 +804,12 @@ def find_spec(cls, fullname, path=None, target=None):
     def find_module(cls, fullname, path=None):
         """Find module named in the registry.
 
-        This method is deprecated.  Use exec_module() instead.
+        This method is deprecated.  Use find_spec() instead.
 
         """
+        _warnings.warn("WindowsRegistryFinder.find_module() is deprecated and "
+                       "slated for removal in Python 3.12; use find_spec() instead",
+                       DeprecationWarning)
         spec = cls.find_spec(fullname, path)
         if spec is not None:
             return spec.loader
@@ -1404,6 +1410,9 @@ def find_module(cls, fullname, path=None):
         This method is deprecated.  Use find_spec() instead.
 
         """
+        _warnings.warn("PathFinder.find_module() is deprecated and "
+                       "slated for removal in Python 3.12; use find_spec() instead",
+                       DeprecationWarning)
         spec = cls.find_spec(fullname, path)
         if spec is None:
             return None
@@ -1459,6 +1468,9 @@ def find_loader(self, fullname):
         This method is deprecated.  Use find_spec() instead.
 
         """
+        _warnings.warn("FileFinder.find_loader() is deprecated and "
+                       "slated for removal in Python 3.12; use find_spec() instead",
+                       DeprecationWarning)
         spec = self.find_spec(fullname)
         if spec is None:
             return None, []
diff --git a/Lib/importlib/abc.py b/Lib/importlib/abc.py
index 4be51e2..0b4a3f8 100644
--- a/Lib/importlib/abc.py
+++ b/Lib/importlib/abc.py
@@ -41,15 +41,27 @@ class Finder(metaclass=abc.ABCMeta):
     Deprecated since Python 3.3
     """
 
+    def __init__(self):
+        warnings.warn("the Finder ABC is deprecated and "
+                       "slated for removal in Python 3.12; use MetaPathFinder "
+                       "or PathEntryFinder instead",
+                       DeprecationWarning)
+
     @abc.abstractmethod
     def find_module(self, fullname, path=None):
         """An abstract method that should find a module.
         The fullname is a str and the optional path is a str or None.
         Returns a Loader object or None.
         """
+        warnings.warn("importlib.abc.Finder along with its find_module() "
+                      "method are deprecated and "
+                       "slated for removal in Python 3.12; use "
+                       "MetaPathFinder.find_spec() or "
+                       "PathEntryFinder.find_spec() instead",
+                       DeprecationWarning)
 
 
-class MetaPathFinder(Finder):
+class MetaPathFinder(metaclass=abc.ABCMeta):
 
     """Abstract base class for import finders on sys.meta_path."""
 
@@ -68,8 +80,8 @@ def find_module(self, fullname, path):
 
         """
         warnings.warn("MetaPathFinder.find_module() is deprecated since Python "
-                      "3.4 in favor of MetaPathFinder.find_spec() "
-                      "(available since 3.4)",
+                      "3.4 in favor of MetaPathFinder.find_spec() and is "
+                      "slated for removal in Python 3.12",
                       DeprecationWarning,
                       stacklevel=2)
         if not hasattr(self, 'find_spec'):
@@ -86,7 +98,7 @@ def invalidate_caches(self):
           machinery.PathFinder, machinery.WindowsRegistryFinder)
 
 
-class PathEntryFinder(Finder):
+class PathEntryFinder(metaclass=abc.ABCMeta):
 
     """Abstract base class for path entry finders used by PathFinder."""
 
diff --git a/Lib/test/test_importlib/builtin/test_finder.py b/Lib/test/test_importlib/builtin/test_finder.py
index 084f3de..6f51aba 100644
--- a/Lib/test/test_importlib/builtin/test_finder.py
+++ b/Lib/test/test_importlib/builtin/test_finder.py
@@ -5,6 +5,7 @@
 
 import sys
 import unittest
+import warnings
 
 
 @unittest.skipIf(util.BUILTINS.good_name is None, 'no reasonable builtin module')
@@ -58,7 +59,9 @@ class FinderTests(abc.FinderTests):
     def test_module(self):
         # Common case.
         with util.uncache(util.BUILTINS.good_name):
-            found = self.machinery.BuiltinImporter.find_module(util.BUILTINS.good_name)
+            with warnings.catch_warnings():
+                warnings.simplefilter("ignore", DeprecationWarning)
+                found = self.machinery.BuiltinImporter.find_module(util.BUILTINS.good_name)
             self.assertTrue(found)
             self.assertTrue(hasattr(found, 'load_module'))
 
@@ -70,14 +73,19 @@ def test_module(self):
 
     def test_failure(self):
         assert 'importlib' not in sys.builtin_module_names
-        loader = self.machinery.BuiltinImporter.find_module('importlib')
+        with warnings.catch_warnings():
+            warnings.simplefilter("ignore", DeprecationWarning)
+            loader = self.machinery.BuiltinImporter.find_module('importlib')
         self.assertIsNone(loader)
 
     def test_ignore_path(self):
         # The value for 'path' should always trigger a failed import.
         with util.uncache(util.BUILTINS.good_name):
-            loader = self.machinery.BuiltinImporter.find_module(util.BUILTINS.good_name,
-                                                            ['pkg'])
+            with warnings.catch_warnings():
+                warnings.simplefilter("ignore", DeprecationWarning)
+                loader = self.machinery.BuiltinImporter.find_module(
+                                                        util.BUILTINS.good_name,
+                                                        ['pkg'])
             self.assertIsNone(loader)
 
 
diff --git a/Lib/test/test_importlib/extension/test_case_sensitivity.py b/Lib/test/test_importlib/extension/test_case_sensitivity.py
index 4d76fa0..20bf035 100644
--- a/Lib/test/test_importlib/extension/test_case_sensitivity.py
+++ b/Lib/test/test_importlib/extension/test_case_sensitivity.py
@@ -12,30 +12,30 @@
 @util.case_insensitive_tests
 class ExtensionModuleCaseSensitivityTest(util.CASEOKTestBase):
 
-    def find_module(self):
+    def find_spec(self):
         good_name = util.EXTENSIONS.name
         bad_name = good_name.upper()
         assert good_name != bad_name
         finder = self.machinery.FileFinder(util.EXTENSIONS.path,
                                           (self.machinery.ExtensionFileLoader,
                                            self.machinery.EXTENSION_SUFFIXES))
-        return finder.find_module(bad_name)
+        return finder.find_spec(bad_name)
 
     @unittest.skipIf(sys.flags.ignore_environment, 'ignore_environment flag was set')
     def test_case_sensitive(self):
         with os_helper.EnvironmentVarGuard() as env:
             env.unset('PYTHONCASEOK')
             self.caseok_env_changed(should_exist=False)
-            loader = self.find_module()
-            self.assertIsNone(loader)
+            spec = self.find_spec()
+            self.assertIsNone(spec)
 
     @unittest.skipIf(sys.flags.ignore_environment, 'ignore_environment flag was set')
     def test_case_insensitivity(self):
         with os_helper.EnvironmentVarGuard() as env:
             env.set('PYTHONCASEOK', '1')
             self.caseok_env_changed(should_exist=True)
-            loader = self.find_module()
-            self.assertTrue(hasattr(loader, 'load_module'))
+            spec = self.find_spec()
+            self.assertTrue(spec)
 
 
 (Frozen_ExtensionCaseSensitivity,
diff --git a/Lib/test/test_importlib/extension/test_finder.py b/Lib/test/test_importlib/extension/test_finder.py
index c9b4a37..e8065d7 100644
--- a/Lib/test/test_importlib/extension/test_finder.py
+++ b/Lib/test/test_importlib/extension/test_finder.py
@@ -11,16 +11,15 @@ class FinderTests(abc.FinderTests):
 
     """Test the finder for extension modules."""
 
-    def find_module(self, fullname):
+    def find_spec(self, fullname):
         importer = self.machinery.FileFinder(util.EXTENSIONS.path,
                                             (self.machinery.ExtensionFileLoader,
                                              self.machinery.EXTENSION_SUFFIXES))
-        with warnings.catch_warnings():
-            warnings.simplefilter('ignore', DeprecationWarning)
-            return importer.find_module(fullname)
+
+        return importer.find_spec(fullname)
 
     def test_module(self):
-        self.assertTrue(self.find_module(util.EXTENSIONS.name))
+        self.assertTrue(self.find_spec(util.EXTENSIONS.name))
 
     # No extension module as an __init__ available for testing.
     test_package = test_package_in_package = None
@@ -32,7 +31,7 @@ def test_module(self):
     test_package_over_module = None
 
     def test_failure(self):
-        self.assertIsNone(self.find_module('asdfjkl;'))
+        self.assertIsNone(self.find_spec('asdfjkl;'))
 
 
 (Frozen_FinderTests,
diff --git a/Lib/test/test_importlib/frozen/test_finder.py b/Lib/test/test_importlib/frozen/test_finder.py
index 519aa02..eb7a4d2 100644
--- a/Lib/test/test_importlib/frozen/test_finder.py
+++ b/Lib/test/test_importlib/frozen/test_finder.py
@@ -4,6 +4,7 @@
 machinery = util.import_importlib('importlib.machinery')
 
 import unittest
+import warnings
 
 
 class FindSpecTests(abc.FinderTests):
@@ -49,7 +50,9 @@ class FinderTests(abc.FinderTests):
 
     def find(self, name, path=None):
         finder = self.machinery.FrozenImporter
-        return finder.find_module(name, path)
+        with warnings.catch_warnings():
+            warnings.simplefilter("ignore", DeprecationWarning)
+            return finder.find_module(name, path)
 
     def test_module(self):
         name = '__hello__'
diff --git a/Lib/test/test_importlib/frozen/test_loader.py b/Lib/test/test_importlib/frozen/test_loader.py
index 632246a..f0cf179 100644
--- a/Lib/test/test_importlib/frozen/test_loader.py
+++ b/Lib/test/test_importlib/frozen/test_loader.py
@@ -78,7 +78,7 @@ def test_module_repr_indirect(self):
     test_state_after_failure = None
 
     def test_unloadable(self):
-        assert self.machinery.FrozenImporter.find_module('_not_real') is None
+        assert self.machinery.FrozenImporter.find_spec('_not_real') is None
         with self.assertRaises(ImportError) as cm:
             self.exec_module('_not_real')
         self.assertEqual(cm.exception.name, '_not_real')
diff --git a/Lib/test/test_importlib/import_/test_path.py b/Lib/test/test_importlib/import_/test_path.py
index 2ba7030..57a2522 100644
--- a/Lib/test/test_importlib/import_/test_path.py
+++ b/Lib/test/test_importlib/import_/test_path.py
@@ -75,7 +75,8 @@ def test_empty_path_hooks(self):
         with util.import_state(path_importer_cache={}, path_hooks=[],
                                path=[path_entry]):
             with warnings.catch_warnings(record=True) as w:
-                warnings.simplefilter('always')
+                warnings.simplefilter('always', ImportWarning)
+                warnings.simplefilter('ignore', DeprecationWarning)
                 self.assertIsNone(self.find('os'))
                 self.assertIsNone(sys.path_importer_cache[path_entry])
                 self.assertEqual(len(w), 1)
@@ -216,7 +217,9 @@ def test_invalidate_caches_clear_out_None(self):
 
 class FindModuleTests(FinderTests):
     def find(self, *args, **kwargs):
-        return self.machinery.PathFinder.find_module(*args, **kwargs)
+        with warnings.catch_warnings():
+            warnings.simplefilter("ignore", DeprecationWarning)
+            return self.machinery.PathFinder.find_module(*args, **kwargs)
     def check_found(self, found, importer):
         self.assertIs(found, importer)
 
@@ -278,6 +281,7 @@ def find_module(fullname):
                                path_hooks=[Finder]):
             with warnings.catch_warnings():
                 warnings.simplefilter("ignore", ImportWarning)
+                warnings.simplefilter("ignore", DeprecationWarning)
                 self.machinery.PathFinder.find_module('importlib')
 
 
diff --git a/Lib/test/test_importlib/source/test_case_sensitivity.py b/Lib/test/test_importlib/source/test_case_sensitivity.py
index 77c06a7..19543f4 100644
--- a/Lib/test/test_importlib/source/test_case_sensitivity.py
+++ b/Lib/test/test_importlib/source/test_case_sensitivity.py
@@ -9,6 +9,7 @@
 import os
 from test.support import os_helper
 import unittest
+import warnings
 
 
 @util.case_insensitive_tests
@@ -64,7 +65,9 @@ def test_insensitive(self):
 
 class CaseSensitivityTestPEP302(CaseSensitivityTest):
     def find(self, finder):
-        return finder.find_module(self.name)
+        with warnings.catch_warnings():
+            warnings.simplefilter("ignore", DeprecationWarning)
+            return finder.find_module(self.name)
 
 
 (Frozen_CaseSensitivityTestPEP302,
diff --git a/Lib/test/test_importlib/test_abc.py b/Lib/test/test_importlib/test_abc.py
index 98f5835..45cbf90 100644
--- a/Lib/test/test_importlib/test_abc.py
+++ b/Lib/test/test_importlib/test_abc.py
@@ -55,7 +55,7 @@ def test_superclasses(self):
 
 
 class MetaPathFinder(InheritanceTests):
-    superclass_names = ['Finder']
+    superclass_names = []
     subclass_names = ['BuiltinImporter', 'FrozenImporter', 'PathFinder',
                       'WindowsRegistryFinder']
 
@@ -66,7 +66,7 @@ class MetaPathFinder(InheritanceTests):
 
 
 class PathEntryFinder(InheritanceTests):
-    superclass_names = ['Finder']
+    superclass_names = []
     subclass_names = ['FileFinder']
 
 
diff --git a/Lib/test/test_importlib/test_api.py b/Lib/test/test_importlib/test_api.py
index 8344fb0..763b2ad 100644
--- a/Lib/test/test_importlib/test_api.py
+++ b/Lib/test/test_importlib/test_api.py
@@ -440,9 +440,9 @@ def test_everyone_has___loader__(self):
                 with self.subTest(name=name):
                     self.assertTrue(hasattr(module, '__loader__'),
                                     '{!r} lacks a __loader__ attribute'.format(name))
-                    if self.machinery.BuiltinImporter.find_module(name):
+                    if self.machinery.BuiltinImporter.find_spec(name):
                         self.assertIsNot(module.__loader__, None)
-                    elif self.machinery.FrozenImporter.find_module(name):
+                    elif self.machinery.FrozenImporter.find_spec(name):
                         self.assertIsNot(module.__loader__, None)
 
     def test_everyone_has___spec__(self):
@@ -450,9 +450,9 @@ def test_everyone_has___spec__(self):
             if isinstance(module, types.ModuleType):
                 with self.subTest(name=name):
                     self.assertTrue(hasattr(module, '__spec__'))
-                    if self.machinery.BuiltinImporter.find_module(name):
+                    if self.machinery.BuiltinImporter.find_spec(name):
                         self.assertIsNot(module.__spec__, None)
-                    elif self.machinery.FrozenImporter.find_module(name):
+                    elif self.machinery.FrozenImporter.find_spec(name):
                         self.assertIsNot(module.__spec__, None)
 
 
diff --git a/Lib/zipimport.py b/Lib/zipimport.py
index e88d7a2..c55fec6 100644
--- a/Lib/zipimport.py
+++ b/Lib/zipimport.py
@@ -119,6 +119,9 @@ def find_loader(self, fullname, path=None):
 
         Deprecated since Python 3.10. Use find_spec() instead.
         """
+        _warnings.warn("zipimporter.find_loader() is deprecated and slated for "
+                       "removal in Python 3.12; use find_spec() instead",
+                       DeprecationWarning)
         mi = _get_module_info(self, fullname)
         if mi is not None:
             # This is a module or package.
@@ -152,6 +155,9 @@ def find_module(self, fullname, path=None):
 
         Deprecated since Python 3.10. Use find_spec() instead.
         """
+        _warnings.warn("zipimporter.find_module() is deprecated and slated for "
+                       "removal in Python 3.12; use find_spec() instead",
+                       DeprecationWarning)
         return self.find_loader(fullname, path)[0]
 
     def find_spec(self, fullname, target=None):