mirror of
https://github.com/python/cpython.git
synced 2025-07-07 19:35:27 +00:00
bpo-42135: Deprecate implementations of find_module() and find_loader() (GH-25169)
This commit is contained in:
parent
efccff9ac8
commit
57c6cb5100
20 changed files with 3821 additions and 3653 deletions
|
@ -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.
|
1486
Python/importlib.h
generated
1486
Python/importlib.h
generated
File diff suppressed because it is too large
Load diff
4058
Python/importlib_external.h
generated
4058
Python/importlib_external.h
generated
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue