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):