gh-98040: Remove find_loader, find_module and other deprecated APIs (#98059)

* Remove deprecated classes from pkgutil
* Remove some other PEP 302 obsolescence
* Use find_spec instead of load_module
* Remove more tests of PEP 302 obsolete APIs
* Remove another bunch of tests using obsolete load_modules()
* Remove deleted names from __all__
* Remove obsolete footnote
* imp is removed
* Remove `imp` from generated stdlib names
* What's new and blurb
* Update zipimport documentation for the removed methods
* Fix some Windows tests
* Remove any test (or part of a test) that references `find_module()`.
* Use assertIsNone() / assertIsNotNone() consistently.
* Update Doc/reference/import.rst
* We don't need pkgutil._get_spec() any more either
*  test.test_importlib.fixtures.NullFinder
* ...BadLoaderFinder.find_module
* ...test_api.InvalidatingNullFinder.find_module
* ...test.test_zipimport test of z.find_module
* Suppress cross-references to find_loader and find_module
* Suppress cross-references to Finder
* Suppress cross-references to pkgutil.ImpImporter and pkgutil.ImpLoader

---------

Co-authored-by: Oleg Iarygin <oleg@arhadthedev.net>
Co-authored-by: Adam Turner <9087854+aa-turner@users.noreply.github.com>
This commit is contained in:
Barry Warsaw 2023-05-03 04:55:22 -07:00 committed by GitHub
parent bcea36f8db
commit 326997829d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 137 additions and 1047 deletions

View File

@ -127,28 +127,6 @@ Functions
.. versionchanged:: 3.3
Parent packages are automatically imported.
.. function:: find_loader(name, path=None)
Find the loader for a module, optionally within the specified *path*. If the
module is in :attr:`sys.modules`, then ``sys.modules[name].__loader__`` is
returned (unless the loader would be ``None`` or is not set, in which case
:exc:`ValueError` is raised). Otherwise a search using :attr:`sys.meta_path`
is done. ``None`` is returned if no loader is found.
A dotted name does not have its parents implicitly imported as that requires
loading them and that may not be desired. To properly import a submodule you
will need to import all parent packages of the submodule and use the correct
argument to *path*.
.. versionadded:: 3.3
.. versionchanged:: 3.4
If ``__loader__`` is not set, raise :exc:`ValueError`, just like when the
attribute is set to ``None``.
.. deprecated:: 3.4
Use :func:`importlib.util.find_spec` instead.
.. function:: invalidate_caches()
Invalidate the internal caches of finders stored at
@ -247,7 +225,6 @@ are also provided to help in implementing the core ABCs.
ABC hierarchy::
object
+-- Finder (deprecated)
+-- MetaPathFinder
+-- PathEntryFinder
+-- Loader
@ -258,28 +235,6 @@ ABC hierarchy::
+-- SourceLoader
.. class:: Finder
An abstract base class representing a :term:`finder`.
.. deprecated:: 3.3
Use :class:`MetaPathFinder` or :class:`PathEntryFinder` instead.
.. abstractmethod:: find_module(fullname, path=None)
An abstract method for finding a :term:`loader` for the specified
module. Originally specified in :pep:`302`, this method was meant
for use in :data:`sys.meta_path` and in the path-based import subsystem.
.. versionchanged:: 3.4
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
An abstract base class representing a :term:`meta path finder`.
@ -287,7 +242,7 @@ ABC hierarchy::
.. versionadded:: 3.3
.. versionchanged:: 3.10
No longer a subclass of :class:`Finder`.
No longer a subclass of :class:`!Finder`.
.. method:: find_spec(fullname, path, target=None)
@ -303,25 +258,6 @@ ABC hierarchy::
.. versionadded:: 3.4
.. method:: find_module(fullname, path)
A legacy method for finding a :term:`loader` for the specified
module. If this is a top-level import, *path* will be ``None``.
Otherwise, this is a search for a subpackage or module and *path*
will be the value of :attr:`__path__` from the parent
package. If a loader cannot be found, ``None`` is returned.
If :meth:`find_spec` is defined, backwards-compatible functionality is
provided.
.. versionchanged:: 3.4
Returns ``None`` when called instead of raising
:exc:`NotImplementedError`. Can use :meth:`find_spec` to provide
functionality.
.. deprecated:: 3.4
Use :meth:`find_spec` instead.
.. method:: invalidate_caches()
An optional method which, when called, should invalidate any internal
@ -342,7 +278,7 @@ ABC hierarchy::
.. versionadded:: 3.3
.. versionchanged:: 3.10
No longer a subclass of :class:`Finder`.
No longer a subclass of :class:`!Finder`.
.. method:: find_spec(fullname, target=None)
@ -356,36 +292,6 @@ ABC hierarchy::
.. versionadded:: 3.4
.. method:: find_loader(fullname)
A legacy method for finding a :term:`loader` for the specified
module. Returns a 2-tuple of ``(loader, portion)`` where ``portion``
is a sequence of file system locations contributing to part of a namespace
package. The loader may be ``None`` while specifying ``portion`` to
signify the contribution of the file system locations to a namespace
package. An empty list can be used for ``portion`` to signify the loader
is not part of a namespace package. If ``loader`` is ``None`` and
``portion`` is the empty list then no loader or location for a namespace
package were found (i.e. failure to find anything for the module).
If :meth:`find_spec` is defined then backwards-compatible functionality is
provided.
.. versionchanged:: 3.4
Returns ``(None, [])`` instead of raising :exc:`NotImplementedError`.
Uses :meth:`find_spec` when available to provide functionality.
.. deprecated:: 3.4
Use :meth:`find_spec` instead.
.. method:: find_module(fullname)
A concrete implementation of :meth:`Finder.find_module` which is
equivalent to ``self.find_loader(fullname)[0]``.
.. deprecated:: 3.4
Use :meth:`find_spec` instead.
.. method:: invalidate_caches()
An optional method which, when called, should invalidate any internal
@ -881,13 +787,6 @@ find and load modules.
is no longer valid then ``None`` is returned but no value is cached
in :data:`sys.path_importer_cache`.
.. classmethod:: find_module(fullname, path=None)
A legacy wrapper around :meth:`find_spec`.
.. deprecated:: 3.4
Use :meth:`find_spec` instead.
.. classmethod:: invalidate_caches()
Calls :meth:`importlib.abc.PathEntryFinder.invalidate_caches` on all
@ -938,13 +837,6 @@ find and load modules.
.. versionadded:: 3.4
.. method:: find_loader(fullname)
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.

View File

@ -48,33 +48,6 @@ support.
this function to raise an exception (in line with :func:`os.path.isdir`
behavior).
.. class:: ImpImporter(dirname=None)
:pep:`302` Finder that wraps Python's "classic" import algorithm.
If *dirname* is a string, a :pep:`302` finder is created that searches that
directory. If *dirname* is ``None``, a :pep:`302` finder is created that
searches the current :data:`sys.path`, plus any modules that are frozen or
built-in.
Note that :class:`ImpImporter` does not currently support being used by
placement on :data:`sys.meta_path`.
.. deprecated:: 3.3
This emulation is no longer needed, as the standard import mechanism
is now fully :pep:`302` compliant and available in :mod:`importlib`.
.. class:: ImpLoader(fullname, file, filename, etc)
:term:`Loader <loader>` that wraps Python's "classic" import algorithm.
.. deprecated:: 3.3
This emulation is no longer needed, as the standard import mechanism
is now fully :pep:`302` compliant and available in :mod:`importlib`.
.. function:: find_loader(fullname)
Retrieve a module :term:`loader` for the given *fullname*.

View File

@ -1177,7 +1177,7 @@ always available.
:term:`Module specs <module spec>` were introduced in Python 3.4, by
:pep:`451`. Earlier versions of Python looked for a method called
:meth:`~importlib.abc.MetaPathFinder.find_module`.
:meth:`!find_module`.
This is still called as a fallback if a :data:`meta_path` entry doesn't
have a :meth:`~importlib.abc.MetaPathFinder.find_spec` method.

View File

@ -74,6 +74,11 @@ zipimporter Objects
:exc:`ZipImportError` is raised if *archivepath* doesn't point to a valid ZIP
archive.
.. versionchanged:: 3.12
Methods ``find_loader()`` and ``find_module()``, deprecated in 3.10 are
now removed. Use :meth:`find_spec` instead.
.. method:: create_module(spec)
Implementation of :meth:`importlib.abc.Loader.create_module` that returns
@ -89,28 +94,6 @@ zipimporter Objects
.. versionadded:: 3.10
.. method:: find_loader(fullname, path=None)
An implementation of :meth:`importlib.abc.PathEntryFinder.find_loader`.
.. deprecated:: 3.10
Use :meth:`find_spec` instead.
.. method:: find_module(fullname, path=None)
Search for a module specified by *fullname*. *fullname* must be the fully
qualified (dotted) module name. It returns the zipimporter instance itself
if the module was found, or :const:`None` if it wasn't. The optional
*path* argument is ignored---it's there for compatibility with the
importer protocol.
.. deprecated:: 3.10
Use :meth:`find_spec` instead.
.. method:: find_spec(fullname, target=None)
An implementation of :meth:`importlib.abc.PathEntryFinder.find_spec`.

View File

@ -324,15 +324,18 @@ modules, and one that knows how to import modules from an :term:`import path`
.. versionchanged:: 3.4
The :meth:`~importlib.abc.MetaPathFinder.find_spec` method of meta path
finders replaced :meth:`~importlib.abc.MetaPathFinder.find_module`, which
finders replaced :meth:`!find_module`, which
is now deprecated. While it will continue to work without change, the
import machinery will try it only if the finder does not implement
``find_spec()``.
.. versionchanged:: 3.10
Use of :meth:`~importlib.abc.MetaPathFinder.find_module` by the import system
Use of :meth:`!find_module` by the import system
now raises :exc:`ImportWarning`.
.. versionchanged:: 3.12
``find_module()`` has been removed. Use :meth:`find_spec` instead.
Loading
=======
@ -837,7 +840,7 @@ stores finder objects rather than being limited to :term:`importer` objects).
In this way, the expensive search for a particular :term:`path entry`
location's :term:`path entry finder` need only be done once. User code is
free to remove cache entries from :data:`sys.path_importer_cache` forcing
the path based finder to perform the path entry search again [#fnpic]_.
the path based finder to perform the path entry search again.
If the path entry is not present in the cache, the path based finder iterates
over every callable in :data:`sys.path_hooks`. Each of the :term:`path entry
@ -887,13 +890,13 @@ module. ``find_spec()`` returns a fully populated spec for the module.
This spec will always have "loader" set (with one exception).
To indicate to the import machinery that the spec represents a namespace
:term:`portion`, the path entry finder sets "submodule_search_locations" to
:term:`portion`, the path entry finder sets ``submodule_search_locations`` to
a list containing the portion.
.. versionchanged:: 3.4
:meth:`~importlib.abc.PathEntryFinder.find_spec` replaced
:meth:`~importlib.abc.PathEntryFinder.find_loader` and
:meth:`~importlib.abc.PathEntryFinder.find_module`, both of which
:meth:`!find_loader` and
:meth:`!find_module`, both of which
are now deprecated, but will be used if ``find_spec()`` is not defined.
Older path entry finders may implement one of these two deprecated methods
@ -901,7 +904,7 @@ a list containing the portion.
sake of backward compatibility. However, if ``find_spec()`` is
implemented on the path entry finder, the legacy methods are ignored.
:meth:`~importlib.abc.PathEntryFinder.find_loader` takes one argument, the
:meth:`!find_loader` takes one argument, the
fully qualified name of the module being imported. ``find_loader()``
returns a 2-tuple where the first item is the loader and the second item
is a namespace :term:`portion`.
@ -920,10 +923,13 @@ a list containing the portion.
``find_loader()`` in preference to ``find_module()``.
.. versionchanged:: 3.10
Calls to :meth:`~importlib.abc.PathEntryFinder.find_module` and
:meth:`~importlib.abc.PathEntryFinder.find_loader` by the import
Calls to :meth:`!find_module` and
:meth:`!find_loader` by the import
system will raise :exc:`ImportWarning`.
.. versionchanged:: 3.12
``find_module()`` and ``find_loader()`` have been removed.
Replacing the standard import system
====================================
@ -1045,8 +1051,8 @@ The original specification for :data:`sys.meta_path` was :pep:`302`, with
subsequent extension in :pep:`420`.
:pep:`420` introduced :term:`namespace packages <namespace package>` for
Python 3.3. :pep:`420` also introduced the :meth:`find_loader` protocol as an
alternative to :meth:`find_module`.
Python 3.3. :pep:`420` also introduced the :meth:`!find_loader` protocol as an
alternative to :meth:`!find_module`.
:pep:`366` describes the addition of the ``__package__`` attribute for
explicit relative imports in main modules.
@ -1073,9 +1079,3 @@ methods to finders and loaders.
module may replace itself in :data:`sys.modules`. This is
implementation-specific behavior that is not guaranteed to work in other
Python implementations.
.. [#fnpic] In legacy code, it is possible to find instances of
:class:`imp.NullImporter` in the :data:`sys.path_importer_cache`. It
is recommended that code be changed to use ``None`` instead. See
:ref:`portingpythoncode` for more details. Note that the ``imp`` module
was removed in Python 3.12.

View File

@ -728,7 +728,7 @@ module:
Importer objects must have a single method, ``find_module(fullname,
path=None)``. *fullname* will be a module or package name, e.g. ``string`` or
``distutils.core``. :meth:`find_module` must return a loader object that has a
``distutils.core``. :meth:`!find_module` must return a loader object that has a
single method, ``load_module(fullname)``, that creates and returns the
corresponding module object.

View File

@ -1608,7 +1608,7 @@ Deprecated
* Starting in this release, there will be a concerted effort to begin
cleaning up old import semantics that were kept for Python 2.7
compatibility. Specifically,
:meth:`~importlib.abc.PathEntryFinder.find_loader`/:meth:`~importlib.abc.Finder.find_module`
:meth:`!find_loader`/:meth:`!find_module`
(superseded by :meth:`~importlib.abc.Finder.find_spec`),
:meth:`~importlib.abc.Loader.load_module`
(superseded by :meth:`~importlib.abc.Loader.exec_module`),
@ -1645,8 +1645,8 @@ Deprecated
:meth:`~importlib.abc.Loader.exec_module` is preferred.
(Contributed by Brett Cannon in :issue:`26131`.)
* The use of :meth:`importlib.abc.MetaPathFinder.find_module` and
:meth:`importlib.abc.PathEntryFinder.find_module` by the import system now
* The use of :meth:`!importlib.abc.MetaPathFinder.find_module` and
:meth:`!importlib.abc.PathEntryFinder.find_module` by the import system now
trigger an :exc:`ImportWarning` as
:meth:`importlib.abc.MetaPathFinder.find_spec` and
:meth:`importlib.abc.PathEntryFinder.find_spec`
@ -1654,40 +1654,40 @@ Deprecated
:func:`importlib.util.spec_from_loader` to help in porting.
(Contributed by Brett Cannon in :issue:`42134`.)
* The use of :meth:`importlib.abc.PathEntryFinder.find_loader` by the import
* The use of :meth:`!importlib.abc.PathEntryFinder.find_loader` by the import
system now triggers an :exc:`ImportWarning` as
:meth:`importlib.abc.PathEntryFinder.find_spec` is preferred. You can use
: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` )
: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.Finder` is deprecated (including its sole method,
:meth:`!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`,
* 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
: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`.)

View File

@ -1876,24 +1876,24 @@ C APIs pending removal are
* The :class:`typing.io <typing.IO>` namespace
* The :class:`typing.re <typing.Pattern>` namespace
* :func:`!cgi.log`
* :func:`importlib.find_loader`
* :func:`!importlib.find_loader`
* :meth:`importlib.abc.Loader.module_repr`
* :meth:`importlib.abc.MetaPathFinder.find_module`
* :meth:`importlib.abc.PathEntryFinder.find_loader`
* :meth:`importlib.abc.PathEntryFinder.find_module`
* :meth:`!importlib.abc.MetaPathFinder.find_module`
* :meth:`!importlib.abc.PathEntryFinder.find_loader`
* :meth:`!importlib.abc.PathEntryFinder.find_module`
* :meth:`!importlib.machinery.BuiltinImporter.find_module`
* :meth:`!importlib.machinery.BuiltinLoader.module_repr`
* :meth:`!importlib.machinery.FileFinder.find_loader`
* :meth:`!importlib.machinery.FileFinder.find_module`
* :meth:`!importlib.machinery.FrozenImporter.find_module`
* :meth:`!importlib.machinery.FrozenLoader.module_repr`
* :meth:`importlib.machinery.PathFinder.find_module`
* :meth:`!importlib.machinery.PathFinder.find_module`
* :meth:`!importlib.machinery.WindowsRegistryFinder.find_module`
* :func:`importlib.util.module_for_loader`
* :func:`!importlib.util.set_loader_wrapper`
* :func:`!importlib.util.set_package_wrapper`
* :class:`pkgutil.ImpImporter`
* :class:`pkgutil.ImpLoader`
* :class:`!pkgutil.ImpImporter`
* :class:`!pkgutil.ImpLoader`
* :meth:`pathlib.Path.link_to`
* :func:`!sqlite3.enable_shared_cache`
* :func:`!sqlite3.OptimizedUnicode`

View File

@ -983,14 +983,20 @@ Removed
* Many previously deprecated cleanups in :mod:`importlib` have now been
completed:
* References to, and support for ``module_repr()`` has been eradicated.
* References to, and support for ``module_repr()`` has been removed.
(Contributed by Barry Warsaw in :gh:`97850`.)
* ``importlib.util.set_package`` has been removed.
(Contributed by Brett Cannon in :gh:`65961`.)
* ``importlib.util.set_package`` has been removed. (Contributed by Brett
Cannon in :gh:`65961`.)
* The ``imp`` module has been removed. (Contributed by Barry Warsaw in
:gh:`98040`.)
* Support for ``find_loader()`` and ``find_module()`` APIs have been
removed. (Contributed by Barry Warsaw in :gh:`98040`.)
* ``importlib.abc.Finder``, ``pkg.ImpImporter``, and ``pkg.ImpLoader`` have
been removed. (Contributed by Barry Warsaw in :gh:`98040`.)
* The ``imp`` module has been removed. (Contributed by Barry Warsaw in
:gh:`98040`.)
* Removed the ``suspicious`` rule from the documentation Makefile, and
removed ``Doc/tools/rstlint.py``, both in favor of `sphinx-lint

View File

@ -714,7 +714,7 @@ to properly delineate between :term:`meta path finders <meta path finder>`
and :term:`path entry finders <path entry finder>` by introducing
:class:`importlib.abc.MetaPathFinder` and
:class:`importlib.abc.PathEntryFinder`, respectively. The old ABC of
:class:`importlib.abc.Finder` is now only provided for backwards-compatibility
:class:`!importlib.abc.Finder` is now only provided for backwards-compatibility
and does not enforce any method requirements.
In terms of finders, :class:`importlib.machinery.FileFinder` exposes the
@ -2390,7 +2390,7 @@ Porting Python code
:attr:`sys.path_importer_cache` where it represents the use of implicit
finders, but semantically it should not change anything.
* :class:`importlib.abc.Finder` no longer specifies a ``find_module()`` abstract
* :class:`!importlib.abc.Finder` no longer specifies a ``find_module()`` abstract
method that must be implemented. If you were relying on subclasses to
implement that method, make sure to check for the method's existence first.
You will probably want to check for ``find_loader()`` first, though, in the

View File

@ -2077,19 +2077,19 @@ Deprecations in the Python API
------------------------------
* As mentioned in :ref:`whatsnew-pep-451`, a number of :mod:`importlib`
methods and functions are deprecated: :meth:`importlib.find_loader` is
methods and functions are deprecated: :meth:`!importlib.find_loader` is
replaced by :func:`importlib.util.find_spec`;
:meth:`importlib.machinery.PathFinder.find_module` is replaced by
:meth:`!importlib.machinery.PathFinder.find_module` is replaced by
:meth:`importlib.machinery.PathFinder.find_spec`;
:meth:`importlib.abc.MetaPathFinder.find_module` is replaced by
:meth:`!importlib.abc.MetaPathFinder.find_module` is replaced by
:meth:`importlib.abc.MetaPathFinder.find_spec`;
:meth:`importlib.abc.PathEntryFinder.find_loader` and
:meth:`~importlib.abc.PathEntryFinder.find_module` are replaced by
:meth:`!importlib.abc.PathEntryFinder.find_loader` and
:meth:`!find_module` are replaced by
:meth:`importlib.abc.PathEntryFinder.find_spec`; all of the ``xxxLoader`` ABC
``load_module`` methods (:meth:`importlib.abc.Loader.load_module`,
:meth:`importlib.abc.InspectLoader.load_module`,
:meth:`importlib.abc.FileLoader.load_module`,
:meth:`importlib.abc.SourceLoader.load_module`) should no longer be
``load_module`` methods (:meth:`!importlib.abc.Loader.load_module`,
:meth:`!importlib.abc.InspectLoader.load_module`,
:meth:`!importlib.abc.FileLoader.load_module`,
:meth:`!importlib.abc.SourceLoader.load_module`) should no longer be
implemented, instead loaders should implement an
``exec_module`` method
(:meth:`importlib.abc.Loader.exec_module`,

View File

@ -2004,11 +2004,11 @@ importlib
---------
Methods
:meth:`MetaPathFinder.find_module() <importlib.abc.MetaPathFinder.find_module>`
:meth:`MetaPathFinder.find_module() <!importlib.abc.MetaPathFinder.find_module>`
(replaced by
:meth:`MetaPathFinder.find_spec() <importlib.abc.MetaPathFinder.find_spec>`)
and
:meth:`PathEntryFinder.find_loader() <importlib.abc.PathEntryFinder.find_loader>`
:meth:`PathEntryFinder.find_loader() <!importlib.abc.PathEntryFinder.find_loader>`
(replaced by
:meth:`PathEntryFinder.find_spec() <importlib.abc.PathEntryFinder.find_spec>`)
both deprecated in Python 3.4 now emit :exc:`DeprecationWarning`.

View File

@ -70,40 +70,6 @@ def invalidate_caches():
finder.invalidate_caches()
def find_loader(name, path=None):
"""Return the loader for the specified module.
This is a backward-compatible wrapper around find_spec().
This function is deprecated in favor of importlib.util.find_spec().
"""
warnings.warn('Deprecated since Python 3.4 and slated for removal in '
'Python 3.12; use importlib.util.find_spec() instead',
DeprecationWarning, stacklevel=2)
try:
loader = sys.modules[name].__loader__
if loader is None:
raise ValueError(f'{name}.__loader__ is None')
else:
return loader
except KeyError:
pass
except AttributeError:
raise ValueError(f'{name}.__loader__ is not set') from None
spec = _bootstrap._find_spec(name, path)
# We won't worry about malformed specs (missing attributes).
if spec is None:
return None
if spec.loader is None:
if spec.submodule_search_locations is None:
raise ImportError(f'spec for {name} missing loader', name=name)
raise ImportError('namespace packages do not have loaders',
name=name)
return spec.loader
def import_module(name, package=None):
"""Import a module.

View File

@ -892,21 +892,6 @@ class BuiltinImporter:
else:
return None
@classmethod
def find_module(cls, fullname, path=None):
"""Find the built-in module.
If 'path' is ever specified then the search is considered a failure.
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
@staticmethod
def create_module(spec):
"""Create a built-in module"""
@ -1076,18 +1061,6 @@ class FrozenImporter:
spec.submodule_search_locations.insert(0, pkgdir)
return spec
@classmethod
def find_module(cls, fullname, path=None):
"""Find a frozen module.
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
def create_module(spec):
"""Set __file__, if able."""
@ -1170,16 +1143,6 @@ def _resolve_name(name, package, level):
return f'{base}.{name}' if name else base
def _find_spec_legacy(finder, name, path):
msg = (f"{_object_name(finder)}.find_spec() not found; "
"falling back to find_module()")
_warnings.warn(msg, ImportWarning)
loader = finder.find_module(name, path)
if loader is None:
return None
return spec_from_loader(name, loader)
def _find_spec(name, path, target=None):
"""Find a module's spec."""
meta_path = sys.meta_path
@ -1200,9 +1163,7 @@ def _find_spec(name, path, target=None):
try:
find_spec = finder.find_spec
except AttributeError:
spec = _find_spec_legacy(finder, name, path)
if spec is None:
continue
continue
else:
spec = find_spec(name, path, target)
if spec is not None:

View File

@ -659,26 +659,6 @@ def _check_name(method):
return _check_name_wrapper
def _find_module_shim(self, fullname):
"""Try to find a loader for the specified module by delegating to
self.find_loader().
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.
loader, portions = self.find_loader(fullname)
if loader is None and len(portions):
msg = f'Not importing directory {portions[0]}: missing __init__'
_warnings.warn(msg, ImportWarning)
return loader
def _classify_pyc(data, name, exc_details):
"""Perform basic validity checking of a pyc header and return the flags field,
which determines how the pyc should be further validated against the source.
@ -985,22 +965,6 @@ class WindowsRegistryFinder:
origin=filepath)
return spec
@classmethod
def find_module(cls, fullname, path=None):
"""Find module named in the registry.
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
else:
return None
class _LoaderBasics:
@ -1517,27 +1481,6 @@ class PathFinder:
sys.path_importer_cache[path] = finder
return finder
@classmethod
def _legacy_get_spec(cls, fullname, finder):
# This would be a good place for a DeprecationWarning if
# we ended up going that route.
if hasattr(finder, 'find_loader'):
msg = (f"{_bootstrap._object_name(finder)}.find_spec() not found; "
"falling back to find_loader()")
_warnings.warn(msg, ImportWarning)
loader, portions = finder.find_loader(fullname)
else:
msg = (f"{_bootstrap._object_name(finder)}.find_spec() not found; "
"falling back to find_module()")
_warnings.warn(msg, ImportWarning)
loader = finder.find_module(fullname)
portions = []
if loader is not None:
return _bootstrap.spec_from_loader(fullname, loader)
spec = _bootstrap.ModuleSpec(fullname, None)
spec.submodule_search_locations = portions
return spec
@classmethod
def _get_spec(cls, fullname, path, target=None):
"""Find the loader or namespace_path for this module/package name."""
@ -1549,10 +1492,7 @@ class PathFinder:
continue
finder = cls._path_importer_cache(entry)
if finder is not None:
if hasattr(finder, 'find_spec'):
spec = finder.find_spec(fullname, target)
else:
spec = cls._legacy_get_spec(fullname, finder)
spec = finder.find_spec(fullname, target)
if spec is None:
continue
if spec.loader is not None:
@ -1594,22 +1534,6 @@ class PathFinder:
else:
return spec
@classmethod
def find_module(cls, fullname, path=None):
"""find the module on sys.path or 'path' based on sys.path_hooks and
sys.path_importer_cache.
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
return spec.loader
@staticmethod
def find_distributions(*args, **kwargs):
"""
@ -1654,23 +1578,6 @@ class FileFinder:
"""Invalidate the directory mtime."""
self._path_mtime = -1
find_module = _find_module_shim
def find_loader(self, fullname):
"""Try to find a loader for the specified module, or the namespace
package portions. Returns (loader, list-of-portions).
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, []
return spec.loader, spec.submodule_search_locations or []
def _get_spec(self, loader_class, fullname, path, smsl, target):
loader = loader_class(fullname, path)
return spec_from_file_location(fullname, path, loader=loader,

View File

@ -19,7 +19,7 @@ from .resources import abc as _resources_abc
__all__ = [
'Loader', 'Finder', 'MetaPathFinder', 'PathEntryFinder',
'Loader', 'MetaPathFinder', 'PathEntryFinder',
'ResourceLoader', 'InspectLoader', 'ExecutionLoader',
'FileLoader', 'SourceLoader',
]
@ -49,38 +49,6 @@ def _register(abstract_cls, *classes):
abstract_cls.register(frozen_cls)
class Finder(metaclass=abc.ABCMeta):
"""Legacy abstract base class for import finders.
It may be subclassed for compatibility with legacy third party
reimplementations of the import system. Otherwise, finder
implementations should derive from the more specific MetaPathFinder
or PathEntryFinder ABCs.
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(metaclass=abc.ABCMeta):
"""Abstract base class for import finders on sys.meta_path."""
@ -88,27 +56,6 @@ class MetaPathFinder(metaclass=abc.ABCMeta):
# We don't define find_spec() here since that would break
# hasattr checks we do to support backward compatibility.
def find_module(self, fullname, path):
"""Return a loader for the module.
If no module is found, return None. The fullname is a str and
the path is a list of strings or None.
This method is deprecated since Python 3.4 in favor of
finder.find_spec(). If find_spec() exists then backwards-compatible
functionality is provided for this method.
"""
warnings.warn("MetaPathFinder.find_module() is deprecated since Python "
"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'):
return None
found = self.find_spec(fullname, path)
return found.loader if found is not None else None
def invalidate_caches(self):
"""An optional method for clearing the finder's cache, if any.
This method is used by importlib.invalidate_caches().
@ -122,43 +69,6 @@ class PathEntryFinder(metaclass=abc.ABCMeta):
"""Abstract base class for path entry finders used by PathFinder."""
# We don't define find_spec() here since that would break
# hasattr checks we do to support backward compatibility.
def find_loader(self, fullname):
"""Return (loader, namespace portion) for the path entry.
The fullname is a str. The namespace portion is a sequence of
path entries contributing to part of a namespace package. The
sequence may be empty. If loader is not None, the portion will
be ignored.
The portion will be discarded if another path entry finder
locates the module as a normal module or package.
This method is deprecated since Python 3.4 in favor of
finder.find_spec(). If find_spec() is provided than backwards-compatible
functionality is provided.
"""
warnings.warn("PathEntryFinder.find_loader() is deprecated since Python "
"3.4 in favor of PathEntryFinder.find_spec() "
"(available since 3.4)",
DeprecationWarning,
stacklevel=2)
if not hasattr(self, 'find_spec'):
return None, []
found = self.find_spec(fullname)
if found is not None:
if not found.submodule_search_locations:
portions = []
else:
portions = found.submodule_search_locations
return found.loader, portions
else:
return None, []
find_module = _bootstrap_external._find_module_shim
def invalidate_caches(self):
"""An optional method for clearing the finder's cache, if any.
This method is used by PathFinder.invalidate_caches().

View File

@ -23,20 +23,6 @@ ModuleInfo = namedtuple('ModuleInfo', 'module_finder name ispkg')
ModuleInfo.__doc__ = 'A namedtuple with minimal info about a module.'
def _get_spec(finder, name):
"""Return the finder-specific module spec."""
# Works with legacy finders.
try:
find_spec = finder.find_spec
except AttributeError:
loader = finder.find_module(name)
if loader is None:
return None
return importlib.util.spec_from_loader(name, loader)
else:
return find_spec(name)
def read_code(stream):
# This helper is needed in order for the PEP 302 emulation to
# correctly handle compiled files

View File

@ -2242,7 +2242,7 @@ class ModuleScanner:
callback(None, modname, '')
else:
try:
spec = pkgutil._get_spec(importer, modname)
spec = importer.find_spec(modname)
except SyntaxError:
# raised by tests for bad coding cookies or BOM
continue

View File

@ -43,38 +43,5 @@ class FindSpecTests(abc.FinderTests):
) = util.test_both(FindSpecTests, machinery=machinery)
@unittest.skipIf(util.BUILTINS.good_name is None, 'no reasonable builtin module')
class FinderTests(abc.FinderTests):
"""Test find_module() for built-in modules."""
def test_module(self):
# Common case.
with util.uncache(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'))
# Built-in modules cannot be a package.
test_package = test_package_in_package = test_package_over_module = None
# Built-in modules cannot be in a package.
test_module_in_package = None
def test_failure(self):
assert 'importlib' not in sys.builtin_module_names
with warnings.catch_warnings():
warnings.simplefilter("ignore", DeprecationWarning)
loader = self.machinery.BuiltinImporter.find_module('importlib')
self.assertIsNone(loader)
(Frozen_FinderTests,
Source_FinderTests
) = util.test_both(FinderTests, machinery=machinery)
if __name__ == '__main__':
unittest.main()

View File

@ -19,7 +19,7 @@ class PathHookTests:
def test_success(self):
# Path hook should handle a directory where a known extension module
# exists.
self.assertTrue(hasattr(self.hook(util.EXTENSIONS.path), 'find_module'))
self.assertTrue(hasattr(self.hook(util.EXTENSIONS.path), 'find_spec'))
(Frozen_PathHooksTests,

View File

@ -350,11 +350,6 @@ def DALS(str):
return textwrap.dedent(str).lstrip()
class NullFinder:
def find_module(self, name):
pass
@requires_zlib()
class ZipFixtures:
root = 'test.test_importlib.data'

View File

@ -182,45 +182,5 @@ class FindSpecTests(abc.FinderTests):
) = util.test_both(FindSpecTests, machinery=machinery)
class FinderTests(abc.FinderTests):
"""Test finding frozen modules."""
def find(self, name, path=None):
finder = self.machinery.FrozenImporter
with warnings.catch_warnings():
warnings.simplefilter("ignore", DeprecationWarning)
with import_helper.frozen_modules():
return finder.find_module(name, path)
def test_module(self):
name = '__hello__'
loader = self.find(name)
self.assertTrue(hasattr(loader, 'load_module'))
def test_package(self):
loader = self.find('__phello__')
self.assertTrue(hasattr(loader, 'load_module'))
def test_module_in_package(self):
loader = self.find('__phello__.spam', ['__phello__'])
self.assertTrue(hasattr(loader, 'load_module'))
# No frozen package within another package to test with.
test_package_in_package = None
# No easy way to test.
test_package_over_module = None
def test_failure(self):
loader = self.find('<not real>')
self.assertIsNone(loader)
(Frozen_FinderTests,
Source_FinderTests
) = util.test_both(FinderTests, machinery=machinery)
if __name__ == '__main__':
unittest.main()

View File

@ -125,88 +125,6 @@ class ExecModuleTests(abc.LoaderTests):
) = util.test_both(ExecModuleTests, machinery=machinery)
class LoaderTests(abc.LoaderTests):
def load_module(self, name):
with fresh(name, oldapi=True):
module = self.machinery.FrozenImporter.load_module(name)
with captured_stdout() as stdout:
module.main()
return module, stdout
def test_module(self):
module, stdout = self.load_module('__hello__')
filename = resolve_stdlib_file('__hello__')
check = {'__name__': '__hello__',
'__package__': '',
'__loader__': self.machinery.FrozenImporter,
'__file__': filename,
}
for attr, value in check.items():
self.assertEqual(getattr(module, attr, None), value)
self.assertEqual(stdout.getvalue(), 'Hello world!\n')
def test_package(self):
module, stdout = self.load_module('__phello__')
filename = resolve_stdlib_file('__phello__', ispkg=True)
pkgdir = os.path.dirname(filename)
check = {'__name__': '__phello__',
'__package__': '__phello__',
'__path__': [pkgdir],
'__loader__': self.machinery.FrozenImporter,
'__file__': filename,
}
for attr, value in check.items():
attr_value = getattr(module, attr, None)
self.assertEqual(attr_value, value,
"for __phello__.%s, %r != %r" %
(attr, attr_value, value))
self.assertEqual(stdout.getvalue(), 'Hello world!\n')
def test_lacking_parent(self):
with util.uncache('__phello__'):
module, stdout = self.load_module('__phello__.spam')
filename = resolve_stdlib_file('__phello__.spam')
check = {'__name__': '__phello__.spam',
'__package__': '__phello__',
'__loader__': self.machinery.FrozenImporter,
'__file__': filename,
}
for attr, value in check.items():
attr_value = getattr(module, attr)
self.assertEqual(attr_value, value,
"for __phello__.spam.%s, %r != %r" %
(attr, attr_value, value))
self.assertEqual(stdout.getvalue(), 'Hello world!\n')
def test_module_reuse(self):
with fresh('__hello__', oldapi=True):
module1 = self.machinery.FrozenImporter.load_module('__hello__')
module2 = self.machinery.FrozenImporter.load_module('__hello__')
with captured_stdout() as stdout:
module1.main()
module2.main()
self.assertIs(module1, module2)
self.assertEqual(stdout.getvalue(),
'Hello world!\nHello world!\n')
# No way to trigger an error in a frozen module.
test_state_after_failure = None
def test_unloadable(self):
with import_helper.frozen_modules():
with deprecated():
assert self.machinery.FrozenImporter.find_module('_not_real') is None
with self.assertRaises(ImportError) as cm:
self.load_module('_not_real')
self.assertEqual(cm.exception.name, '_not_real')
(Frozen_LoaderTests,
Source_LoaderTests
) = util.test_both(LoaderTests, machinery=machinery)
class InspectLoaderTests:
"""Tests for the InspectLoader methods for FrozenImporter."""

View File

@ -33,48 +33,5 @@ class SpecLoaderAttributeTests:
) = util.test_both(SpecLoaderAttributeTests, __import__=util.__import__)
class LoaderMock:
def find_module(self, fullname, path=None):
return self
def load_module(self, fullname):
sys.modules[fullname] = self.module
return self.module
class LoaderAttributeTests:
def test___loader___missing(self):
with warnings.catch_warnings():
warnings.simplefilter("ignore", ImportWarning)
module = types.ModuleType('blah')
try:
del module.__loader__
except AttributeError:
pass
loader = LoaderMock()
loader.module = module
with util.uncache('blah'), util.import_state(meta_path=[loader]):
module = self.__import__('blah')
self.assertEqual(loader, module.__loader__)
def test___loader___is_None(self):
with warnings.catch_warnings():
warnings.simplefilter("ignore", ImportWarning)
module = types.ModuleType('blah')
module.__loader__ = None
loader = LoaderMock()
loader.module = module
with util.uncache('blah'), util.import_state(meta_path=[loader]):
returned_module = self.__import__('blah')
self.assertEqual(loader, module.__loader__)
(Frozen_Tests,
Source_Tests
) = util.test_both(LoaderAttributeTests, __import__=util.__import__)
if __name__ == '__main__':
unittest.main()

View File

@ -95,25 +95,6 @@ class FakeSpec:
self.parent = parent
class Using__package__PEP302(Using__package__):
mock_modules = util.mock_modules
def test_using___package__(self):
with warnings.catch_warnings():
warnings.simplefilter("ignore", ImportWarning)
super().test_using___package__()
def test_spec_fallback(self):
with warnings.catch_warnings():
warnings.simplefilter("ignore", ImportWarning)
super().test_spec_fallback()
(Frozen_UsingPackagePEP302,
Source_UsingPackagePEP302
) = util.test_both(Using__package__PEP302, __import__=util.__import__)
class Using__package__PEP451(Using__package__):
mock_modules = util.mock_spec
@ -162,23 +143,6 @@ class Setting__package__:
module = getattr(pkg, 'mod')
self.assertEqual(module.__package__, 'pkg')
class Setting__package__PEP302(Setting__package__, unittest.TestCase):
mock_modules = util.mock_modules
def test_top_level(self):
with warnings.catch_warnings():
warnings.simplefilter("ignore", ImportWarning)
super().test_top_level()
def test_package(self):
with warnings.catch_warnings():
warnings.simplefilter("ignore", ImportWarning)
super().test_package()
def test_submodule(self):
with warnings.catch_warnings():
warnings.simplefilter("ignore", ImportWarning)
super().test_submodule()
class Setting__package__PEP451(Setting__package__, unittest.TestCase):
mock_modules = util.mock_spec

View File

@ -28,11 +28,6 @@ class BadSpecFinderLoader:
class BadLoaderFinder:
@classmethod
def find_module(cls, fullname, path):
if fullname == SUBMOD_NAME:
return cls
@classmethod
def load_module(cls, fullname):
if fullname == SUBMOD_NAME:

View File

@ -52,12 +52,11 @@ class ImportlibUseCache(UseCache, unittest.TestCase):
__import__ = util.__import__['Source']
def create_mock(self, *names, return_=None):
mock = util.mock_modules(*names)
original_load = mock.load_module
def load_module(self, fullname):
original_load(fullname)
return return_
mock.load_module = MethodType(load_module, mock)
mock = util.mock_spec(*names)
original_spec = mock.find_spec
def find_spec(self, fullname, path, target=None):
return original_spec(fullname)
mock.find_spec = MethodType(find_spec, mock)
return mock
# __import__ inconsistent between loaders and built-in import when it comes
@ -86,14 +85,12 @@ class ImportlibUseCache(UseCache, unittest.TestCase):
# See test_using_cache_after_loader() for reasoning.
def test_using_cache_for_fromlist(self):
# [from cache for fromlist]
with warnings.catch_warnings():
warnings.simplefilter("ignore", ImportWarning)
with self.create_mock('pkg.__init__', 'pkg.module') as importer:
with util.import_state(meta_path=[importer]):
module = self.__import__('pkg', fromlist=['module'])
self.assertTrue(hasattr(module, 'module'))
self.assertEqual(id(module.module),
id(sys.modules['pkg.module']))
with self.create_mock('pkg.__init__', 'pkg.module') as importer:
with util.import_state(meta_path=[importer]):
module = self.__import__('pkg', fromlist=['module'])
self.assertTrue(hasattr(module, 'module'))
self.assertEqual(id(module.module),
id(sys.modules['pkg.module']))
if __name__ == '__main__':

View File

@ -113,16 +113,6 @@ class CallSignoreSuppressImportWarning(CallSignature):
super().test_no_path()
class CallSignaturePEP302(CallSignoreSuppressImportWarning):
mock_modules = util.mock_modules
finder_name = 'find_module'
(Frozen_CallSignaturePEP302,
Source_CallSignaturePEP302
) = util.test_both(CallSignaturePEP302, __import__=util.__import__)
class CallSignaturePEP451(CallSignature):
mock_modules = util.mock_spec
finder_name = 'find_spec'

View File

@ -116,46 +116,6 @@ class FinderTests:
if email is not missing:
sys.modules['email'] = email
def test_finder_with_find_module(self):
class TestFinder:
def find_module(self, fullname):
return self.to_return
failing_finder = TestFinder()
failing_finder.to_return = None
path = 'testing path'
with util.import_state(path_importer_cache={path: failing_finder}):
with warnings.catch_warnings():
warnings.simplefilter("ignore", ImportWarning)
self.assertIsNone(
self.machinery.PathFinder.find_spec('whatever', [path]))
success_finder = TestFinder()
success_finder.to_return = __loader__
with util.import_state(path_importer_cache={path: success_finder}):
with warnings.catch_warnings():
warnings.simplefilter("ignore", ImportWarning)
spec = self.machinery.PathFinder.find_spec('whatever', [path])
self.assertEqual(spec.loader, __loader__)
def test_finder_with_find_loader(self):
class TestFinder:
loader = None
portions = []
def find_loader(self, fullname):
return self.loader, self.portions
path = 'testing path'
with util.import_state(path_importer_cache={path: TestFinder()}):
with warnings.catch_warnings():
warnings.simplefilter("ignore", ImportWarning)
self.assertIsNone(
self.machinery.PathFinder.find_spec('whatever', [path]))
success_finder = TestFinder()
success_finder.loader = __loader__
with util.import_state(path_importer_cache={path: success_finder}):
with warnings.catch_warnings():
warnings.simplefilter("ignore", ImportWarning)
spec = self.machinery.PathFinder.find_spec('whatever', [path])
self.assertEqual(spec.loader, __loader__)
def test_finder_with_find_spec(self):
class TestFinder:
spec = None
@ -228,9 +188,9 @@ class FinderTests:
class FindModuleTests(FinderTests):
def find(self, *args, **kwargs):
with warnings.catch_warnings():
warnings.simplefilter("ignore", DeprecationWarning)
return self.machinery.PathFinder.find_module(*args, **kwargs)
spec = self.machinery.PathFinder.find_spec(*args, **kwargs)
return None if spec is None else spec.loader
def check_found(self, found, importer):
self.assertIs(found, importer)
@ -255,16 +215,14 @@ class FindSpecTests(FinderTests):
class PathEntryFinderTests:
def test_finder_with_failing_find_spec(self):
# PathEntryFinder with find_module() defined should work.
# Issue #20763.
class Finder:
path_location = 'test_finder_with_find_module'
path_location = 'test_finder_with_find_spec'
def __init__(self, path):
if path != self.path_location:
raise ImportError
@staticmethod
def find_module(fullname):
def find_spec(fullname, target=None):
return None
@ -274,27 +232,6 @@ class PathEntryFinderTests:
warnings.simplefilter("ignore", ImportWarning)
self.machinery.PathFinder.find_spec('importlib')
def test_finder_with_failing_find_module(self):
# PathEntryFinder with find_module() defined should work.
# Issue #20763.
class Finder:
path_location = 'test_finder_with_find_module'
def __init__(self, path):
if path != self.path_location:
raise ImportError
@staticmethod
def find_module(fullname):
return None
with util.import_state(path=[Finder.path_location]+sys.path[:],
path_hooks=[Finder]):
with warnings.catch_warnings():
warnings.simplefilter("ignore", ImportWarning)
warnings.simplefilter("ignore", DeprecationWarning)
self.machinery.PathFinder.find_module('importlib')
(Frozen_PEFTests,
Source_PEFTests

View File

@ -63,19 +63,6 @@ class CaseSensitivityTest(util.CASEOKTestBase):
self.assertIn(self.name, insensitive.get_filename(self.name))
class CaseSensitivityTestPEP302(CaseSensitivityTest):
def find(self, finder):
with warnings.catch_warnings():
warnings.simplefilter("ignore", DeprecationWarning)
return finder.find_module(self.name)
(Frozen_CaseSensitivityTestPEP302,
Source_CaseSensitivityTestPEP302
) = util.test_both(CaseSensitivityTestPEP302, importlib=importlib,
machinery=machinery)
class CaseSensitivityTestPEP451(CaseSensitivityTest):
def find(self, finder):
found = finder.find_spec(self.name)

View File

@ -120,7 +120,7 @@ class FinderTests(abc.FinderTests):
def test_failure(self):
with util.create_modules('blah') as mapping:
nothing = self.import_(mapping['.root'], 'sdfsadsadf')
self.assertIsNone(nothing)
self.assertEqual(nothing, self.NOT_FOUND)
def test_empty_string_for_dir(self):
# The empty string from sys.path means to search in the cwd.
@ -150,7 +150,7 @@ class FinderTests(abc.FinderTests):
found = self._find(finder, 'mod', loader_only=True)
self.assertIsNotNone(found)
found = self._find(finder, 'mod', loader_only=True)
self.assertIsNone(found)
self.assertEqual(found, self.NOT_FOUND)
@unittest.skipUnless(sys.platform != 'win32',
'os.chmod() does not support the needed arguments under Windows')
@ -196,10 +196,12 @@ class FinderTestsPEP420(FinderTests):
NOT_FOUND = (None, [])
def _find(self, finder, name, loader_only=False):
with warnings.catch_warnings():
warnings.simplefilter("ignore", DeprecationWarning)
loader_portions = finder.find_loader(name)
return loader_portions[0] if loader_only else loader_portions
spec = finder.find_spec(name)
if spec is None:
return self.NOT_FOUND
if loader_only:
return spec.loader
return spec.loader, spec.submodule_search_locations
(Frozen_FinderTestsPEP420,
@ -207,20 +209,5 @@ class FinderTestsPEP420(FinderTests):
) = util.test_both(FinderTestsPEP420, machinery=machinery)
class FinderTestsPEP302(FinderTests):
NOT_FOUND = None
def _find(self, finder, name, loader_only=False):
with warnings.catch_warnings():
warnings.simplefilter("ignore", DeprecationWarning)
return finder.find_module(name)
(Frozen_FinderTestsPEP302,
Source_FinderTestsPEP302
) = util.test_both(FinderTestsPEP302, machinery=machinery)
if __name__ == '__main__':
unittest.main()

View File

@ -18,19 +18,10 @@ class PathHookTest:
self.assertTrue(hasattr(self.path_hook()(mapping['.root']),
'find_spec'))
def test_success_legacy(self):
with util.create_modules('dummy') as mapping:
self.assertTrue(hasattr(self.path_hook()(mapping['.root']),
'find_module'))
def test_empty_string(self):
# The empty string represents the cwd.
self.assertTrue(hasattr(self.path_hook()(''), 'find_spec'))
def test_empty_string_legacy(self):
# The empty string represents the cwd.
self.assertTrue(hasattr(self.path_hook()(''), 'find_module'))
(Frozen_PathHookTest,
Source_PathHooktest

View File

@ -147,20 +147,13 @@ class ABCTestHarness:
class MetaPathFinder:
def find_module(self, fullname, path):
return super().find_module(fullname, path)
pass
class MetaPathFinderDefaultsTests(ABCTestHarness):
SPLIT = make_abc_subclasses(MetaPathFinder)
def test_find_module(self):
# Default should return None.
with self.assertWarns(DeprecationWarning):
found = self.ins.find_module('something', None)
self.assertIsNone(found)
def test_invalidate_caches(self):
# Calling the method is a no-op.
self.ins.invalidate_caches()
@ -173,22 +166,13 @@ class MetaPathFinderDefaultsTests(ABCTestHarness):
class PathEntryFinder:
def find_loader(self, fullname):
return super().find_loader(fullname)
pass
class PathEntryFinderDefaultsTests(ABCTestHarness):
SPLIT = make_abc_subclasses(PathEntryFinder)
def test_find_loader(self):
with self.assertWarns(DeprecationWarning):
found = self.ins.find_loader('something')
self.assertEqual(found, (None, []))
def find_module(self):
self.assertEqual(None, self.ins.find_module('something'))
def test_invalidate_caches(self):
# Should be a no-op.
self.ins.invalidate_caches()
@ -201,8 +185,7 @@ class PathEntryFinderDefaultsTests(ABCTestHarness):
class Loader:
def load_module(self, fullname):
return super().load_module(fullname)
pass
class LoaderDefaultsTests(ABCTestHarness):
@ -333,14 +316,6 @@ class MetaPathFinderFindModuleTests:
return MetaPathSpecFinder()
def test_find_module(self):
finder = self.finder(None)
path = ['a', 'b', 'c']
name = 'blah'
with self.assertWarns(DeprecationWarning):
found = finder.find_module(name, path)
self.assertIsNone(found)
def test_find_spec_with_explicit_target(self):
loader = object()
spec = self.util.spec_from_loader('blah', loader)
@ -370,53 +345,6 @@ class MetaPathFinderFindModuleTests:
) = test_util.test_both(MetaPathFinderFindModuleTests, abc=abc, util=util)
##### PathEntryFinder concrete methods #########################################
class PathEntryFinderFindLoaderTests:
@classmethod
def finder(cls, spec):
class PathEntrySpecFinder(cls.abc.PathEntryFinder):
def find_spec(self, fullname, target=None):
self.called_for = fullname
return spec
return PathEntrySpecFinder()
def test_no_spec(self):
finder = self.finder(None)
name = 'blah'
with self.assertWarns(DeprecationWarning):
found = finder.find_loader(name)
self.assertIsNone(found[0])
self.assertEqual([], found[1])
self.assertEqual(name, finder.called_for)
def test_spec_with_loader(self):
loader = object()
spec = self.util.spec_from_loader('blah', loader)
finder = self.finder(spec)
with self.assertWarns(DeprecationWarning):
found = finder.find_loader('blah')
self.assertIs(found[0], spec.loader)
def test_spec_with_portions(self):
spec = self.machinery.ModuleSpec('blah', None)
paths = ['a', 'b', 'c']
spec.submodule_search_locations = paths
finder = self.finder(spec)
with self.assertWarns(DeprecationWarning):
found = finder.find_loader('blah')
self.assertIsNone(found[0])
self.assertEqual(paths, found[1])
(Frozen_PEFFindLoaderTests,
Source_PEFFindLoaderTests
) = test_util.test_both(PathEntryFinderFindLoaderTests, abc=abc, util=util,
machinery=machinery)
##### Loader concrete methods ##################################################
class LoaderLoadModuleTests:

View File

@ -95,7 +95,8 @@ class ImportModuleTests:
(Frozen_ImportModuleTests,
Source_ImportModuleTests
) = test_util.test_both(ImportModuleTests, init=init)
) = test_util.test_both(
ImportModuleTests, init=init, util=util, machinery=machinery)
class FindLoaderTests:
@ -103,29 +104,26 @@ class FindLoaderTests:
FakeMetaFinder = None
def test_sys_modules(self):
# If a module with __loader__ is in sys.modules, then return it.
# If a module with __spec__.loader is in sys.modules, then return it.
name = 'some_mod'
with test_util.uncache(name):
module = types.ModuleType(name)
loader = 'a loader!'
module.__loader__ = loader
module.__spec__ = self.machinery.ModuleSpec(name, loader)
sys.modules[name] = module
with warnings.catch_warnings():
warnings.simplefilter('ignore', DeprecationWarning)
found = self.init.find_loader(name)
self.assertEqual(loader, found)
spec = self.util.find_spec(name)
self.assertIsNotNone(spec)
self.assertEqual(spec.loader, loader)
def test_sys_modules_loader_is_None(self):
# If sys.modules[name].__loader__ is None, raise ValueError.
# If sys.modules[name].__spec__.loader is None, raise ValueError.
name = 'some_mod'
with test_util.uncache(name):
module = types.ModuleType(name)
module.__loader__ = None
sys.modules[name] = module
with self.assertRaises(ValueError):
with warnings.catch_warnings():
warnings.simplefilter('ignore', DeprecationWarning)
self.init.find_loader(name)
self.util.find_spec(name)
def test_sys_modules_loader_is_not_set(self):
# Should raise ValueError
@ -134,24 +132,20 @@ class FindLoaderTests:
with test_util.uncache(name):
module = types.ModuleType(name)
try:
del module.__loader__
del module.__spec__.loader
except AttributeError:
pass
sys.modules[name] = module
with self.assertRaises(ValueError):
with warnings.catch_warnings():
warnings.simplefilter('ignore', DeprecationWarning)
self.init.find_loader(name)
self.util.find_spec(name)
def test_success(self):
# Return the loader found on sys.meta_path.
name = 'some_mod'
with test_util.uncache(name):
with test_util.import_state(meta_path=[self.FakeMetaFinder]):
with warnings.catch_warnings():
warnings.simplefilter('ignore', DeprecationWarning)
warnings.simplefilter('ignore', ImportWarning)
self.assertEqual((name, None), self.init.find_loader(name))
spec = self.util.find_spec(name)
self.assertEqual((name, (name, None)), (spec.name, spec.loader))
def test_success_path(self):
# Searching on a path should work.
@ -159,17 +153,12 @@ class FindLoaderTests:
path = 'path to some place'
with test_util.uncache(name):
with test_util.import_state(meta_path=[self.FakeMetaFinder]):
with warnings.catch_warnings():
warnings.simplefilter('ignore', DeprecationWarning)
warnings.simplefilter('ignore', ImportWarning)
self.assertEqual((name, path),
self.init.find_loader(name, path))
spec = self.util.find_spec(name, path)
self.assertEqual(name, spec.name)
def test_nothing(self):
# None is returned upon failure to find a loader.
with warnings.catch_warnings():
warnings.simplefilter('ignore', DeprecationWarning)
self.assertIsNone(self.init.find_loader('nevergoingtofindthismodule'))
self.assertIsNone(self.util.find_spec('nevergoingtofindthismodule'))
class FindLoaderPEP451Tests(FindLoaderTests):
@ -182,20 +171,8 @@ class FindLoaderPEP451Tests(FindLoaderTests):
(Frozen_FindLoaderPEP451Tests,
Source_FindLoaderPEP451Tests
) = test_util.test_both(FindLoaderPEP451Tests, init=init)
class FindLoaderPEP302Tests(FindLoaderTests):
class FakeMetaFinder:
@staticmethod
def find_module(name, path=None):
return name, path
(Frozen_FindLoaderPEP302Tests,
Source_FindLoaderPEP302Tests
) = test_util.test_both(FindLoaderPEP302Tests, init=init)
) = test_util.test_both(
FindLoaderPEP451Tests, init=init, util=util, machinery=machinery)
class ReloadTests:
@ -380,7 +357,8 @@ class ReloadTests:
(Frozen_ReloadTests,
Source_ReloadTests
) = test_util.test_both(ReloadTests, init=init, util=util)
) = test_util.test_both(
ReloadTests, init=init, util=util, machinery=machinery)
class InvalidateCacheTests:
@ -390,8 +368,6 @@ class InvalidateCacheTests:
class InvalidatingNullFinder:
def __init__(self, *ignored):
self.called = False
def find_module(self, *args):
return None
def invalidate_caches(self):
self.called = True
@ -416,7 +392,8 @@ class InvalidateCacheTests:
(Frozen_InvalidateCacheTests,
Source_InvalidateCacheTests
) = test_util.test_both(InvalidateCacheTests, init=init)
) = test_util.test_both(
InvalidateCacheTests, init=init, util=util, machinery=machinery)
class FrozenImportlibTests(unittest.TestCase):

View File

@ -92,30 +92,16 @@ class WindowsRegistryFinderTests:
def test_find_spec_missing(self):
spec = self.machinery.WindowsRegistryFinder.find_spec('spam')
self.assertIs(spec, None)
def test_find_module_missing(self):
with warnings.catch_warnings():
warnings.simplefilter("ignore", DeprecationWarning)
loader = self.machinery.WindowsRegistryFinder.find_module('spam')
self.assertIs(loader, None)
self.assertIsNone(spec)
def test_module_found(self):
with setup_module(self.machinery, self.test_module):
with warnings.catch_warnings():
warnings.simplefilter("ignore", DeprecationWarning)
loader = self.machinery.WindowsRegistryFinder.find_module(self.test_module)
spec = self.machinery.WindowsRegistryFinder.find_spec(self.test_module)
self.assertIsNot(loader, None)
self.assertIsNot(spec, None)
self.assertIsNotNone(spec)
def test_module_not_found(self):
with setup_module(self.machinery, self.test_module, path="."):
with warnings.catch_warnings():
warnings.simplefilter("ignore", DeprecationWarning)
loader = self.machinery.WindowsRegistryFinder.find_module(self.test_module)
spec = self.machinery.WindowsRegistryFinder.find_spec(self.test_module)
self.assertIsNone(loader)
self.assertIsNone(spec)
(Frozen_WindowsRegistryFinderTests,

View File

@ -194,8 +194,7 @@ def import_state(**kwargs):
new_value = default
setattr(sys, attr, new_value)
if len(kwargs):
raise ValueError(
'unrecognized arguments: {0}'.format(kwargs.keys()))
raise ValueError('unrecognized arguments: {}'.format(kwargs))
yield
finally:
for attr, value in originals.items():
@ -243,30 +242,6 @@ class _ImporterMock:
self._uncache.__exit__(None, None, None)
class mock_modules(_ImporterMock):
"""Importer mock using PEP 302 APIs."""
def find_module(self, fullname, path=None):
if fullname not in self.modules:
return None
else:
return self
def load_module(self, fullname):
if fullname not in self.modules:
raise ImportError
else:
sys.modules[fullname] = self.modules[fullname]
if fullname in self.module_code:
try:
self.module_code[fullname]()
except Exception:
del sys.modules[fullname]
raise
return self.modules[fullname]
class mock_spec(_ImporterMock):
"""Importer mock using PEP 451 APIs."""

View File

@ -429,7 +429,7 @@ class ExtendPathTests(unittest.TestCase):
importers = list(iter_importers(fullname))
expected_importer = get_importer(pathitem)
for finder in importers:
spec = pkgutil._get_spec(finder, fullname)
spec = finder.find_spec(fullname)
loader = spec.loader
try:
loader = loader.loader
@ -441,7 +441,7 @@ class ExtendPathTests(unittest.TestCase):
self.assertEqual(finder, expected_importer)
self.assertIsInstance(loader,
importlib.machinery.SourceFileLoader)
self.assertIsNone(pkgutil._get_spec(finder, pkgname))
self.assertIsNone(finder.find_spec(pkgname))
with self.assertRaises(ImportError):
list(iter_importers('invalid.module'))
@ -535,12 +535,6 @@ class ImportlibMigrationTests(unittest.TestCase):
# PEP 302 emulation in this module is in the process of being
# deprecated in favour of importlib proper
def check_deprecated(self):
return check_warnings(
("This emulation is deprecated and slated for removal in "
"Python 3.12; use 'importlib' instead",
DeprecationWarning))
def test_get_loader_avoids_emulation(self):
with check_warnings() as w:
self.assertIsNotNone(pkgutil.get_loader("sys"))

View File

@ -836,7 +836,6 @@ class BadFileZipImportTestCase(unittest.TestCase):
self.assertRaises(TypeError, z.get_source, None)
error = zipimport.ZipImportError
self.assertIsNone(z.find_module('abc'))
self.assertIsNone(z.find_spec('abc'))
with warnings.catch_warnings():

View File

@ -0,0 +1,2 @@
Remove more deprecated importlib APIs: ``find_loader()``, ``find_module()``,
``importlib.abc.Finder``, ``pkgutil.ImpImporter``, ``pkgutil.ImpLoader``.