mirror of https://github.com/python/cpython
bpo-42135: Deprecate implementations of find_module() and find_loader() (GH-25169)
This commit is contained in:
parent
efccff9ac8
commit
57c6cb5100
|
@ -257,6 +257,10 @@ ABC hierarchy::
|
|||
Returns ``None`` when called instead of raising
|
||||
:exc:`NotImplementedError`.
|
||||
|
||||
.. deprecated:: 3.10
|
||||
Implement :meth:`MetaPathFinder.find_spec` or
|
||||
:meth:`PathEntryFinder.find_spec` instead.
|
||||
|
||||
|
||||
.. class:: MetaPathFinder
|
||||
|
||||
|
@ -265,6 +269,9 @@ ABC hierarchy::
|
|||
|
||||
.. versionadded:: 3.3
|
||||
|
||||
.. versionchanged:: 3.10
|
||||
No longer a subclass of :class:`Finder`.
|
||||
|
||||
.. method:: find_spec(fullname, path, target=None)
|
||||
|
||||
An abstract method for finding a :term:`spec <module spec>` for
|
||||
|
@ -313,11 +320,13 @@ ABC hierarchy::
|
|||
An abstract base class representing a :term:`path entry finder`. Though
|
||||
it bears some similarities to :class:`MetaPathFinder`, ``PathEntryFinder``
|
||||
is meant for use only within the path-based import subsystem provided
|
||||
by :class:`PathFinder`. This ABC is a subclass of :class:`Finder` for
|
||||
compatibility reasons only.
|
||||
by :class:`importlib.machinery.PathFinder`.
|
||||
|
||||
.. versionadded:: 3.3
|
||||
|
||||
.. versionchanged:: 3.10
|
||||
No longer a subclass of :class:`Finder`.
|
||||
|
||||
.. method:: find_spec(fullname, target=None)
|
||||
|
||||
An abstract method for finding a :term:`spec <module spec>` for
|
||||
|
@ -363,7 +372,8 @@ ABC hierarchy::
|
|||
.. method:: invalidate_caches()
|
||||
|
||||
An optional method which, when called, should invalidate any internal
|
||||
cache used by the finder. Used by :meth:`PathFinder.invalidate_caches`
|
||||
cache used by the finder. Used by
|
||||
:meth:`importlib.machinery.PathFinder.invalidate_caches`
|
||||
when invalidating the caches of all cached finders.
|
||||
|
||||
|
||||
|
@ -1193,6 +1203,9 @@ find and load modules.
|
|||
|
||||
Attempt to find the loader to handle *fullname* within :attr:`path`.
|
||||
|
||||
.. deprecated:: 3.10
|
||||
Use :meth:`find_spec` instead.
|
||||
|
||||
.. method:: invalidate_caches()
|
||||
|
||||
Clear out the internal cache.
|
||||
|
|
|
@ -1062,6 +1062,39 @@ Deprecated
|
|||
:func:`importlib.util.spec_from_loader` to help in porting.
|
||||
(Contributed by Brett Cannon in :issue:`43672`.)
|
||||
|
||||
* The various implementations of
|
||||
:meth:`importlib.abc.MetaPathFinder.find_module` (
|
||||
:meth:`importlib.machinery.BuiltinImporter.find_module`,
|
||||
:meth:`importlib.machinery.FrozenImporter.find_module`,
|
||||
:meth:`importlib.machinery.WindowsRegistryFinder.find_module`,
|
||||
:meth:`importlib.machinery.PathFinder.find_module`,
|
||||
:meth:`importlib.abc.MetaPathFinder.find_module`),
|
||||
:meth:`importlib.abc.PathEntryFinder.find_module` (
|
||||
:meth:`importlib.machinery.FileFinder.find_module`,
|
||||
), and
|
||||
:meth:`importlib.abc.PathEntryFinder.find_loader` (
|
||||
:meth:`importlib.machinery.FileFinder.find_loader`
|
||||
) now raise :exc:`DeprecationWarning` and are slated for removal in
|
||||
Python 3.12 (previously they were documented as deprecated in Python 3.4).
|
||||
(Contributed by Brett Cannon in :issue:`42135`.)
|
||||
|
||||
* :class:`importlib.abc.Finder` is deprecated (including its sole method,
|
||||
:meth:`~importlib.abc.Finder.find_module`). Both
|
||||
:class:`importlib.abc.MetaPathFinder` and :class:`importlib.abc.PathEntryFinder`
|
||||
no longer inherit from the class. Users should inherit from one of these two
|
||||
classes as appropriate instead.
|
||||
(Contributed by Brett Cannon in :issue:`42135`.)
|
||||
|
||||
* The deprecations of :mod:`imp`, :func:`importlib.find_loader`,
|
||||
:func:`importlib.util.set_package_wrapper`,
|
||||
:func:`importlib.util.set_loader_wrapper`,
|
||||
:func:`importlib.util.module_for_loader`,
|
||||
:class:`pkgutil.ImpImporter`, and
|
||||
:class:`pkgutil.ImpLoader` have all been updated to list Python 3.12 as the
|
||||
slated version of removal (they began raising :exc:`DeprecationWarning` in
|
||||
previous versions of Python).
|
||||
(Contributed by Brett Cannon in :issue:`43720`.)
|
||||
|
||||
* The import system now uses the ``__spec__`` attribute on modules before
|
||||
falling back on :meth:`~importlib.abc.Loader.module_repr` for a module's
|
||||
``__repr__()`` method. Removal of the use of ``module_repr()`` is scheduled
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -761,6 +761,9 @@ class BuiltinImporter:
|
|||
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 @@ class FrozenImporter:
|
|||
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
|
||||
|
|
|
@ -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 @@ class WindowsRegistryFinder:
|
|||
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 @@ class PathFinder:
|
|||
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 @@ class FileFinder:
|
|||
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, []
|
||||
|
|
|
@ -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 @@ class MetaPathFinder(Finder):
|
|||
|
||||
"""
|
||||
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 @@ _register(MetaPathFinder, machinery.BuiltinImporter, machinery.FrozenImporter,
|
|||
machinery.PathFinder, machinery.WindowsRegistryFinder)
|
||||
|
||||
|
||||
class PathEntryFinder(Finder):
|
||||
class PathEntryFinder(metaclass=abc.ABCMeta):
|
||||
|
||||
"""Abstract base class for path entry finders used by PathFinder."""
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ machinery = util.import_importlib('importlib.machinery')
|
|||
|
||||
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 @@ class FinderTests(abc.FinderTests):
|
|||
|
||||
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)
|
||||
|
||||
|
||||
|
|
|
@ -12,30 +12,30 @@ machinery = util.import_importlib('importlib.machinery')
|
|||
@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,
|
||||
|
|
|
@ -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 @@ class FinderTests(abc.FinderTests):
|
|||
test_package_over_module = None
|
||||
|
||||
def test_failure(self):
|
||||
self.assertIsNone(self.find_module('asdfjkl;'))
|
||||
self.assertIsNone(self.find_spec('asdfjkl;'))
|
||||
|
||||
|
||||
(Frozen_FinderTests,
|
||||
|
|
|
@ -4,6 +4,7 @@ from .. import util
|
|||
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__'
|
||||
|
|
|
@ -78,7 +78,7 @@ class ExecModuleTests(abc.LoaderTests):
|
|||
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')
|
||||
|
|
|
@ -75,7 +75,8 @@ class FinderTests:
|
|||
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 @@ class FinderTests:
|
|||
|
||||
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 @@ class PathEntryFinderTests:
|
|||
path_hooks=[Finder]):
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("ignore", ImportWarning)
|
||||
warnings.simplefilter("ignore", DeprecationWarning)
|
||||
self.machinery.PathFinder.find_module('importlib')
|
||||
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ machinery = util.import_importlib('importlib.machinery')
|
|||
import os
|
||||
from test.support import os_helper
|
||||
import unittest
|
||||
import warnings
|
||||
|
||||
|
||||
@util.case_insensitive_tests
|
||||
|
@ -64,7 +65,9 @@ class CaseSensitivityTest(util.CASEOKTestBase):
|
|||
|
||||
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,
|
||||
|
|
|
@ -55,7 +55,7 @@ class InheritanceTests:
|
|||
|
||||
|
||||
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']
|
||||
|
||||
|
||||
|
|
|
@ -440,9 +440,9 @@ class StartupTests:
|
|||
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 @@ class StartupTests:
|
|||
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)
|
||||
|
||||
|
||||
|
|
|
@ -119,6 +119,9 @@ class zipimporter(_bootstrap_external._LoaderBasics):
|
|||
|
||||
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 @@ class zipimporter(_bootstrap_external._LoaderBasics):
|
|||
|
||||
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):
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
Deprecate find_module() and find_loader() implementations in importlib and
|
||||
zipimport.
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue