mirror of
https://github.com/python/cpython
synced 2024-10-14 09:01:41 +00:00
gh-98040: Remove just the imp
module (#98573)
This commit is contained in:
parent
79b9db9295
commit
e1f14643dc
|
@ -188,6 +188,8 @@ Importing Modules
|
|||
.. versionchanged:: 3.3
|
||||
Uses :func:`imp.source_from_cache()` in calculating the source path if
|
||||
only the bytecode path is provided.
|
||||
.. versionchanged:: 3.12
|
||||
No longer uses the removed ``imp`` module.
|
||||
|
||||
|
||||
.. c:function:: long PyImport_GetMagicNumber()
|
||||
|
|
|
@ -1987,7 +1987,6 @@ are always available. They are listed here in alphabetical order.
|
|||
|
||||
.. index::
|
||||
statement: import
|
||||
module: imp
|
||||
|
||||
.. note::
|
||||
|
||||
|
|
|
@ -1,411 +0,0 @@
|
|||
:mod:`imp` --- Access the :ref:`import <importsystem>` internals
|
||||
================================================================
|
||||
|
||||
.. module:: imp
|
||||
:synopsis: Access the implementation of the import statement.
|
||||
:deprecated:
|
||||
|
||||
**Source code:** :source:`Lib/imp.py`
|
||||
|
||||
.. deprecated-removed:: 3.4 3.12
|
||||
The :mod:`imp` module is deprecated in favor of :mod:`importlib`.
|
||||
|
||||
.. index:: statement: import
|
||||
|
||||
--------------
|
||||
|
||||
This module provides an interface to the mechanisms used to implement the
|
||||
:keyword:`import` statement. It defines the following constants and functions:
|
||||
|
||||
|
||||
.. function:: get_magic()
|
||||
|
||||
.. index:: pair: file; byte-code
|
||||
|
||||
Return the magic string value used to recognize byte-compiled code files
|
||||
(:file:`.pyc` files). (This value may be different for each Python version.)
|
||||
|
||||
.. deprecated:: 3.4
|
||||
Use :attr:`importlib.util.MAGIC_NUMBER` instead.
|
||||
|
||||
|
||||
.. function:: get_suffixes()
|
||||
|
||||
Return a list of 3-element tuples, each describing a particular type of
|
||||
module. Each triple has the form ``(suffix, mode, type)``, where *suffix* is
|
||||
a string to be appended to the module name to form the filename to search
|
||||
for, *mode* is the mode string to pass to the built-in :func:`open` function
|
||||
to open the file (this can be ``'r'`` for text files or ``'rb'`` for binary
|
||||
files), and *type* is the file type, which has one of the values
|
||||
:const:`PY_SOURCE`, :const:`PY_COMPILED`, or :const:`C_EXTENSION`, described
|
||||
below.
|
||||
|
||||
.. deprecated:: 3.3
|
||||
Use the constants defined on :mod:`importlib.machinery` instead.
|
||||
|
||||
|
||||
.. function:: find_module(name[, path])
|
||||
|
||||
Try to find the module *name*. If *path* is omitted or ``None``, the list of
|
||||
directory names given by ``sys.path`` is searched, but first a few special
|
||||
places are searched: the function tries to find a built-in module with the
|
||||
given name (:const:`C_BUILTIN`), then a frozen module (:const:`PY_FROZEN`),
|
||||
and on some systems some other places are looked in as well (on Windows, it
|
||||
looks in the registry which may point to a specific file).
|
||||
|
||||
Otherwise, *path* must be a list of directory names; each directory is
|
||||
searched for files with any of the suffixes returned by :func:`get_suffixes`
|
||||
above. Invalid names in the list are silently ignored (but all list items
|
||||
must be strings).
|
||||
|
||||
If search is successful, the return value is a 3-element tuple ``(file,
|
||||
pathname, description)``:
|
||||
|
||||
*file* is an open :term:`file object` positioned at the beginning, *pathname*
|
||||
is the pathname of the file found, and *description* is a 3-element tuple as
|
||||
contained in the list returned by :func:`get_suffixes` describing the kind of
|
||||
module found.
|
||||
|
||||
If the module is built-in or frozen then *file* and *pathname* are both ``None``
|
||||
and the *description* tuple contains empty strings for its suffix and mode;
|
||||
the module type is indicated as given in parentheses above. If the search
|
||||
is unsuccessful, :exc:`ImportError` is raised. Other exceptions indicate
|
||||
problems with the arguments or environment.
|
||||
|
||||
If the module is a package, *file* is ``None``, *pathname* is the package
|
||||
path and the last item in the *description* tuple is :const:`PKG_DIRECTORY`.
|
||||
|
||||
This function does not handle hierarchical module names (names containing
|
||||
dots). In order to find *P.M*, that is, submodule *M* of package *P*, use
|
||||
:func:`find_module` and :func:`load_module` to find and load package *P*, and
|
||||
then use :func:`find_module` with the *path* argument set to ``P.__path__``.
|
||||
When *P* itself has a dotted name, apply this recipe recursively.
|
||||
|
||||
.. deprecated:: 3.3
|
||||
Use :func:`importlib.util.find_spec` instead unless Python 3.3
|
||||
compatibility is required, in which case use
|
||||
:func:`importlib.find_loader`. For example usage of the former case,
|
||||
see the :ref:`importlib-examples` section of the :mod:`importlib`
|
||||
documentation.
|
||||
|
||||
|
||||
.. function:: load_module(name, file, pathname, description)
|
||||
|
||||
Load a module that was previously found by :func:`find_module` (or by an
|
||||
otherwise conducted search yielding compatible results). This function does
|
||||
more than importing the module: if the module was already imported, it will
|
||||
reload the module! The *name* argument indicates the full
|
||||
module name (including the package name, if this is a submodule of a
|
||||
package). The *file* argument is an open file, and *pathname* is the
|
||||
corresponding file name; these can be ``None`` and ``''``, respectively, when
|
||||
the module is a package or not being loaded from a file. The *description*
|
||||
argument is a tuple, as would be returned by :func:`get_suffixes`, describing
|
||||
what kind of module must be loaded.
|
||||
|
||||
If the load is successful, the return value is the module object; otherwise,
|
||||
an exception (usually :exc:`ImportError`) is raised.
|
||||
|
||||
**Important:** the caller is responsible for closing the *file* argument, if
|
||||
it was not ``None``, even when an exception is raised. This is best done
|
||||
using a :keyword:`try` ... :keyword:`finally` statement.
|
||||
|
||||
.. deprecated:: 3.3
|
||||
If previously used in conjunction with :func:`imp.find_module` then
|
||||
consider using :func:`importlib.import_module`, otherwise use the loader
|
||||
returned by the replacement you chose for :func:`imp.find_module`. If you
|
||||
called :func:`imp.load_module` and related functions directly with file
|
||||
path arguments then use a combination of
|
||||
:func:`importlib.util.spec_from_file_location` and
|
||||
:func:`importlib.util.module_from_spec`. See the :ref:`importlib-examples`
|
||||
section of the :mod:`importlib` documentation for details of the various
|
||||
approaches.
|
||||
|
||||
|
||||
.. function:: new_module(name)
|
||||
|
||||
Return a new empty module object called *name*. This object is *not* inserted
|
||||
in ``sys.modules``.
|
||||
|
||||
.. deprecated:: 3.4
|
||||
Use :func:`importlib.util.module_from_spec` instead.
|
||||
|
||||
|
||||
.. function:: reload(module)
|
||||
|
||||
Reload a previously imported *module*. The argument must be a module object, so
|
||||
it must have been successfully imported before. This is useful if you have
|
||||
edited the module source file using an external editor and want to try out the
|
||||
new version without leaving the Python interpreter. The return value is the
|
||||
module object (the same as the *module* argument).
|
||||
|
||||
When ``reload(module)`` is executed:
|
||||
|
||||
* Python modules' code is recompiled and the module-level code reexecuted,
|
||||
defining a new set of objects which are bound to names in the module's
|
||||
dictionary. The ``init`` function of extension modules is not called a second
|
||||
time.
|
||||
|
||||
* As with all other objects in Python the old objects are only reclaimed after
|
||||
their reference counts drop to zero.
|
||||
|
||||
* The names in the module namespace are updated to point to any new or changed
|
||||
objects.
|
||||
|
||||
* Other references to the old objects (such as names external to the module) are
|
||||
not rebound to refer to the new objects and must be updated in each namespace
|
||||
where they occur if that is desired.
|
||||
|
||||
There are a number of other caveats:
|
||||
|
||||
When a module is reloaded, its dictionary (containing the module's global
|
||||
variables) is retained. Redefinitions of names will override the old
|
||||
definitions, so this is generally not a problem. If the new version of a module
|
||||
does not define a name that was defined by the old version, the old definition
|
||||
remains. This feature can be used to the module's advantage if it maintains a
|
||||
global table or cache of objects --- with a :keyword:`try` statement it can test
|
||||
for the table's presence and skip its initialization if desired::
|
||||
|
||||
try:
|
||||
cache
|
||||
except NameError:
|
||||
cache = {}
|
||||
|
||||
It is legal though generally not very useful to reload built-in or dynamically
|
||||
loaded modules, except for :mod:`sys`, :mod:`__main__` and :mod:`builtins`.
|
||||
In many cases, however, extension modules are not designed to be initialized
|
||||
more than once, and may fail in arbitrary ways when reloaded.
|
||||
|
||||
If a module imports objects from another module using :keyword:`from` ...
|
||||
:keyword:`import` ..., calling :func:`reload` for the other module does not
|
||||
redefine the objects imported from it --- one way around this is to re-execute
|
||||
the :keyword:`!from` statement, another is to use :keyword:`!import` and qualified
|
||||
names (*module*.*name*) instead.
|
||||
|
||||
If a module instantiates instances of a class, reloading the module that defines
|
||||
the class does not affect the method definitions of the instances --- they
|
||||
continue to use the old class definition. The same is true for derived classes.
|
||||
|
||||
.. versionchanged:: 3.3
|
||||
Relies on both ``__name__`` and ``__loader__`` being defined on the module
|
||||
being reloaded instead of just ``__name__``.
|
||||
|
||||
.. deprecated:: 3.4
|
||||
Use :func:`importlib.reload` instead.
|
||||
|
||||
|
||||
The following functions are conveniences for handling :pep:`3147` byte-compiled
|
||||
file paths.
|
||||
|
||||
.. versionadded:: 3.2
|
||||
|
||||
.. function:: cache_from_source(path, debug_override=None)
|
||||
|
||||
Return the :pep:`3147` path to the byte-compiled file associated with the
|
||||
source *path*. For example, if *path* is ``/foo/bar/baz.py`` the return
|
||||
value would be ``/foo/bar/__pycache__/baz.cpython-32.pyc`` for Python 3.2.
|
||||
The ``cpython-32`` string comes from the current magic tag (see
|
||||
:func:`get_tag`; if :attr:`sys.implementation.cache_tag` is not defined then
|
||||
:exc:`NotImplementedError` will be raised). By passing in ``True`` or
|
||||
``False`` for *debug_override* you can override the system's value for
|
||||
``__debug__``, leading to optimized bytecode.
|
||||
|
||||
*path* need not exist.
|
||||
|
||||
.. versionchanged:: 3.3
|
||||
If :attr:`sys.implementation.cache_tag` is ``None``, then
|
||||
:exc:`NotImplementedError` is raised.
|
||||
|
||||
.. deprecated:: 3.4
|
||||
Use :func:`importlib.util.cache_from_source` instead.
|
||||
|
||||
.. versionchanged:: 3.5
|
||||
The *debug_override* parameter no longer creates a ``.pyo`` file.
|
||||
|
||||
|
||||
.. function:: source_from_cache(path)
|
||||
|
||||
Given the *path* to a :pep:`3147` file name, return the associated source code
|
||||
file path. For example, if *path* is
|
||||
``/foo/bar/__pycache__/baz.cpython-32.pyc`` the returned path would be
|
||||
``/foo/bar/baz.py``. *path* need not exist, however if it does not conform
|
||||
to :pep:`3147` format, a :exc:`ValueError` is raised. If
|
||||
:attr:`sys.implementation.cache_tag` is not defined,
|
||||
:exc:`NotImplementedError` is raised.
|
||||
|
||||
.. versionchanged:: 3.3
|
||||
Raise :exc:`NotImplementedError` when
|
||||
:attr:`sys.implementation.cache_tag` is not defined.
|
||||
|
||||
.. deprecated:: 3.4
|
||||
Use :func:`importlib.util.source_from_cache` instead.
|
||||
|
||||
|
||||
.. function:: get_tag()
|
||||
|
||||
Return the :pep:`3147` magic tag string matching this version of Python's
|
||||
magic number, as returned by :func:`get_magic`.
|
||||
|
||||
.. deprecated:: 3.4
|
||||
Use :attr:`sys.implementation.cache_tag` directly starting
|
||||
in Python 3.3.
|
||||
|
||||
|
||||
The following functions help interact with the import system's internal
|
||||
locking mechanism. Locking semantics of imports are an implementation
|
||||
detail which may vary from release to release. However, Python ensures
|
||||
that circular imports work without any deadlocks.
|
||||
|
||||
|
||||
.. function:: lock_held()
|
||||
|
||||
Return ``True`` if the global import lock is currently held, else
|
||||
``False``. On platforms without threads, always return ``False``.
|
||||
|
||||
On platforms with threads, a thread executing an import first holds a
|
||||
global import lock, then sets up a per-module lock for the rest of the
|
||||
import. This blocks other threads from importing the same module until
|
||||
the original import completes, preventing other threads from seeing
|
||||
incomplete module objects constructed by the original thread. An
|
||||
exception is made for circular imports, which by construction have to
|
||||
expose an incomplete module object at some point.
|
||||
|
||||
.. versionchanged:: 3.3
|
||||
The locking scheme has changed to per-module locks for
|
||||
the most part. A global import lock is kept for some critical tasks,
|
||||
such as initializing the per-module locks.
|
||||
|
||||
.. deprecated:: 3.4
|
||||
|
||||
|
||||
.. function:: acquire_lock()
|
||||
|
||||
Acquire the interpreter's global import lock for the current thread.
|
||||
This lock should be used by import hooks to ensure thread-safety when
|
||||
importing modules.
|
||||
|
||||
Once a thread has acquired the import lock, the same thread may acquire it
|
||||
again without blocking; the thread must release it once for each time it has
|
||||
acquired it.
|
||||
|
||||
On platforms without threads, this function does nothing.
|
||||
|
||||
.. versionchanged:: 3.3
|
||||
The locking scheme has changed to per-module locks for
|
||||
the most part. A global import lock is kept for some critical tasks,
|
||||
such as initializing the per-module locks.
|
||||
|
||||
.. deprecated:: 3.4
|
||||
|
||||
|
||||
.. function:: release_lock()
|
||||
|
||||
Release the interpreter's global import lock. On platforms without
|
||||
threads, this function does nothing.
|
||||
|
||||
.. versionchanged:: 3.3
|
||||
The locking scheme has changed to per-module locks for
|
||||
the most part. A global import lock is kept for some critical tasks,
|
||||
such as initializing the per-module locks.
|
||||
|
||||
.. deprecated:: 3.4
|
||||
|
||||
|
||||
The following constants with integer values, defined in this module, are used
|
||||
to indicate the search result of :func:`find_module`.
|
||||
|
||||
|
||||
.. data:: PY_SOURCE
|
||||
|
||||
The module was found as a source file.
|
||||
|
||||
.. deprecated:: 3.3
|
||||
|
||||
|
||||
.. data:: PY_COMPILED
|
||||
|
||||
The module was found as a compiled code object file.
|
||||
|
||||
.. deprecated:: 3.3
|
||||
|
||||
|
||||
.. data:: C_EXTENSION
|
||||
|
||||
The module was found as dynamically loadable shared library.
|
||||
|
||||
.. deprecated:: 3.3
|
||||
|
||||
|
||||
.. data:: PKG_DIRECTORY
|
||||
|
||||
The module was found as a package directory.
|
||||
|
||||
.. deprecated:: 3.3
|
||||
|
||||
|
||||
.. data:: C_BUILTIN
|
||||
|
||||
The module was found as a built-in module.
|
||||
|
||||
.. deprecated:: 3.3
|
||||
|
||||
|
||||
.. data:: PY_FROZEN
|
||||
|
||||
The module was found as a frozen module.
|
||||
|
||||
.. deprecated:: 3.3
|
||||
|
||||
|
||||
.. class:: NullImporter(path_string)
|
||||
|
||||
The :class:`NullImporter` type is a :pep:`302` import hook that handles
|
||||
non-directory path strings by failing to find any modules. Calling this type
|
||||
with an existing directory or empty string raises :exc:`ImportError`.
|
||||
Otherwise, a :class:`NullImporter` instance is returned.
|
||||
|
||||
Instances have only one method:
|
||||
|
||||
.. method:: NullImporter.find_module(fullname [, path])
|
||||
|
||||
This method always returns ``None``, indicating that the requested module could
|
||||
not be found.
|
||||
|
||||
.. versionchanged:: 3.3
|
||||
``None`` is inserted into ``sys.path_importer_cache`` instead of an
|
||||
instance of :class:`NullImporter`.
|
||||
|
||||
.. deprecated:: 3.4
|
||||
Insert ``None`` into ``sys.path_importer_cache`` instead.
|
||||
|
||||
|
||||
.. _examples-imp:
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
The following function emulates what was the standard import statement up to
|
||||
Python 1.4 (no hierarchical module names). (This *implementation* wouldn't work
|
||||
in that version, since :func:`find_module` has been extended and
|
||||
:func:`load_module` has been added in 1.4.) ::
|
||||
|
||||
import imp
|
||||
import sys
|
||||
|
||||
def __import__(name, globals=None, locals=None, fromlist=None):
|
||||
# Fast path: see if the module has already been imported.
|
||||
try:
|
||||
return sys.modules[name]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
# If any of the following calls raises an exception,
|
||||
# there's a problem we can't handle -- let the caller handle it.
|
||||
|
||||
fp, pathname, description = imp.find_module(name)
|
||||
|
||||
try:
|
||||
return imp.load_module(name, fp, pathname, description)
|
||||
finally:
|
||||
# Since we may exit via an exception, close fp explicitly.
|
||||
if fp:
|
||||
fp.close()
|
|
@ -17,7 +17,6 @@ backwards compatibility. They have been superseded by other modules.
|
|||
chunk.rst
|
||||
crypt.rst
|
||||
imghdr.rst
|
||||
imp.rst
|
||||
mailcap.rst
|
||||
msilib.rst
|
||||
nis.rst
|
||||
|
|
|
@ -1253,10 +1253,6 @@ always available.
|
|||
|
||||
Originally specified in :pep:`302`.
|
||||
|
||||
.. versionchanged:: 3.3
|
||||
``None`` is stored instead of :class:`imp.NullImporter` when no finder
|
||||
is found.
|
||||
|
||||
|
||||
.. data:: platform
|
||||
|
||||
|
|
|
@ -1077,4 +1077,5 @@ methods to finders and loaders.
|
|||
.. [#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.
|
||||
:ref:`portingpythoncode` for more details. Note that the ``imp`` module
|
||||
was removed in Python 3.12.
|
||||
|
|
|
@ -149,7 +149,6 @@ Doc/library/http.cookiejar.rst
|
|||
Doc/library/http.cookies.rst
|
||||
Doc/library/http.server.rst
|
||||
Doc/library/idle.rst
|
||||
Doc/library/imp.rst
|
||||
Doc/library/importlib.resources.abc.rst
|
||||
Doc/library/importlib.resources.rst
|
||||
Doc/library/importlib.rst
|
||||
|
|
|
@ -961,11 +961,14 @@ Removed
|
|||
completed:
|
||||
|
||||
* References to, and support for ``module_repr()`` has been eradicated.
|
||||
|
||||
(Contributed by Barry Warsaw in :gh:`97850`.)
|
||||
|
||||
* ``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`.)
|
||||
|
||||
* Removed the ``suspicious`` rule from the documentation Makefile, and
|
||||
removed ``Doc/tools/rstlint.py``, both in favor of `sphinx-lint
|
||||
<https://github.com/sphinx-contrib/sphinx-lint>`_.
|
||||
|
|
346
Lib/imp.py
346
Lib/imp.py
|
@ -1,346 +0,0 @@
|
|||
"""This module provides the components needed to build your own __import__
|
||||
function. Undocumented functions are obsolete.
|
||||
|
||||
In most cases it is preferred you consider using the importlib module's
|
||||
functionality over this module.
|
||||
|
||||
"""
|
||||
# (Probably) need to stay in _imp
|
||||
from _imp import (lock_held, acquire_lock, release_lock,
|
||||
get_frozen_object, is_frozen_package,
|
||||
init_frozen, is_builtin, is_frozen,
|
||||
_fix_co_filename, _frozen_module_names)
|
||||
try:
|
||||
from _imp import create_dynamic
|
||||
except ImportError:
|
||||
# Platform doesn't support dynamic loading.
|
||||
create_dynamic = None
|
||||
|
||||
from importlib._bootstrap import _ERR_MSG, _exec, _load, _builtin_from_name
|
||||
from importlib._bootstrap_external import SourcelessFileLoader
|
||||
|
||||
from importlib import machinery
|
||||
from importlib import util
|
||||
import importlib
|
||||
import os
|
||||
import sys
|
||||
import tokenize
|
||||
import types
|
||||
import warnings
|
||||
|
||||
warnings.warn("the imp module is deprecated in favour of importlib and slated "
|
||||
"for removal in Python 3.12; "
|
||||
"see the module's documentation for alternative uses",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
|
||||
# DEPRECATED
|
||||
SEARCH_ERROR = 0
|
||||
PY_SOURCE = 1
|
||||
PY_COMPILED = 2
|
||||
C_EXTENSION = 3
|
||||
PY_RESOURCE = 4
|
||||
PKG_DIRECTORY = 5
|
||||
C_BUILTIN = 6
|
||||
PY_FROZEN = 7
|
||||
PY_CODERESOURCE = 8
|
||||
IMP_HOOK = 9
|
||||
|
||||
|
||||
def new_module(name):
|
||||
"""**DEPRECATED**
|
||||
|
||||
Create a new module.
|
||||
|
||||
The module is not entered into sys.modules.
|
||||
|
||||
"""
|
||||
return types.ModuleType(name)
|
||||
|
||||
|
||||
def get_magic():
|
||||
"""**DEPRECATED**
|
||||
|
||||
Return the magic number for .pyc files.
|
||||
"""
|
||||
return util.MAGIC_NUMBER
|
||||
|
||||
|
||||
def get_tag():
|
||||
"""Return the magic tag for .pyc files."""
|
||||
return sys.implementation.cache_tag
|
||||
|
||||
|
||||
def cache_from_source(path, debug_override=None):
|
||||
"""**DEPRECATED**
|
||||
|
||||
Given the path to a .py file, return the path to its .pyc file.
|
||||
|
||||
The .py file does not need to exist; this simply returns the path to the
|
||||
.pyc file calculated as if the .py file were imported.
|
||||
|
||||
If debug_override is not None, then it must be a boolean and is used in
|
||||
place of sys.flags.optimize.
|
||||
|
||||
If sys.implementation.cache_tag is None then NotImplementedError is raised.
|
||||
|
||||
"""
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore')
|
||||
return util.cache_from_source(path, debug_override)
|
||||
|
||||
|
||||
def source_from_cache(path):
|
||||
"""**DEPRECATED**
|
||||
|
||||
Given the path to a .pyc. file, return the path to its .py file.
|
||||
|
||||
The .pyc file does not need to exist; this simply returns the path to
|
||||
the .py file calculated to correspond to the .pyc file. If path does
|
||||
not conform to PEP 3147 format, ValueError will be raised. If
|
||||
sys.implementation.cache_tag is None then NotImplementedError is raised.
|
||||
|
||||
"""
|
||||
return util.source_from_cache(path)
|
||||
|
||||
|
||||
def get_suffixes():
|
||||
"""**DEPRECATED**"""
|
||||
extensions = [(s, 'rb', C_EXTENSION) for s in machinery.EXTENSION_SUFFIXES]
|
||||
source = [(s, 'r', PY_SOURCE) for s in machinery.SOURCE_SUFFIXES]
|
||||
bytecode = [(s, 'rb', PY_COMPILED) for s in machinery.BYTECODE_SUFFIXES]
|
||||
|
||||
return extensions + source + bytecode
|
||||
|
||||
|
||||
class NullImporter:
|
||||
|
||||
"""**DEPRECATED**
|
||||
|
||||
Null import object.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, path):
|
||||
if path == '':
|
||||
raise ImportError('empty pathname', path='')
|
||||
elif os.path.isdir(path):
|
||||
raise ImportError('existing directory', path=path)
|
||||
|
||||
def find_module(self, fullname):
|
||||
"""Always returns None."""
|
||||
return None
|
||||
|
||||
|
||||
class _HackedGetData:
|
||||
|
||||
"""Compatibility support for 'file' arguments of various load_*()
|
||||
functions."""
|
||||
|
||||
def __init__(self, fullname, path, file=None):
|
||||
super().__init__(fullname, path)
|
||||
self.file = file
|
||||
|
||||
def get_data(self, path):
|
||||
"""Gross hack to contort loader to deal w/ load_*()'s bad API."""
|
||||
if self.file and path == self.path:
|
||||
# The contract of get_data() requires us to return bytes. Reopen the
|
||||
# file in binary mode if needed.
|
||||
if not self.file.closed:
|
||||
file = self.file
|
||||
if 'b' not in file.mode:
|
||||
file.close()
|
||||
if self.file.closed:
|
||||
self.file = file = open(self.path, 'rb')
|
||||
|
||||
with file:
|
||||
return file.read()
|
||||
else:
|
||||
return super().get_data(path)
|
||||
|
||||
|
||||
class _LoadSourceCompatibility(_HackedGetData, machinery.SourceFileLoader):
|
||||
|
||||
"""Compatibility support for implementing load_source()."""
|
||||
|
||||
|
||||
def load_source(name, pathname, file=None):
|
||||
loader = _LoadSourceCompatibility(name, pathname, file)
|
||||
spec = util.spec_from_file_location(name, pathname, loader=loader)
|
||||
if name in sys.modules:
|
||||
module = _exec(spec, sys.modules[name])
|
||||
else:
|
||||
module = _load(spec)
|
||||
# To allow reloading to potentially work, use a non-hacked loader which
|
||||
# won't rely on a now-closed file object.
|
||||
module.__loader__ = machinery.SourceFileLoader(name, pathname)
|
||||
module.__spec__.loader = module.__loader__
|
||||
return module
|
||||
|
||||
|
||||
class _LoadCompiledCompatibility(_HackedGetData, SourcelessFileLoader):
|
||||
|
||||
"""Compatibility support for implementing load_compiled()."""
|
||||
|
||||
|
||||
def load_compiled(name, pathname, file=None):
|
||||
"""**DEPRECATED**"""
|
||||
loader = _LoadCompiledCompatibility(name, pathname, file)
|
||||
spec = util.spec_from_file_location(name, pathname, loader=loader)
|
||||
if name in sys.modules:
|
||||
module = _exec(spec, sys.modules[name])
|
||||
else:
|
||||
module = _load(spec)
|
||||
# To allow reloading to potentially work, use a non-hacked loader which
|
||||
# won't rely on a now-closed file object.
|
||||
module.__loader__ = SourcelessFileLoader(name, pathname)
|
||||
module.__spec__.loader = module.__loader__
|
||||
return module
|
||||
|
||||
|
||||
def load_package(name, path):
|
||||
"""**DEPRECATED**"""
|
||||
if os.path.isdir(path):
|
||||
extensions = (machinery.SOURCE_SUFFIXES[:] +
|
||||
machinery.BYTECODE_SUFFIXES[:])
|
||||
for extension in extensions:
|
||||
init_path = os.path.join(path, '__init__' + extension)
|
||||
if os.path.exists(init_path):
|
||||
path = init_path
|
||||
break
|
||||
else:
|
||||
raise ValueError('{!r} is not a package'.format(path))
|
||||
spec = util.spec_from_file_location(name, path,
|
||||
submodule_search_locations=[])
|
||||
if name in sys.modules:
|
||||
return _exec(spec, sys.modules[name])
|
||||
else:
|
||||
return _load(spec)
|
||||
|
||||
|
||||
def load_module(name, file, filename, details):
|
||||
"""**DEPRECATED**
|
||||
|
||||
Load a module, given information returned by find_module().
|
||||
|
||||
The module name must include the full package name, if any.
|
||||
|
||||
"""
|
||||
suffix, mode, type_ = details
|
||||
if mode and (not mode.startswith('r') or '+' in mode):
|
||||
raise ValueError('invalid file open mode {!r}'.format(mode))
|
||||
elif file is None and type_ in {PY_SOURCE, PY_COMPILED}:
|
||||
msg = 'file object required for import (type code {})'.format(type_)
|
||||
raise ValueError(msg)
|
||||
elif type_ == PY_SOURCE:
|
||||
return load_source(name, filename, file)
|
||||
elif type_ == PY_COMPILED:
|
||||
return load_compiled(name, filename, file)
|
||||
elif type_ == C_EXTENSION and load_dynamic is not None:
|
||||
if file is None:
|
||||
with open(filename, 'rb') as opened_file:
|
||||
return load_dynamic(name, filename, opened_file)
|
||||
else:
|
||||
return load_dynamic(name, filename, file)
|
||||
elif type_ == PKG_DIRECTORY:
|
||||
return load_package(name, filename)
|
||||
elif type_ == C_BUILTIN:
|
||||
return init_builtin(name)
|
||||
elif type_ == PY_FROZEN:
|
||||
return init_frozen(name)
|
||||
else:
|
||||
msg = "Don't know how to import {} (type code {})".format(name, type_)
|
||||
raise ImportError(msg, name=name)
|
||||
|
||||
|
||||
def find_module(name, path=None):
|
||||
"""**DEPRECATED**
|
||||
|
||||
Search for a module.
|
||||
|
||||
If path is omitted or None, search for a built-in, frozen or special
|
||||
module and continue search in sys.path. The module name cannot
|
||||
contain '.'; to search for a submodule of a package, pass the
|
||||
submodule name and the package's __path__.
|
||||
|
||||
"""
|
||||
if not isinstance(name, str):
|
||||
raise TypeError("'name' must be a str, not {}".format(type(name)))
|
||||
elif not isinstance(path, (type(None), list)):
|
||||
# Backwards-compatibility
|
||||
raise RuntimeError("'path' must be None or a list, "
|
||||
"not {}".format(type(path)))
|
||||
|
||||
if path is None:
|
||||
if is_builtin(name):
|
||||
return None, None, ('', '', C_BUILTIN)
|
||||
elif is_frozen(name):
|
||||
return None, None, ('', '', PY_FROZEN)
|
||||
else:
|
||||
path = sys.path
|
||||
|
||||
for entry in path:
|
||||
package_directory = os.path.join(entry, name)
|
||||
for suffix in ['.py', machinery.BYTECODE_SUFFIXES[0]]:
|
||||
package_file_name = '__init__' + suffix
|
||||
file_path = os.path.join(package_directory, package_file_name)
|
||||
if os.path.isfile(file_path):
|
||||
return None, package_directory, ('', '', PKG_DIRECTORY)
|
||||
for suffix, mode, type_ in get_suffixes():
|
||||
file_name = name + suffix
|
||||
file_path = os.path.join(entry, file_name)
|
||||
if os.path.isfile(file_path):
|
||||
break
|
||||
else:
|
||||
continue
|
||||
break # Break out of outer loop when breaking out of inner loop.
|
||||
else:
|
||||
raise ImportError(_ERR_MSG.format(name), name=name)
|
||||
|
||||
encoding = None
|
||||
if 'b' not in mode:
|
||||
with open(file_path, 'rb') as file:
|
||||
encoding = tokenize.detect_encoding(file.readline)[0]
|
||||
file = open(file_path, mode, encoding=encoding)
|
||||
return file, file_path, (suffix, mode, type_)
|
||||
|
||||
|
||||
def reload(module):
|
||||
"""**DEPRECATED**
|
||||
|
||||
Reload the module and return it.
|
||||
|
||||
The module must have been successfully imported before.
|
||||
|
||||
"""
|
||||
return importlib.reload(module)
|
||||
|
||||
|
||||
def init_builtin(name):
|
||||
"""**DEPRECATED**
|
||||
|
||||
Load and return a built-in module by name, or None is such module doesn't
|
||||
exist
|
||||
"""
|
||||
try:
|
||||
return _builtin_from_name(name)
|
||||
except ImportError:
|
||||
return None
|
||||
|
||||
|
||||
if create_dynamic:
|
||||
def load_dynamic(name, path, file=None):
|
||||
"""**DEPRECATED**
|
||||
|
||||
Load an extension module.
|
||||
"""
|
||||
import importlib.machinery
|
||||
loader = importlib.machinery.ExtensionFileLoader(name, path)
|
||||
|
||||
# Issue #24748: Skip the sys.modules check in _load_module_shim;
|
||||
# always load new extension
|
||||
spec = importlib.util.spec_from_file_location(
|
||||
name, path, loader=loader)
|
||||
return _load(spec)
|
||||
|
||||
else:
|
||||
load_dynamic = None
|
183
Lib/pkgutil.py
183
Lib/pkgutil.py
|
@ -14,7 +14,7 @@
|
|||
__all__ = [
|
||||
'get_importer', 'iter_importers', 'get_loader', 'find_loader',
|
||||
'walk_packages', 'iter_modules', 'get_data',
|
||||
'ImpImporter', 'ImpLoader', 'read_code', 'extend_path',
|
||||
'read_code', 'extend_path',
|
||||
'ModuleInfo',
|
||||
]
|
||||
|
||||
|
@ -185,187 +185,6 @@ def _iter_file_finder_modules(importer, prefix=''):
|
|||
importlib.machinery.FileFinder, _iter_file_finder_modules)
|
||||
|
||||
|
||||
def _import_imp():
|
||||
global imp
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
imp = importlib.import_module('imp')
|
||||
|
||||
class ImpImporter:
|
||||
"""PEP 302 Finder that wraps Python's "classic" import algorithm
|
||||
|
||||
ImpImporter(dirname) produces a PEP 302 finder that searches that
|
||||
directory. ImpImporter(None) produces a PEP 302 finder that searches
|
||||
the current sys.path, plus any modules that are frozen or built-in.
|
||||
|
||||
Note that ImpImporter does not currently support being used by placement
|
||||
on sys.meta_path.
|
||||
"""
|
||||
|
||||
def __init__(self, path=None):
|
||||
global imp
|
||||
warnings.warn("This emulation is deprecated and slated for removal "
|
||||
"in Python 3.12; use 'importlib' instead",
|
||||
DeprecationWarning)
|
||||
_import_imp()
|
||||
self.path = path
|
||||
|
||||
def find_module(self, fullname, path=None):
|
||||
# Note: we ignore 'path' argument since it is only used via meta_path
|
||||
subname = fullname.split(".")[-1]
|
||||
if subname != fullname and self.path is None:
|
||||
return None
|
||||
if self.path is None:
|
||||
path = None
|
||||
else:
|
||||
path = [os.path.realpath(self.path)]
|
||||
try:
|
||||
file, filename, etc = imp.find_module(subname, path)
|
||||
except ImportError:
|
||||
return None
|
||||
return ImpLoader(fullname, file, filename, etc)
|
||||
|
||||
def iter_modules(self, prefix=''):
|
||||
if self.path is None or not os.path.isdir(self.path):
|
||||
return
|
||||
|
||||
yielded = {}
|
||||
import inspect
|
||||
try:
|
||||
filenames = os.listdir(self.path)
|
||||
except OSError:
|
||||
# ignore unreadable directories like import does
|
||||
filenames = []
|
||||
filenames.sort() # handle packages before same-named modules
|
||||
|
||||
for fn in filenames:
|
||||
modname = inspect.getmodulename(fn)
|
||||
if modname=='__init__' or modname in yielded:
|
||||
continue
|
||||
|
||||
path = os.path.join(self.path, fn)
|
||||
ispkg = False
|
||||
|
||||
if not modname and os.path.isdir(path) and '.' not in fn:
|
||||
modname = fn
|
||||
try:
|
||||
dircontents = os.listdir(path)
|
||||
except OSError:
|
||||
# ignore unreadable directories like import does
|
||||
dircontents = []
|
||||
for fn in dircontents:
|
||||
subname = inspect.getmodulename(fn)
|
||||
if subname=='__init__':
|
||||
ispkg = True
|
||||
break
|
||||
else:
|
||||
continue # not a package
|
||||
|
||||
if modname and '.' not in modname:
|
||||
yielded[modname] = 1
|
||||
yield prefix + modname, ispkg
|
||||
|
||||
|
||||
class ImpLoader:
|
||||
"""PEP 302 Loader that wraps Python's "classic" import algorithm
|
||||
"""
|
||||
code = source = None
|
||||
|
||||
def __init__(self, fullname, file, filename, etc):
|
||||
warnings.warn("This emulation is deprecated and slated for removal in "
|
||||
"Python 3.12; use 'importlib' instead",
|
||||
DeprecationWarning)
|
||||
_import_imp()
|
||||
self.file = file
|
||||
self.filename = filename
|
||||
self.fullname = fullname
|
||||
self.etc = etc
|
||||
|
||||
def load_module(self, fullname):
|
||||
self._reopen()
|
||||
try:
|
||||
mod = imp.load_module(fullname, self.file, self.filename, self.etc)
|
||||
finally:
|
||||
if self.file:
|
||||
self.file.close()
|
||||
# Note: we don't set __loader__ because we want the module to look
|
||||
# normal; i.e. this is just a wrapper for standard import machinery
|
||||
return mod
|
||||
|
||||
def get_data(self, pathname):
|
||||
with open(pathname, "rb") as file:
|
||||
return file.read()
|
||||
|
||||
def _reopen(self):
|
||||
if self.file and self.file.closed:
|
||||
mod_type = self.etc[2]
|
||||
if mod_type==imp.PY_SOURCE:
|
||||
self.file = open(self.filename, 'r')
|
||||
elif mod_type in (imp.PY_COMPILED, imp.C_EXTENSION):
|
||||
self.file = open(self.filename, 'rb')
|
||||
|
||||
def _fix_name(self, fullname):
|
||||
if fullname is None:
|
||||
fullname = self.fullname
|
||||
elif fullname != self.fullname:
|
||||
raise ImportError("Loader for module %s cannot handle "
|
||||
"module %s" % (self.fullname, fullname))
|
||||
return fullname
|
||||
|
||||
def is_package(self, fullname):
|
||||
fullname = self._fix_name(fullname)
|
||||
return self.etc[2]==imp.PKG_DIRECTORY
|
||||
|
||||
def get_code(self, fullname=None):
|
||||
fullname = self._fix_name(fullname)
|
||||
if self.code is None:
|
||||
mod_type = self.etc[2]
|
||||
if mod_type==imp.PY_SOURCE:
|
||||
source = self.get_source(fullname)
|
||||
self.code = compile(source, self.filename, 'exec')
|
||||
elif mod_type==imp.PY_COMPILED:
|
||||
self._reopen()
|
||||
try:
|
||||
self.code = read_code(self.file)
|
||||
finally:
|
||||
self.file.close()
|
||||
elif mod_type==imp.PKG_DIRECTORY:
|
||||
self.code = self._get_delegate().get_code()
|
||||
return self.code
|
||||
|
||||
def get_source(self, fullname=None):
|
||||
fullname = self._fix_name(fullname)
|
||||
if self.source is None:
|
||||
mod_type = self.etc[2]
|
||||
if mod_type==imp.PY_SOURCE:
|
||||
self._reopen()
|
||||
try:
|
||||
self.source = self.file.read()
|
||||
finally:
|
||||
self.file.close()
|
||||
elif mod_type==imp.PY_COMPILED:
|
||||
if os.path.exists(self.filename[:-1]):
|
||||
with open(self.filename[:-1], 'r') as f:
|
||||
self.source = f.read()
|
||||
elif mod_type==imp.PKG_DIRECTORY:
|
||||
self.source = self._get_delegate().get_source()
|
||||
return self.source
|
||||
|
||||
def _get_delegate(self):
|
||||
finder = ImpImporter(self.filename)
|
||||
spec = _get_spec(finder, '__init__')
|
||||
return spec.loader
|
||||
|
||||
def get_filename(self, fullname=None):
|
||||
fullname = self._fix_name(fullname)
|
||||
mod_type = self.etc[2]
|
||||
if mod_type==imp.PKG_DIRECTORY:
|
||||
return self._get_delegate().get_filename()
|
||||
elif mod_type in (imp.PY_SOURCE, imp.PY_COMPILED, imp.C_EXTENSION):
|
||||
return self.filename
|
||||
return None
|
||||
|
||||
|
||||
try:
|
||||
import zipimport
|
||||
from zipimport import zipimporter
|
||||
|
|
|
@ -512,7 +512,7 @@ def getdocloc(self, object, basedir=sysconfig.get_path('stdlib')):
|
|||
|
||||
basedir = os.path.normcase(basedir)
|
||||
if (isinstance(object, type(os)) and
|
||||
(object.__name__ in ('errno', 'exceptions', 'gc', 'imp',
|
||||
(object.__name__ in ('errno', 'exceptions', 'gc',
|
||||
'marshal', 'posix', 'signal', 'sys',
|
||||
'_thread', 'zipimport') or
|
||||
(file.startswith(basedir) and
|
||||
|
|
|
@ -279,12 +279,7 @@ def run_path(path_name, init_globals=None, run_name=None):
|
|||
pkg_name = run_name.rpartition(".")[0]
|
||||
from pkgutil import get_importer
|
||||
importer = get_importer(path_name)
|
||||
# Trying to avoid importing imp so as to not consume the deprecation warning.
|
||||
is_NullImporter = False
|
||||
if type(importer).__module__ == 'imp':
|
||||
if type(importer).__name__ == 'NullImporter':
|
||||
is_NullImporter = True
|
||||
if isinstance(importer, type(None)) or is_NullImporter:
|
||||
if isinstance(importer, type(None)):
|
||||
# Not a valid sys.path entry, so run the code directly
|
||||
# execfile() doesn't help as we want to allow compiled files
|
||||
code, fname = _get_code_from_file(run_name, path_name)
|
||||
|
|
|
@ -1,524 +0,0 @@
|
|||
import gc
|
||||
import importlib
|
||||
import importlib.util
|
||||
import os
|
||||
import os.path
|
||||
import py_compile
|
||||
import sys
|
||||
from test import support
|
||||
from test.support import import_helper
|
||||
from test.support import os_helper
|
||||
from test.support import script_helper
|
||||
from test.support import warnings_helper
|
||||
import unittest
|
||||
import warnings
|
||||
imp = warnings_helper.import_deprecated('imp')
|
||||
import _imp
|
||||
|
||||
|
||||
OS_PATH_NAME = os.path.__name__
|
||||
|
||||
|
||||
def requires_load_dynamic(meth):
|
||||
"""Decorator to skip a test if not running under CPython or lacking
|
||||
imp.load_dynamic()."""
|
||||
meth = support.cpython_only(meth)
|
||||
return unittest.skipIf(getattr(imp, 'load_dynamic', None) is None,
|
||||
'imp.load_dynamic() required')(meth)
|
||||
|
||||
|
||||
class LockTests(unittest.TestCase):
|
||||
|
||||
"""Very basic test of import lock functions."""
|
||||
|
||||
def verify_lock_state(self, expected):
|
||||
self.assertEqual(imp.lock_held(), expected,
|
||||
"expected imp.lock_held() to be %r" % expected)
|
||||
def testLock(self):
|
||||
LOOPS = 50
|
||||
|
||||
# The import lock may already be held, e.g. if the test suite is run
|
||||
# via "import test.autotest".
|
||||
lock_held_at_start = imp.lock_held()
|
||||
self.verify_lock_state(lock_held_at_start)
|
||||
|
||||
for i in range(LOOPS):
|
||||
imp.acquire_lock()
|
||||
self.verify_lock_state(True)
|
||||
|
||||
for i in range(LOOPS):
|
||||
imp.release_lock()
|
||||
|
||||
# The original state should be restored now.
|
||||
self.verify_lock_state(lock_held_at_start)
|
||||
|
||||
if not lock_held_at_start:
|
||||
try:
|
||||
imp.release_lock()
|
||||
except RuntimeError:
|
||||
pass
|
||||
else:
|
||||
self.fail("release_lock() without lock should raise "
|
||||
"RuntimeError")
|
||||
|
||||
class ImportTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
mod = importlib.import_module('test.encoded_modules')
|
||||
self.test_strings = mod.test_strings
|
||||
self.test_path = mod.__path__
|
||||
|
||||
# test_import_encoded_module moved to test_source_encoding.py
|
||||
|
||||
def test_find_module_encoding(self):
|
||||
for mod, encoding, _ in self.test_strings:
|
||||
with imp.find_module('module_' + mod, self.test_path)[0] as fd:
|
||||
self.assertEqual(fd.encoding, encoding)
|
||||
|
||||
path = [os.path.dirname(__file__)]
|
||||
with self.assertRaises(SyntaxError):
|
||||
imp.find_module('badsyntax_pep3120', path)
|
||||
|
||||
def test_issue1267(self):
|
||||
for mod, encoding, _ in self.test_strings:
|
||||
fp, filename, info = imp.find_module('module_' + mod,
|
||||
self.test_path)
|
||||
with fp:
|
||||
self.assertNotEqual(fp, None)
|
||||
self.assertEqual(fp.encoding, encoding)
|
||||
self.assertEqual(fp.tell(), 0)
|
||||
self.assertEqual(fp.readline(), '# test %s encoding\n'
|
||||
% encoding)
|
||||
|
||||
fp, filename, info = imp.find_module("tokenize")
|
||||
with fp:
|
||||
self.assertNotEqual(fp, None)
|
||||
self.assertEqual(fp.encoding, "utf-8")
|
||||
self.assertEqual(fp.tell(), 0)
|
||||
self.assertEqual(fp.readline(),
|
||||
'"""Tokenization help for Python programs.\n')
|
||||
|
||||
def test_issue3594(self):
|
||||
temp_mod_name = 'test_imp_helper'
|
||||
sys.path.insert(0, '.')
|
||||
try:
|
||||
with open(temp_mod_name + '.py', 'w', encoding="latin-1") as file:
|
||||
file.write("# coding: cp1252\nu = 'test.test_imp'\n")
|
||||
file, filename, info = imp.find_module(temp_mod_name)
|
||||
file.close()
|
||||
self.assertEqual(file.encoding, 'cp1252')
|
||||
finally:
|
||||
del sys.path[0]
|
||||
os_helper.unlink(temp_mod_name + '.py')
|
||||
os_helper.unlink(temp_mod_name + '.pyc')
|
||||
|
||||
def test_issue5604(self):
|
||||
# Test cannot cover imp.load_compiled function.
|
||||
# Martin von Loewis note what shared library cannot have non-ascii
|
||||
# character because init_xxx function cannot be compiled
|
||||
# and issue never happens for dynamic modules.
|
||||
# But sources modified to follow generic way for processing paths.
|
||||
|
||||
# the return encoding could be uppercase or None
|
||||
fs_encoding = sys.getfilesystemencoding()
|
||||
|
||||
# covers utf-8 and Windows ANSI code pages
|
||||
# one non-space symbol from every page
|
||||
# (http://en.wikipedia.org/wiki/Code_page)
|
||||
known_locales = {
|
||||
'utf-8' : b'\xc3\xa4',
|
||||
'cp1250' : b'\x8C',
|
||||
'cp1251' : b'\xc0',
|
||||
'cp1252' : b'\xc0',
|
||||
'cp1253' : b'\xc1',
|
||||
'cp1254' : b'\xc0',
|
||||
'cp1255' : b'\xe0',
|
||||
'cp1256' : b'\xe0',
|
||||
'cp1257' : b'\xc0',
|
||||
'cp1258' : b'\xc0',
|
||||
}
|
||||
|
||||
if sys.platform == 'darwin':
|
||||
self.assertEqual(fs_encoding, 'utf-8')
|
||||
# Mac OS X uses the Normal Form D decomposition
|
||||
# http://developer.apple.com/mac/library/qa/qa2001/qa1173.html
|
||||
special_char = b'a\xcc\x88'
|
||||
else:
|
||||
special_char = known_locales.get(fs_encoding)
|
||||
|
||||
if not special_char:
|
||||
self.skipTest("can't run this test with %s as filesystem encoding"
|
||||
% fs_encoding)
|
||||
decoded_char = special_char.decode(fs_encoding)
|
||||
temp_mod_name = 'test_imp_helper_' + decoded_char
|
||||
test_package_name = 'test_imp_helper_package_' + decoded_char
|
||||
init_file_name = os.path.join(test_package_name, '__init__.py')
|
||||
try:
|
||||
# if the curdir is not in sys.path the test fails when run with
|
||||
# ./python ./Lib/test/regrtest.py test_imp
|
||||
sys.path.insert(0, os.curdir)
|
||||
with open(temp_mod_name + '.py', 'w', encoding="utf-8") as file:
|
||||
file.write('a = 1\n')
|
||||
file, filename, info = imp.find_module(temp_mod_name)
|
||||
with file:
|
||||
self.assertIsNotNone(file)
|
||||
self.assertTrue(filename[:-3].endswith(temp_mod_name))
|
||||
self.assertEqual(info[0], '.py')
|
||||
self.assertEqual(info[1], 'r')
|
||||
self.assertEqual(info[2], imp.PY_SOURCE)
|
||||
|
||||
mod = imp.load_module(temp_mod_name, file, filename, info)
|
||||
self.assertEqual(mod.a, 1)
|
||||
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore')
|
||||
mod = imp.load_source(temp_mod_name, temp_mod_name + '.py')
|
||||
self.assertEqual(mod.a, 1)
|
||||
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore')
|
||||
if not sys.dont_write_bytecode:
|
||||
mod = imp.load_compiled(
|
||||
temp_mod_name,
|
||||
imp.cache_from_source(temp_mod_name + '.py'))
|
||||
self.assertEqual(mod.a, 1)
|
||||
|
||||
if not os.path.exists(test_package_name):
|
||||
os.mkdir(test_package_name)
|
||||
with open(init_file_name, 'w', encoding="utf-8") as file:
|
||||
file.write('b = 2\n')
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore')
|
||||
package = imp.load_package(test_package_name, test_package_name)
|
||||
self.assertEqual(package.b, 2)
|
||||
finally:
|
||||
del sys.path[0]
|
||||
for ext in ('.py', '.pyc'):
|
||||
os_helper.unlink(temp_mod_name + ext)
|
||||
os_helper.unlink(init_file_name + ext)
|
||||
os_helper.rmtree(test_package_name)
|
||||
os_helper.rmtree('__pycache__')
|
||||
|
||||
def test_issue9319(self):
|
||||
path = os.path.dirname(__file__)
|
||||
self.assertRaises(SyntaxError,
|
||||
imp.find_module, "badsyntax_pep3120", [path])
|
||||
|
||||
def test_load_from_source(self):
|
||||
# Verify that the imp module can correctly load and find .py files
|
||||
# XXX (ncoghlan): It would be nice to use import_helper.CleanImport
|
||||
# here, but that breaks because the os module registers some
|
||||
# handlers in copy_reg on import. Since CleanImport doesn't
|
||||
# revert that registration, the module is left in a broken
|
||||
# state after reversion. Reinitialising the module contents
|
||||
# and just reverting os.environ to its previous state is an OK
|
||||
# workaround
|
||||
with import_helper.CleanImport('os', 'os.path', OS_PATH_NAME):
|
||||
import os
|
||||
orig_path = os.path
|
||||
orig_getenv = os.getenv
|
||||
with os_helper.EnvironmentVarGuard():
|
||||
x = imp.find_module("os")
|
||||
self.addCleanup(x[0].close)
|
||||
new_os = imp.load_module("os", *x)
|
||||
self.assertIs(os, new_os)
|
||||
self.assertIs(orig_path, new_os.path)
|
||||
self.assertIsNot(orig_getenv, new_os.getenv)
|
||||
|
||||
@requires_load_dynamic
|
||||
def test_issue15828_load_extensions(self):
|
||||
# Issue 15828 picked up that the adapter between the old imp API
|
||||
# and importlib couldn't handle C extensions
|
||||
example = "_heapq"
|
||||
x = imp.find_module(example)
|
||||
file_ = x[0]
|
||||
if file_ is not None:
|
||||
self.addCleanup(file_.close)
|
||||
mod = imp.load_module(example, *x)
|
||||
self.assertEqual(mod.__name__, example)
|
||||
|
||||
@requires_load_dynamic
|
||||
def test_issue16421_multiple_modules_in_one_dll(self):
|
||||
# Issue 16421: loading several modules from the same compiled file fails
|
||||
m = '_testimportmultiple'
|
||||
fileobj, pathname, description = imp.find_module(m)
|
||||
fileobj.close()
|
||||
mod0 = imp.load_dynamic(m, pathname)
|
||||
mod1 = imp.load_dynamic('_testimportmultiple_foo', pathname)
|
||||
mod2 = imp.load_dynamic('_testimportmultiple_bar', pathname)
|
||||
self.assertEqual(mod0.__name__, m)
|
||||
self.assertEqual(mod1.__name__, '_testimportmultiple_foo')
|
||||
self.assertEqual(mod2.__name__, '_testimportmultiple_bar')
|
||||
with self.assertRaises(ImportError):
|
||||
imp.load_dynamic('nonexistent', pathname)
|
||||
|
||||
@requires_load_dynamic
|
||||
def test_load_dynamic_ImportError_path(self):
|
||||
# Issue #1559549 added `name` and `path` attributes to ImportError
|
||||
# in order to provide better detail. Issue #10854 implemented those
|
||||
# attributes on import failures of extensions on Windows.
|
||||
path = 'bogus file path'
|
||||
name = 'extension'
|
||||
with self.assertRaises(ImportError) as err:
|
||||
imp.load_dynamic(name, path)
|
||||
self.assertIn(path, err.exception.path)
|
||||
self.assertEqual(name, err.exception.name)
|
||||
|
||||
@requires_load_dynamic
|
||||
def test_load_module_extension_file_is_None(self):
|
||||
# When loading an extension module and the file is None, open one
|
||||
# on the behalf of imp.load_dynamic().
|
||||
# Issue #15902
|
||||
name = '_testimportmultiple'
|
||||
found = imp.find_module(name)
|
||||
if found[0] is not None:
|
||||
found[0].close()
|
||||
if found[2][2] != imp.C_EXTENSION:
|
||||
self.skipTest("found module doesn't appear to be a C extension")
|
||||
imp.load_module(name, None, *found[1:])
|
||||
|
||||
@requires_load_dynamic
|
||||
def test_issue24748_load_module_skips_sys_modules_check(self):
|
||||
name = 'test.imp_dummy'
|
||||
try:
|
||||
del sys.modules[name]
|
||||
except KeyError:
|
||||
pass
|
||||
try:
|
||||
module = importlib.import_module(name)
|
||||
spec = importlib.util.find_spec('_testmultiphase')
|
||||
module = imp.load_dynamic(name, spec.origin)
|
||||
self.assertEqual(module.__name__, name)
|
||||
self.assertEqual(module.__spec__.name, name)
|
||||
self.assertEqual(module.__spec__.origin, spec.origin)
|
||||
self.assertRaises(AttributeError, getattr, module, 'dummy_name')
|
||||
self.assertEqual(module.int_const, 1969)
|
||||
self.assertIs(sys.modules[name], module)
|
||||
finally:
|
||||
try:
|
||||
del sys.modules[name]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
@unittest.skipIf(sys.dont_write_bytecode,
|
||||
"test meaningful only when writing bytecode")
|
||||
def test_bug7732(self):
|
||||
with os_helper.temp_cwd():
|
||||
source = os_helper.TESTFN + '.py'
|
||||
os.mkdir(source)
|
||||
self.assertRaisesRegex(ImportError, '^No module',
|
||||
imp.find_module, os_helper.TESTFN, ["."])
|
||||
|
||||
def test_multiple_calls_to_get_data(self):
|
||||
# Issue #18755: make sure multiple calls to get_data() can succeed.
|
||||
loader = imp._LoadSourceCompatibility('imp', imp.__file__,
|
||||
open(imp.__file__, encoding="utf-8"))
|
||||
loader.get_data(imp.__file__) # File should be closed
|
||||
loader.get_data(imp.__file__) # Will need to create a newly opened file
|
||||
|
||||
def test_load_source(self):
|
||||
# Create a temporary module since load_source(name) modifies
|
||||
# sys.modules[name] attributes like __loader___
|
||||
modname = f"tmp{__name__}"
|
||||
mod = type(sys.modules[__name__])(modname)
|
||||
with support.swap_item(sys.modules, modname, mod):
|
||||
with self.assertRaisesRegex(ValueError, 'embedded null'):
|
||||
imp.load_source(modname, __file__ + "\0")
|
||||
|
||||
@support.cpython_only
|
||||
def test_issue31315(self):
|
||||
# There shouldn't be an assertion failure in imp.create_dynamic(),
|
||||
# when spec.name is not a string.
|
||||
create_dynamic = support.get_attribute(imp, 'create_dynamic')
|
||||
class BadSpec:
|
||||
name = None
|
||||
origin = 'foo'
|
||||
with self.assertRaises(TypeError):
|
||||
create_dynamic(BadSpec())
|
||||
|
||||
def test_issue_35321(self):
|
||||
# Both _frozen_importlib and _frozen_importlib_external
|
||||
# should have a spec origin of "frozen" and
|
||||
# no need to clean up imports in this case.
|
||||
|
||||
import _frozen_importlib_external
|
||||
self.assertEqual(_frozen_importlib_external.__spec__.origin, "frozen")
|
||||
|
||||
import _frozen_importlib
|
||||
self.assertEqual(_frozen_importlib.__spec__.origin, "frozen")
|
||||
|
||||
def test_source_hash(self):
|
||||
self.assertEqual(_imp.source_hash(42, b'hi'), b'\xfb\xd9G\x05\xaf$\x9b~')
|
||||
self.assertEqual(_imp.source_hash(43, b'hi'), b'\xd0/\x87C\xccC\xff\xe2')
|
||||
|
||||
def test_pyc_invalidation_mode_from_cmdline(self):
|
||||
cases = [
|
||||
([], "default"),
|
||||
(["--check-hash-based-pycs", "default"], "default"),
|
||||
(["--check-hash-based-pycs", "always"], "always"),
|
||||
(["--check-hash-based-pycs", "never"], "never"),
|
||||
]
|
||||
for interp_args, expected in cases:
|
||||
args = interp_args + [
|
||||
"-c",
|
||||
"import _imp; print(_imp.check_hash_based_pycs)",
|
||||
]
|
||||
res = script_helper.assert_python_ok(*args)
|
||||
self.assertEqual(res.out.strip().decode('utf-8'), expected)
|
||||
|
||||
def test_find_and_load_checked_pyc(self):
|
||||
# issue 34056
|
||||
with os_helper.temp_cwd():
|
||||
with open('mymod.py', 'wb') as fp:
|
||||
fp.write(b'x = 42\n')
|
||||
py_compile.compile(
|
||||
'mymod.py',
|
||||
doraise=True,
|
||||
invalidation_mode=py_compile.PycInvalidationMode.CHECKED_HASH,
|
||||
)
|
||||
file, path, description = imp.find_module('mymod', path=['.'])
|
||||
mod = imp.load_module('mymod', file, path, description)
|
||||
self.assertEqual(mod.x, 42)
|
||||
|
||||
def test_issue98354(self):
|
||||
# _imp.create_builtin should raise TypeError
|
||||
# if 'name' attribute of 'spec' argument is not a 'str' instance
|
||||
|
||||
create_builtin = support.get_attribute(_imp, "create_builtin")
|
||||
|
||||
class FakeSpec:
|
||||
def __init__(self, name):
|
||||
self.name = self
|
||||
spec = FakeSpec("time")
|
||||
with self.assertRaises(TypeError):
|
||||
create_builtin(spec)
|
||||
|
||||
class FakeSpec2:
|
||||
name = [1, 2, 3, 4]
|
||||
spec = FakeSpec2()
|
||||
with self.assertRaises(TypeError):
|
||||
create_builtin(spec)
|
||||
|
||||
import builtins
|
||||
class UnicodeSubclass(str):
|
||||
pass
|
||||
class GoodSpec:
|
||||
name = UnicodeSubclass("builtins")
|
||||
spec = GoodSpec()
|
||||
bltin = create_builtin(spec)
|
||||
self.assertEqual(bltin, builtins)
|
||||
|
||||
class UnicodeSubclassFakeSpec(str):
|
||||
def __init__(self, name):
|
||||
self.name = self
|
||||
spec = UnicodeSubclassFakeSpec("builtins")
|
||||
bltin = create_builtin(spec)
|
||||
self.assertEqual(bltin, builtins)
|
||||
|
||||
@support.cpython_only
|
||||
def test_create_builtin_subinterp(self):
|
||||
# gh-99578: create_builtin() behavior changes after the creation of the
|
||||
# first sub-interpreter. Test both code paths, before and after the
|
||||
# creation of a sub-interpreter. Previously, create_builtin() had
|
||||
# a reference leak after the creation of the first sub-interpreter.
|
||||
|
||||
import builtins
|
||||
create_builtin = support.get_attribute(_imp, "create_builtin")
|
||||
class Spec:
|
||||
name = "builtins"
|
||||
spec = Spec()
|
||||
|
||||
def check_get_builtins():
|
||||
refcnt = sys.getrefcount(builtins)
|
||||
mod = _imp.create_builtin(spec)
|
||||
self.assertIs(mod, builtins)
|
||||
self.assertEqual(sys.getrefcount(builtins), refcnt + 1)
|
||||
# Check that a GC collection doesn't crash
|
||||
gc.collect()
|
||||
|
||||
check_get_builtins()
|
||||
|
||||
ret = support.run_in_subinterp("import builtins")
|
||||
self.assertEqual(ret, 0)
|
||||
|
||||
check_get_builtins()
|
||||
|
||||
|
||||
class ReloadTests(unittest.TestCase):
|
||||
|
||||
"""Very basic tests to make sure that imp.reload() operates just like
|
||||
reload()."""
|
||||
|
||||
def test_source(self):
|
||||
# XXX (ncoghlan): It would be nice to use test.import_helper.CleanImport
|
||||
# here, but that breaks because the os module registers some
|
||||
# handlers in copy_reg on import. Since CleanImport doesn't
|
||||
# revert that registration, the module is left in a broken
|
||||
# state after reversion. Reinitialising the module contents
|
||||
# and just reverting os.environ to its previous state is an OK
|
||||
# workaround
|
||||
with os_helper.EnvironmentVarGuard():
|
||||
import os
|
||||
imp.reload(os)
|
||||
|
||||
def test_extension(self):
|
||||
with import_helper.CleanImport('time'):
|
||||
import time
|
||||
imp.reload(time)
|
||||
|
||||
def test_builtin(self):
|
||||
with import_helper.CleanImport('marshal'):
|
||||
import marshal
|
||||
imp.reload(marshal)
|
||||
|
||||
def test_with_deleted_parent(self):
|
||||
# see #18681
|
||||
from html import parser
|
||||
html = sys.modules.pop('html')
|
||||
def cleanup():
|
||||
sys.modules['html'] = html
|
||||
self.addCleanup(cleanup)
|
||||
with self.assertRaisesRegex(ImportError, 'html'):
|
||||
imp.reload(parser)
|
||||
|
||||
|
||||
class PEP3147Tests(unittest.TestCase):
|
||||
"""Tests of PEP 3147."""
|
||||
|
||||
tag = imp.get_tag()
|
||||
|
||||
@unittest.skipUnless(sys.implementation.cache_tag is not None,
|
||||
'requires sys.implementation.cache_tag not be None')
|
||||
def test_cache_from_source(self):
|
||||
# Given the path to a .py file, return the path to its PEP 3147
|
||||
# defined .pyc file (i.e. under __pycache__).
|
||||
path = os.path.join('foo', 'bar', 'baz', 'qux.py')
|
||||
expect = os.path.join('foo', 'bar', 'baz', '__pycache__',
|
||||
'qux.{}.pyc'.format(self.tag))
|
||||
self.assertEqual(imp.cache_from_source(path, True), expect)
|
||||
|
||||
@unittest.skipUnless(sys.implementation.cache_tag is not None,
|
||||
'requires sys.implementation.cache_tag to not be '
|
||||
'None')
|
||||
def test_source_from_cache(self):
|
||||
# Given the path to a PEP 3147 defined .pyc file, return the path to
|
||||
# its source. This tests the good path.
|
||||
path = os.path.join('foo', 'bar', 'baz', '__pycache__',
|
||||
'qux.{}.pyc'.format(self.tag))
|
||||
expect = os.path.join('foo', 'bar', 'baz', 'qux.py')
|
||||
self.assertEqual(imp.source_from_cache(path), expect)
|
||||
|
||||
|
||||
class NullImporterTests(unittest.TestCase):
|
||||
@unittest.skipIf(os_helper.TESTFN_UNENCODABLE is None,
|
||||
"Need an undecodeable filename")
|
||||
def test_unencodeable(self):
|
||||
name = os_helper.TESTFN_UNENCODABLE
|
||||
os.mkdir(name)
|
||||
try:
|
||||
self.assertRaises(ImportError, imp.NullImporter, name)
|
||||
finally:
|
||||
os.rmdir(name)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
|
@ -131,9 +131,8 @@ def uncache(*names):
|
|||
|
||||
"""
|
||||
for name in names:
|
||||
if name in ('sys', 'marshal', 'imp'):
|
||||
raise ValueError(
|
||||
"cannot uncache {0}".format(name))
|
||||
if name in ('sys', 'marshal'):
|
||||
raise ValueError("cannot uncache {}".format(name))
|
||||
try:
|
||||
del sys.modules[name]
|
||||
except KeyError:
|
||||
|
|
|
@ -541,14 +541,6 @@ def check_deprecated(self):
|
|||
"Python 3.12; use 'importlib' instead",
|
||||
DeprecationWarning))
|
||||
|
||||
def test_importer_deprecated(self):
|
||||
with self.check_deprecated():
|
||||
pkgutil.ImpImporter("")
|
||||
|
||||
def test_loader_deprecated(self):
|
||||
with self.check_deprecated():
|
||||
pkgutil.ImpLoader("", "", "", "")
|
||||
|
||||
def test_get_loader_avoids_emulation(self):
|
||||
with check_warnings() as w:
|
||||
self.assertIsNotNone(pkgutil.get_loader("sys"))
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Remove the long-deprecated ``imp`` module.
|
|
@ -884,15 +884,3 @@ PyInit__test_module_state_shared(void)
|
|||
}
|
||||
return module;
|
||||
}
|
||||
|
||||
|
||||
/*** Helper for imp test ***/
|
||||
|
||||
static PyModuleDef imp_dummy_def = TEST_MODULE_DEF("imp_dummy", main_slots, testexport_methods);
|
||||
|
||||
PyMODINIT_FUNC
|
||||
PyInit_imp_dummy(void)
|
||||
{
|
||||
return PyModuleDef_Init(&imp_dummy_def);
|
||||
}
|
||||
|
||||
|
|
|
@ -594,11 +594,11 @@ _PyImport_ClearModulesByIndex(PyInterpreterState *interp)
|
|||
/*
|
||||
It may help to have a big picture view of what happens
|
||||
when an extension is loaded. This includes when it is imported
|
||||
for the first time or via imp.load_dynamic().
|
||||
for the first time.
|
||||
|
||||
Here's a summary, using imp.load_dynamic() as the starting point:
|
||||
Here's a summary, using importlib._boostrap._load() as a starting point.
|
||||
|
||||
1. imp.load_dynamic() -> importlib._bootstrap._load()
|
||||
1. importlib._bootstrap._load()
|
||||
2. _load(): acquire import lock
|
||||
3. _load() -> importlib._bootstrap._load_unlocked()
|
||||
4. _load_unlocked() -> importlib._bootstrap.module_from_spec()
|
||||
|
@ -3794,7 +3794,7 @@ _imp_source_hash_impl(PyObject *module, long key, Py_buffer *source)
|
|||
|
||||
|
||||
PyDoc_STRVAR(doc_imp,
|
||||
"(Extremely) low-level import machinery bits as used by importlib and imp.");
|
||||
"(Extremely) low-level import machinery bits as used by importlib.");
|
||||
|
||||
static PyMethodDef imp_methods[] = {
|
||||
_IMP_EXTENSION_SUFFIXES_METHODDEF
|
||||
|
|
|
@ -7,24 +7,18 @@
|
|||
import sys
|
||||
|
||||
|
||||
try:
|
||||
from importlib.machinery import SourceFileLoader
|
||||
except ImportError:
|
||||
import imp
|
||||
# 2023-04-27(warsaw): Pre-Python 3.12, this would catch ImportErrors and try to
|
||||
# import imp, and then use imp.load_module(). The imp module was removed in
|
||||
# Python 3.12 (and long deprecated before that), and it's unclear under what
|
||||
# conditions this import will now fail, so the fallback was simply removed.
|
||||
from importlib.machinery import SourceFileLoader
|
||||
|
||||
def find_module(modname):
|
||||
"""Finds and returns a module in the local dist/checkout.
|
||||
"""
|
||||
modpath = os.path.join(
|
||||
os.path.dirname(os.path.dirname(__file__)), "Lib")
|
||||
return imp.load_module(modname, *imp.find_module(modname, [modpath]))
|
||||
else:
|
||||
def find_module(modname):
|
||||
"""Finds and returns a module in the local dist/checkout.
|
||||
"""
|
||||
modpath = os.path.join(
|
||||
os.path.dirname(os.path.dirname(__file__)), "Lib", modname + ".py")
|
||||
return SourceFileLoader(modname, modpath).load_module()
|
||||
def find_module(modname):
|
||||
"""Finds and returns a module in the local dist/checkout.
|
||||
"""
|
||||
modpath = os.path.join(
|
||||
os.path.dirname(os.path.dirname(__file__)), "Lib", modname + ".py")
|
||||
return SourceFileLoader(modname, modpath).load_module()
|
||||
|
||||
|
||||
def write_contents(f):
|
||||
|
|
|
@ -2173,10 +2173,9 @@ add_main_module(PyInterpreterState *interp)
|
|||
Py_DECREF(bimod);
|
||||
}
|
||||
|
||||
/* Main is a little special - imp.is_builtin("__main__") will return
|
||||
* False, but BuiltinImporter is still the most appropriate initial
|
||||
* setting for its __loader__ attribute. A more suitable value will
|
||||
* be set if __main__ gets further initialized later in the startup
|
||||
/* Main is a little special - BuiltinImporter is the most appropriate
|
||||
* initial setting for its __loader__ attribute. A more suitable value
|
||||
* will be set if __main__ gets further initialized later in the startup
|
||||
* process.
|
||||
*/
|
||||
loader = _PyDict_GetItemStringWithError(d, "__loader__");
|
||||
|
|
1
Python/stdlib_module_names.h
generated
1
Python/stdlib_module_names.h
generated
|
@ -164,7 +164,6 @@ static const char* _Py_stdlib_module_names[] = {
|
|||
"idlelib",
|
||||
"imaplib",
|
||||
"imghdr",
|
||||
"imp",
|
||||
"importlib",
|
||||
"inspect",
|
||||
"io",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# This script lists the names of standard library modules
|
||||
# to update Python/stdlib_mod_names.h
|
||||
# to update Python/stdlib_module_names.h
|
||||
import _imp
|
||||
import os.path
|
||||
import re
|
||||
|
|
|
@ -495,7 +495,6 @@ Python/import.c:PyImport_ImportModuleLevelObject():PyId___path__ _Py_IDENTIFIER(
|
|||
Python/import.c:PyImport_ImportModuleLevelObject():PyId___spec__ _Py_IDENTIFIER(__spec__)
|
||||
Python/import.c:PyImport_ImportModuleLevelObject():PyId__handle_fromlist _Py_IDENTIFIER(_handle_fromlist)
|
||||
Python/import.c:PyImport_ImportModuleLevelObject():PyId__lock_unlock_module _Py_IDENTIFIER(_lock_unlock_module)
|
||||
Python/import.c:PyImport_ReloadModule():PyId_imp _Py_IDENTIFIER(imp)
|
||||
Python/import.c:PyImport_ReloadModule():PyId_reload _Py_IDENTIFIER(reload)
|
||||
Python/import.c:_PyImportZip_Init():PyId_zipimporter _Py_IDENTIFIER(zipimporter)
|
||||
Python/import.c:import_find_and_load():PyId__find_and_load _Py_IDENTIFIER(_find_and_load)
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
"""
|
||||
from test.test_importlib import util
|
||||
import decimal
|
||||
import imp
|
||||
from importlib.util import cache_from_source
|
||||
import importlib
|
||||
import importlib.machinery
|
||||
import json
|
||||
|
@ -65,7 +65,7 @@ def source_wo_bytecode(seconds, repeat):
|
|||
name = '__importlib_test_benchmark__'
|
||||
# Clears out sys.modules and puts an entry at the front of sys.path.
|
||||
with util.create_modules(name) as mapping:
|
||||
assert not os.path.exists(imp.cache_from_source(mapping[name]))
|
||||
assert not os.path.exists(cache_from_source(mapping[name]))
|
||||
sys.meta_path.append(importlib.machinery.PathFinder)
|
||||
loader = (importlib.machinery.SourceFileLoader,
|
||||
importlib.machinery.SOURCE_SUFFIXES)
|
||||
|
@ -80,7 +80,7 @@ def _wo_bytecode(module):
|
|||
name = module.__name__
|
||||
def benchmark_wo_bytecode(seconds, repeat):
|
||||
"""Source w/o bytecode: {}"""
|
||||
bytecode_path = imp.cache_from_source(module.__file__)
|
||||
bytecode_path = cache_from_source(module.__file__)
|
||||
if os.path.exists(bytecode_path):
|
||||
os.unlink(bytecode_path)
|
||||
sys.dont_write_bytecode = True
|
||||
|
@ -108,9 +108,9 @@ def source_writing_bytecode(seconds, repeat):
|
|||
sys.path_hooks.append(importlib.machinery.FileFinder.path_hook(loader))
|
||||
def cleanup():
|
||||
sys.modules.pop(name)
|
||||
os.unlink(imp.cache_from_source(mapping[name]))
|
||||
os.unlink(cache_from_source(mapping[name]))
|
||||
for result in bench(name, cleanup, repeat=repeat, seconds=seconds):
|
||||
assert not os.path.exists(imp.cache_from_source(mapping[name]))
|
||||
assert not os.path.exists(cache_from_source(mapping[name]))
|
||||
yield result
|
||||
|
||||
|
||||
|
@ -121,7 +121,7 @@ def writing_bytecode_benchmark(seconds, repeat):
|
|||
assert not sys.dont_write_bytecode
|
||||
def cleanup():
|
||||
sys.modules.pop(name)
|
||||
os.unlink(imp.cache_from_source(module.__file__))
|
||||
os.unlink(cache_from_source(module.__file__))
|
||||
yield from bench(name, cleanup, repeat=repeat, seconds=seconds)
|
||||
|
||||
writing_bytecode_benchmark.__doc__ = (
|
||||
|
@ -141,7 +141,7 @@ def source_using_bytecode(seconds, repeat):
|
|||
importlib.machinery.SOURCE_SUFFIXES)
|
||||
sys.path_hooks.append(importlib.machinery.FileFinder.path_hook(loader))
|
||||
py_compile.compile(mapping[name])
|
||||
assert os.path.exists(imp.cache_from_source(mapping[name]))
|
||||
assert os.path.exists(cache_from_source(mapping[name]))
|
||||
yield from bench(name, lambda: sys.modules.pop(name), repeat=repeat,
|
||||
seconds=seconds)
|
||||
|
||||
|
|
Loading…
Reference in a new issue