importlib — Реализация импорта
Новое в версии 3.1.
Исходный код: Lib/importlib/__init__.py
Введение
Цель пакета importlib состоит из трёх пунктов.
Во-первых, предоставить реализацию оператора import (и, следовательно, функции __import__()) в исходном коде Python. Это обеспечивает реализацию import, которая является переносимой на любой интерпретатор Python. Это также предоставляет реализацию, которую легче понять, чем реализацию на языке программирования, отличном от Python.
Во-вторых, компоненты для реализации import представлены в этом пакете, что облегчает пользователям создание собственных пользовательских объектов (обобщенно называемых импортером), чтобы они участвовали в процессе импорта.
В-третьих, пакет содержит модули, предоставляющие дополнительную функциональность для управления аспектами пакетов Python:
-
importlib.metadataпредоставляет доступ к метаданным из дистрибутивов третьих сторон. -
importlib.resourcesпредоставляет функции для доступа к некодовым «ресурсам» из пакетов Python.
См. также
- Оператор импорта
-
Справочник языка по оператору
import. - Спецификация пакетов
-
Исходная спецификация пакетов. Некоторые семантические характеристики изменились с момента написания этой документации (например, перенаправление на основе
Noneвsys.modules). -
The __import__() function -
Оператор
importявляется синтаксическим сахаром для этой функции. - Инициализация пути поиска модуля sys.path
-
Инициализация
sys.path. - PEP 235
-
Импорт на платформах с регистронезависимым написанием
- PEP 263
-
Определение кодировок исходного кода Python
- PEP 302
-
Новые крючки импорта
- PEP 328
-
Импорт: многострочные и абсолютные/относительные
- PEP 366
-
Явные относительные импорты основного модуля
- PEP 420
-
Неявные пакеты пространств имён
- PEP 451
-
Тип ModuleSpec для системы импорта
- PEP 488
-
Устранение файлов PYO
- PEP 489
-
Многофазная инициализация модулей расширения
- PEP 552
-
Детерминированные pycs
- PEP 3120
-
Использование UTF-8 в качестве кодировки по умолчанию для исходного кода
- PEP 3147
-
Директории хранилища PYC
Функции
-
importlib.__import__(name, globals=None, locals=None, fromlist=(), level=0) -
Реализация встроенной функции
__import__().Примечание
Для программирования импорта модулей следует использовать
import_module(), а не эту функцию.
-
importlib.import_module(name, package=None) -
Импортирует модуль. Аргумент name указывает, какой модуль импортировать — в абсолютном или относительном виде (например,
pkg.modили..mod). Если имя указано относительно, то аргумент package должен содержать имя пакета, который будет использоваться для разрешения имени пакета (например,import_module('..mod', 'pkg.subpkg')импортируетpkg.mod).Функция
import_module()является упрощающей оболочкой надimportlib.__import__(). Это означает, что все семантические аспекты функции взяты изimportlib.__import__(). Самое важное различие между этими двумя функциями состоит в том, чтоimport_module()возвращает указанный пакет или модуль (например,pkg.mod), а__import__()возвращает верхнеуровневый пакет или модуль (например,pkg).Если вы динамически импортируете модуль, созданный после начала работы интерпретатора (например, создали файл Python-исходников), вам может потребоваться вызвать
invalidate_caches(), чтобы система импорта заметила новый модуль.Изменено в версии 3.3: Родительские пакеты автоматически импортируются.
-
importlib.find_loader(name, path=None) -
Находит загрузчик модуля, необязательно в указанном пути path. Если модуль находится в
sys.modules, то возвращаетсяsys.modules[name].__loader__(если загрузчик не будетNoneили не задан, в этом случае поднимается исключениеValueError). В противном случае выполняется поиск с использованиемsys.meta_path. Если загрузчик не найден, возвращаетсяNone.У имени с точками его родительские пакеты не импортируются неявно, поскольку это требует их загрузки, а это может быть нежелательно. Чтобы правильно импортировать подмодуль, нужно импортировать все родительские пакеты подмодуля и использовать правильный аргумент для path.
Добавлена в версии 3.3.
Изменено в версии 3.4: Если
__loader__не задан, поднимается исключениеValueError, точно так же, как и когда атрибут установлен вNone.Устарело начиная с версии 3.4: Используйте
importlib.util.find_spec()вместо этого.
-
importlib.invalidate_caches() -
Очищает внутренние кэши поисковиков, хранящихся в
sys.meta_path. Если поисковик реализуетinvalidate_caches(), то он будет вызван для выполнения очистки. Эту функцию следует вызывать, если во время выполнения программы созданы/установлены какие-либо модули, чтобы гарантировать, что все поисковики заметят существование нового модуля.Добавлена в версии 3.3.
Изменено в версии 3.10: Пакеты с пространством имён, созданные/установленные в другом месте
sys.path, после того как то же самое пространство имён уже было импортировано, распознаются.
-
importlib.reload(module) -
Перезагружает ранее импортированный модуль module. Аргументом должен быть объект модуля, так что он должен быть успешно импортирован ранее. Это полезно, если вы отредактировали исходный файл модуля с помощью внешнего редактора и хотите попробовать новую версию, не выходя из интерпретатора Python. Значением возврата является объект модуля (который может отличаться, если повторный импорт приводит к размещению другого объекта в
sys.modules).При выполнении
reload():- Код Python-модуля перекомпилируется, и код модуля на уровне кода выполняется повторно, определяя новый набор объектов, которые привязаны к именам в словаре модуля, повторно используя загрузчик, который изначально загрузил модуль. Функция
initмодулей расширений не вызывается второй раз. - Как и со всеми другими объектами в Python, старые объекты освобождаются только после того, как их счётчики ссылок упадут до нуля.
- Имена в пространстве имен модуля обновляются, чтобы указывать на любые новые или измененные объекты.
- Другие ссылки на старые объекты (например, имена, внешние по отношению к модулю) не перенаправляются на новые объекты и должны быть обновлены в каждом пространстве имён, где они встречаются, если это необходимо.
Существует ряд других замечаний:
При перезагрузке модуля его словарь (содержащий глобальные переменные модуля) сохраняется. Переопределения имён заменят старые определения, поэтому, как правило, это не проблема. Если новая версия модуля не определяет имя, которое было определено старой версией, старое определение сохраняется. Эта функция может быть использована для преимущества модуля, если он поддерживает глобальную таблицу или кэш объектов — с помощью оператора
tryон может проверить наличие таблицы и пропустить её инициализацию при необходимости:try: cache except NameError: cache = {}В общем случае перезагрузка встроенных или динамически загруженных модулей не очень полезна. Перезагрузка
sys,__main__,builtinsи других ключевых модулей не рекомендуется. Во многих случаях модули расширений не предназначены для инициализации более одного раза и могут завершиться произвольными способами при перезагрузке.Если модуль импортирует объекты из другого модуля с использованием
from…import…, вызовreload()для другого модуля не переопределяет импортированные из него объекты — один из способов обойти это — повторно выполнить операторfrom, другой — использоватьimportи квалифицированные имена (module.name) вместо этого.Если модуль создает экземпляры класса, перезагрузка модуля, который определяет класс, не влияет на определения методов экземпляров — они продолжают использовать старое определение класса. То же самое относится к производным классам.
Добавлена в версии 3.4.
Изменено в версии 3.7: Исключение
ModuleNotFoundErrorподнимается, когда перезагружаемый модуль не имеетModuleSpec. - Код Python-модуля перекомпилируется, и код модуля на уровне кода выполняется повторно, определяя новый набор объектов, которые привязаны к именам в словаре модуля, повторно используя загрузчик, который изначально загрузил модуль. Функция
importlib.abc – Абстрактные базовые классы, связанные с импортом
Исходный код: Lib/importlib/abc.py
Модуль importlib.abc содержит все основные абстрактные базовые классы, используемые модулем import. Также предоставляются некоторые подклассы основных абстрактных базовых классов для помощи в реализации основных ABC.
Иерархия ABC:
object
+-- Finder (deprecated)
+-- MetaPathFinder
+-- PathEntryFinder
+-- Loader
+-- ResourceLoader --------+
+-- InspectLoader |
+-- ExecutionLoader --+
+-- FileLoader
+-- SourceLoader
-
class importlib.abc.Finder -
Абстрактный базовый класс, представляющий поисковик.
Устарело начиная с версии 3.3: Используйте
MetaPathFinderилиPathEntryFinderвместо этого.-
abstractmethod find_module(fullname, path=None) -
Абстрактный метод для поиска загрузчика для указанного модуля. Первоначально определён в PEP 302, этот метод предназначался для использования в
sys.meta_pathи в подсистеме импорта на основе путей.Изменено в версии 3.4: Возвращает
Noneпри вызове вместо повышенияNotImplementedError.Устарело начиная с версии 3.10: Реализуйте
MetaPathFinder.find_spec()илиPathEntryFinder.find_spec()вместо этого.
-
-
class importlib.abc.MetaPathFinder -
Абстрактный базовый класс, представляющий поисковик мета-пути.
Введено в версии 3.3.
Изменено в версии 3.10: Больше не является подклассом
Finder.-
find_spec(fullname, path, target=None) -
Абстрактный метод для поиска спецификации для указанного модуля. Если это импорт верхнего уровня, path будет
None. В противном случае, это поиск подпакета или модуля, и path будет значением__path__родительского пакета. Если спецификация не найдена, возвращаетсяNone. Когда передано,targetявляется объектом модуля, который поисковик может использовать для более точного предположения о том, какую спецификацию вернуть.importlib.util.spec_from_loader()может быть полезным для реализации конкретногоMetaPathFinders.Введено в версии 3.4.
-
find_module(fullname, path) -
Легасный метод для поиска загрузчика для указанного модуля. Если это импорт верхнего уровня, path будет
None. В противном случае, это поиск подпакета или модуля, и path будет значением__path__родительского пакета. Если загрузчик не найден, возвращаетсяNone.Если
find_spec()определено, обеспечивается обратная совместимость.Изменено в версии 3.4: Возвращает
Noneпри вызове вместо повышенияNotImplementedError. Может использоватьfind_spec()для обеспечения функциональности.Устарело начиная с версии 3.4: Используйте
find_spec()вместо этого.
-
invalidate_caches() -
Необязательный метод, который, при вызове, должен аннулировать любой внутренний кэш, используемый поисковиком. Используется
importlib.invalidate_caches()при аннулировании кэшей всех поисковиков вsys.meta_path.Изменено в версии 3.4: Возвращает
Noneпри вызове вместоNotImplemented.
-
-
class importlib.abc.PathEntryFinder -
Абстрактный базовый класс, представляющий поисковик по пути. Несмотря на некоторое сходство с
MetaPathFinder,PathEntryFinderпредназначен для использования только внутри подсистемы импорта на основе пути, предоставляемойimportlib.machinery.PathFinder.Введено в версии 3.3.
Изменено в версии 3.10: Больше не является подклассом
Finder.-
find_spec(fullname, target=None) -
Абстрактный метод для поиска спецификации для указанного модуля. Поисковик будет искать модуль только внутри элемента пути, которому он назначен. Если спецификация не найдена, возвращается
None. Переданныйtarget— это объект модуля, который поисковик может использовать для более точного определения, какую спецификацию вернуть.importlib.util.spec_from_loader()может быть полезен для реализации конкретногоPathEntryFinders.Введено в версии 3.4.
-
find_loader(fullname) -
Метод устаревшего типа для поиска загрузчика для указанного модуля. Возвращает пару из 2-х элементов:
(loader, portion), гдеportion— последовательность расположений файловой системы, вносящих вклад в часть пакета имен. Загрузчик может бытьNone, при этом указываетсяportion, чтобы указать вклад расположений файловой системы в пакет имен. Пустой список может быть использован дляportion, чтобы указать, что загрузчик не является частью пакета имен. Еслиloader—None, аportion— пустой список, то загрузчик или расположение для пакета имен не найдены (т.е. ничего не найдено для модуля).Если
find_spec()определено, то обеспечивается обратная совместимость.Изменено в версии 3.4: Возвращает
(None, [])вместо повышенияNotImplementedError. Используетfind_spec()при наличии для обеспечения функциональности.Устарело начиная с версии 3.4: Используйте
find_spec()вместо этого.
-
find_module(fullname) -
Конкретная реализация
Finder.find_module(), которая эквивалентнаself.find_loader(fullname)[0].Устарело начиная с версии 3.4: Используйте
find_spec()вместо этого.
-
invalidate_caches() -
Необязательный метод, который при вызове должен аннулировать любой внутренний кэш, используемый поисковиком. Используется
importlib.machinery.PathFinder.invalidate_caches()при аннулировании кэшей всех кэшированных поисковиков.
-
-
class importlib.abc.Loader -
Абстрактный базовый класс для загрузчика. См. PEP 302 для точного определения загрузчика.
Загрузчики, которые хотят поддерживать чтение ресурсов, должны реализовать метод
get_resource_reader(), как указано вimportlib.resources.abc.ResourceReader.Изменено в версии 3.7: Введён необязательный метод
get_resource_reader().-
create_module(spec) -
Метод, который возвращает объект модуля, который нужно использовать при импорте модуля. Этот метод может вернуть
None, указывая, что следует использовать стандартные правила создания модулей.Введено в версии 3.4.
Изменено в версии 3.6: Этот метод больше не является необязательным, когда определён метод
exec_module().
-
exec_module(module) -
Абстрактный метод, который выполняет модуль в собственном пространстве имён при импорте или перезагрузке модуля. Модуль должен быть уже инициализирован, когда вызывается
exec_module(). Когда этот метод существует, должен быть определён методcreate_module().Введено в версии 3.4.
Изменено в версии 3.6: Также должен быть определён метод
create_module().
-
load_module(fullname) -
Устаревший метод для загрузки модуля. Если модуль не может быть загружен, генерируется исключение
ImportError, в противном случае возвращается загруженный модуль.Если запрашиваемый модуль уже существует в
sys.modules, этот модуль должен быть использован и перезагружен. В противном случае загрузчик должен создать новый модуль и вставить его вsys.modulesдо начала загрузки, чтобы предотвратить рекурсию при импорте. Если загрузчик вставил модуль, а загрузка завершилась ошибкой, он должен удалить его изsys.modules; модули, уже присутствующие вsys.modulesдо начала работы загрузчика, должны быть оставлены в покое (см.importlib.util.module_for_loader()).Загрузчик должен установить несколько атрибутов в модуле (обратите внимание, что некоторые из этих атрибутов могут меняться при перезагрузке модуля):
-
-
__name__ -
Полное квалифицированное имя модуля. Оно является
'__main__'для выполненного модуля.
-
-
-
__cached__ -
Имя файла скомпилированной версии кода модуля. Оно не устанавливается для всех модулей (например, для встроенных модулей).
-
-
-
__path__ -
Список расположений, где будут находиться подмодули пакета. В большинстве случаев это один каталог. Система импорта передаёт этот атрибут методу
__import__()и поисковикам так же, как иsys.path, но только для пакета. Он не устанавливается для модулей, не являющихся пакетами, поэтому может использоваться как индикатор того, что модуль является пакетом.
-
-
-
__package__ -
Полное квалифицированное имя пакета, в котором находится модуль (или пустая строка для модуля верхнего уровня). Если модуль является пакетом, то это то же, что и
__name__.
-
-
-
__loader__ -
Используемый загрузчик для загрузки модуля.
-
Когда
exec_module()доступен, обеспечивается обратная совместимость.Изменено в версии 3.4: Генерируется исключение
ImportErrorвместоNotImplementedError. Функциональность предоставляется, когдаexec_module()доступен.Устарело начиная с версии 3.4: Рекомендуемый API для загрузки модуля —
exec_module()(иcreate_module()). Загрузчики должны реализовывать его вместоload_module(). Механизм импорта позаботится обо всех других обязанностяхload_module(), когда реализованexec_module(). -
-
module_repr(module) -
Устаревший метод, который, если реализован, вычисляет и возвращает строковое представление данного модуля. По умолчанию модуль будет использовать результат этого метода как уместно.
Введено в версии 3.3.
Изменено в версии 3.4: Стало необязательным вместо абстрактного метода.
Устарело начиная с версии 3.4: Механизм импорта теперь обрабатывает это автоматически.
-
-
class importlib.abc.ResourceLoader -
Абстрактный базовый класс для загрузчика, который реализует необязательный протокол PEP 302 для загрузки произвольных ресурсов из хранилища.
Устарело начиная с версии 3.7: Этот ABC устарел в пользу поддержки загрузки ресурсов через
importlib.resources.abc.ResourceReader.-
abstractmethod get_data(path) -
Абстрактный метод для возврата байтов данных, расположенных по пути path. Загрузчики, имеющие хранилище в формате файла, позволяющее хранить произвольные данные, могут реализовать этот абстрактный метод для прямого доступа к хранящимся данным.
OSErrorдолжен быть вызван, если путь path не найден. Ожидается, что path будет построен с использованием атрибута__file__модуля или элемента из атрибута__path__пакета.Изменено в версии 3.4: Генерирует исключение
OSErrorвместоNotImplementedError.
-
-
class importlib.abc.InspectLoader -
Абстрактный базовый класс для загрузчика, который реализует необязательный протокол PEP 302 для загрузчиков, которые инспектируют модули.
-
get_code(fullname) -
Возвращает объект кода для модуля или
None, если у модуля нет объекта кода (например, для встроенного модуля). Вызывает исключениеImportError, если загрузчик не может найти запрашиваемый модуль.Примечание
Хотя метод имеет реализацию по умолчанию, рекомендуется переопределить его, если это возможно, для повышения производительности.
Изменено в версии 3.4: Больше не абстрактный и предоставлена конкретная реализация.
-
abstractmethod get_source(fullname) -
Абстрактный метод для возвращения исходного кода модуля. Он возвращается в виде текстовой строки с использованием универсальных символов новой строки, преобразуя все распознанные разделители строк в
'\n'символы. ВозвращаетNone, если исходный код недоступен (например, для встроенного модуля). Вызывает исключениеImportError, если загрузчик не может найти указанный модуль.Изменено в версии 3.4: Вызывает исключение
ImportErrorвместоNotImplementedError.
-
is_package(fullname) -
Необязательный метод, который возвращает значение true, если модуль является пакетом, и false в противном случае. Исключение
ImportErrorгенерируется, если загрузчик не может найти модуль.Изменено в версии 3.4: Вызывает исключение
ImportErrorвместоNotImplementedError.
-
static source_to_code(data, path='<string>') -
Создает объект кода из исходного кода Python.
Аргумент data может быть любым, что поддерживает функция
compile()(т.е. строка или байты). Аргумент path должен быть «путем» до места происхождения исходного кода, что может быть абстрактным понятием (например, местоположение в файле zip).С помощью последующего объекта кода можно выполнить его в модуле, выполнив
exec(code, module.__dict__).Новое в версии 3.4.
Изменено в версии 3.5: Метод стал статическим.
-
exec_module(module) -
Реализация
Loader.exec_module().Новое в версии 3.4.
-
load_module(fullname) -
Реализация
Loader.load_module().Устарело начиная с версии 3.4: Используйте
exec_module()вместо этого.
-
-
class importlib.abc.ExecutionLoader -
Абстрактный базовый класс, который наследуется от
InspectLoader, который, при реализации, помогает модулю выполняться как скрипт. ABC представляет необязательный протокол PEP 302.-
abstractmethod get_filename(fullname) -
Абстрактный метод, который должен возвращать значение
__file__для указанного модуля. Если путь недоступен, вызывается исключениеImportError.Если исходный код доступен, метод должен возвращать путь к исходному файлу, независимо от того, использовался ли байткод для загрузки модуля.
Изменено в версии 3.4: Вызывает исключение
ImportErrorвместоNotImplementedError.
-
-
class importlib.abc.FileLoader(fullname, path) -
Абстрактный базовый класс, который наследуется от
ResourceLoaderиExecutionLoader, предоставляя конкретные реализацииResourceLoader.get_data()иExecutionLoader.get_filename().Аргумент fullname — это полное разрешенное имя модуля, который обрабатывает загрузчик. Аргумент path — путь к файлу модуля.
Новое в версии 3.3.
-
name -
Имя модуля, который может обрабатывать загрузчик.
-
path -
Путь к файлу модуля.
-
load_module(fullname) -
Вызывает метод суперкласса
load_module().Устарело начиная с версии 3.4: Используйте
Loader.exec_module()вместо этого.
-
abstractmethod get_filename(fullname) -
Возвращает
path.
-
abstractmethod get_data(path) -
Считывает path как двоичный файл и возвращает из него байты.
-
-
class importlib.abc.SourceLoader -
Абстрактный базовый класс для реализации загрузки файлов исходного кода (и необязательно байт-кода). Класс наследуется как от
ResourceLoader, так и отExecutionLoader, требуя реализации:ResourceLoader.get_data()-
-
ExecutionLoader.get_filename() -
Должен возвращать только путь к файлу исходного кода; загрузка без исходного кода не поддерживается.
-
Абстрактные методы, определенные этим классом, предназначены для добавления необязательной поддержки файлов байт-кода. Не реализация этих необязательных методов (или их вызов с возбуждением
NotImplementedError) заставляет загрузчик работать только с исходным кодом. Реализация методов позволяет загрузчику работать с файлами исходного кода и байт-кода; она не допускает загрузки без исходного кода, где предоставлен только байт-код. Файлы байт-кода являются оптимизацией для ускорения загрузки, устраняя этап анализа компилятора Python, поэтому не предоставляется API, специфичный для байт-кода.-
path_stats(path) -
Необязательный абстрактный метод, возвращающий
dictс метаданными о заданном пути. Поддерживаемые ключи словаря:-
'mtime'(обязательно): целое или дробное число, представляющее время последнего изменения исходного кода; -
'size'(необязательно): размер исходного кода в байтах.
Любые другие ключи в словаре игнорируются, чтобы позволить будущие расширения. Если путь не может быть обработан, возбуждается
OSError.Введено в версии 3.3.
Изменено в версии 3.4: Возбуждается
OSErrorвместоNotImplementedError. -
-
path_mtime(path) -
Необязательный абстрактный метод, возвращающий время последнего изменения для заданного пути.
Устарело начиная с версии 3.3: Этот метод устарел в пользу
path_stats(). Необязательно его реализовывать, но он по-прежнему доступен для совместимости. ВозбуждаетсяOSError, если путь не может быть обработан.Изменено в версии 3.4: Возбуждается
OSErrorвместоNotImplementedError.
-
set_data(path, data) -
Необязательный абстрактный метод, записывающий указанные байты в файл по пути. Любые промежуточные директории, которых нет, создаются автоматически.
При неудачной записи по пути из-за того, что путь только для чтения (
errno.EACCES/PermissionError), исключение не распространяется.Изменено в версии 3.4: Больше не возбуждает
NotImplementedErrorпри вызове.
-
get_code(fullname) -
Конкретная реализация
InspectLoader.get_code().
-
exec_module(module) -
Конкретная реализация
Loader.exec_module().Введено в версии 3.4.
-
load_module(fullname) -
Конкретная реализация
Loader.load_module().Устарело начиная с версии 3.4: Используйте
exec_module()вместо этого.
-
get_source(fullname) -
Конкретная реализация
InspectLoader.get_source().
-
is_package(fullname) -
Конкретная реализация
InspectLoader.is_package(). Модуль определяется как пакет, если его путь к файлу (как указано вExecutionLoader.get_filename()) — это файл с именем__init__после удаления расширения и само имя модуля не заканчивается на__init__.
importlib.machinery – Импортеры и обработчики путей
Исходный код: Lib/importlib/machinery.py
Этот модуль содержит различные объекты, которые помогают import находить и загружать модули.
-
importlib.machinery.SOURCE_SUFFIXES -
Список строк, представляющих распознанные расширения файлов для исходных модулей.
Введено в версии 3.3.
-
importlib.machinery.DEBUG_BYTECODE_SUFFIXES -
Список строк, представляющих расширения файлов для неоптимизированных модулей байткода.
Введено в версии 3.3.
Устарело начиная с версии 3.5: Используйте
BYTECODE_SUFFIXESвместо этого.
-
importlib.machinery.OPTIMIZED_BYTECODE_SUFFIXES -
Список строк, представляющих расширения файлов для оптимизированных модулей байткода.
Введено в версии 3.3.
Устарело начиная с версии 3.5: Используйте
BYTECODE_SUFFIXESвместо этого.
-
importlib.machinery.BYTECODE_SUFFIXES -
Список строк, представляющих распознанные расширения файлов для модулей байткода (включая ведущую точку).
Введено в версии 3.3.
Изменено в версии 3.5: Значение больше не зависит от
__debug__.
-
importlib.machinery.EXTENSION_SUFFIXES -
Список строк, представляющих распознанные расширения файлов для модулей расширений.
Введено в версии 3.3.
-
importlib.machinery.all_suffixes() -
Возвращает комбинированный список строк, представляющих все расширения файлов для модулей, распознаваемых стандартным механизмом импорта. Это вспомогательная функция для кода, которому просто нужно знать, может ли путь к файловой системе потенциально ссылаться на модуль, не требуя никаких деталей о типе модуля (например,
inspect.getmodulename()).Введено в версии 3.3.
-
class importlib.machinery.BuiltinImporter -
Импортер для встроенных модулей. Все известные встроенные модули перечислены в
sys.builtin_module_names. Этот класс реализует ABCimportlib.abc.MetaPathFinderиimportlib.abc.InspectLoader.Этот класс определяет только методы класса, чтобы избежать необходимости в создании экземпляра.
Изменено в версии 3.5: В рамках PEP 489 встроенный импортер теперь реализует
Loader.create_module()иLoader.exec_module()
-
class importlib.machinery.FrozenImporter -
Импортер для замороженных модулей. Этот класс реализует ABC
importlib.abc.MetaPathFinderиimportlib.abc.InspectLoader.Этот класс определяет только методы класса, чтобы избежать необходимости в создании экземпляра.
Изменено в версии 3.4: Получил методы
create_module()иexec_module().
-
class importlib.machinery.WindowsRegistryFinder -
Поиск модулей, объявленных в реестре Windows. Этот класс реализует ABC
importlib.abc.MetaPathFinder.Этот класс определяет только методы класса, чтобы избежать необходимости в создании экземпляра.
Введено в версии 3.3.
Устарело начиная с версии 3.6: Используйте настройки
siteвместо этого. Будущие версии Python могут не включать этот поиск по умолчанию.
-
class importlib.machinery.PathFinder -
Поиск по
sys.pathи атрибутам пакета__path__. Этот класс реализует ABCimportlib.abc.MetaPathFinder.Этот класс определяет только методы класса, чтобы избежать необходимости в создании экземпляра.
-
classmethod find_spec(fullname, path=None, target=None) -
Метод класса, который пытается найти спецификацию модуля, указанного в fullname, в
sys.pathили, если определено, в path. Для каждой проверяемой записи пути проверяетсяsys.path_importer_cache. Если найдено ненулевое значение, то оно используется в качестве поисковика по записи пути для поиска искомого модуля. Если запись не найдена вsys.path_importer_cache, то ищется поисковик для записи пути вsys.path_hooksи, если найден, сохраняется вsys.path_importer_cacheвместе с запросом о модуле. Если поисковик не найден ни разу, тоNoneхранится в кэше и возвращается.Введено в версии 3.4.
Изменено в версии 3.5: Если текущая рабочая директория (представленная пустой строкой) больше не допустима, то возвращается
None, но вsys.path_importer_cacheничего не кешируется.
-
classmethod find_module(fullname, path=None) -
Устаревшая оболочка вокруг
find_spec().Устарело начиная с версии 3.4: Используйте
find_spec()вместо этого.
-
classmethod invalidate_caches() -
Вызывает
importlib.abc.PathEntryFinder.invalidate_caches()для всех поисковиков, хранящихся вsys.path_importer_cache, которые определяют этот метод. В противном случае записи вsys.path_importer_cache, установленные вNone, удаляются.Изменено в версии 3.7: Записи
Noneвsys.path_importer_cacheудаляются.
Изменено в версии 3.4: Вызывает объекты в
sys.path_hooksс текущей рабочей директорией для''(т.е. пустой строкой). -
-
class importlib.machinery.FileFinder(path, *loader_details) -
Конкретная реализация
importlib.abc.PathEntryFinder, кэширующая результаты из файловой системы.Аргумент path — это директория, за поиск в которой отвечает данный поиск.
Аргумент loader_details — это переменное число кортежей из двух элементов, каждый из которых содержит загрузчик и последовательность расширений файлов, распознаваемых этим загрузчиком. Ожидается, что загрузчики будут вызываемыми объектами, принимающими два аргумента: имя модуля и путь к найденному файлу.
Поиск будет кэшировать содержимое директории по мере необходимости, используя вызовы stat для каждого поиска модуля, чтобы проверить, не устарел ли кэш. Поскольку устаревание кэша зависит от гранулярности информации операционной системы о состоянии файловой системы, существует потенциальная проблема гонки при поиске модуля, создании нового файла и последующем поиске модуля, который представляет этот новый файл. Если операции выполняются достаточно быстро, чтобы уместиться в гранулярности вызовов stat, поиск модуля завершится неудачей. Чтобы предотвратить это, при динамическом создании модуля, убедитесь, что вы вызываете
importlib.invalidate_caches().Добавлена в версии 3.3.
-
path -
Путь, по которому будет производиться поиск.
-
find_spec(fullname, target=None) -
Попытка найти спецификацию для обработки fullname в пределах
path.Добавлена в версии 3.4.
-
find_loader(fullname) -
Попытка найти загрузчик для обработки fullname в пределах
path.Устарело начиная с версии 3.10: Используйте
find_spec()вместо этого.
-
invalidate_caches() -
Очистка внутреннего кэша.
-
classmethod path_hook(*loader_details) -
Метод класса, возвращающий замыкание для использования с
sys.path_hooks. ЭкземплярFileFinderвозвращается замыканием, используя аргумент path, переданный замыканию непосредственно, и loader_details косвенно.Если аргумент замыкания не является существующей директорией, будет поднято исключение
ImportError.
-
-
class importlib.machinery.SourceFileLoader(fullname, path) -
Конкретная реализация
importlib.abc.SourceLoaderпутём наследования отimportlib.abc.FileLoaderи предоставления конкретных реализаций других методов.Добавлена в версии 3.3.
-
name -
Имя модуля, который будет обрабатывать этот загрузчик.
-
path -
Путь к исходному файлу.
-
is_package(fullname) -
Возвращает
Trueеслиpathкажется, что предназначен для пакета.
-
path_stats(path) -
Конкретная реализация
importlib.abc.SourceLoader.path_stats().
-
set_data(path, data) -
Конкретная реализация
importlib.abc.SourceLoader.set_data().
-
load_module(name=None) -
Конкретная реализация
importlib.abc.Loader.load_module(), где указание имени загружаемого модуля является необязательным.Устарело начиная с версии 3.6: Используйте
importlib.abc.Loader.exec_module()вместо этого.
-
-
class importlib.machinery.SourcelessFileLoader(fullname, path) -
Конкретная реализация
importlib.abc.FileLoader, которая может импортировать байт-кодовые файлы (т. е. файлы исходного кода отсутствуют).Обратите внимание, что прямое использование байт-кодовых файлов (и, следовательно, не файлов исходного кода) препятствует использованию ваших модулей всеми реализациями Python или новыми версиями Python, которые изменяют формат байт-кода.
Добавлена в версии 3.3.
-
name -
Имя модуля, который будет обрабатывать данный загрузчик.
-
path -
Путь к байт-кодовому файлу.
-
is_package(fullname) -
Определяет, является ли модуль пакетом, основываясь на
path.
-
get_source(fullname) -
Возвращает
Noneтак как байт-кодовые файлы не имеют исходного кода при использовании этого загрузчика.
-
load_module(name=None)
Конкретная реализация
importlib.abc.Loader.load_module(), где указание имени загружаемого модуля является необязательным.Устарело начиная с версии 3.6: Используйте
importlib.abc.Loader.exec_module()вместо этого. -
-
class importlib.machinery.ExtensionFileLoader(fullname, path) -
Конкретная реализация
importlib.abc.ExecutionLoaderдля модулей расширения.Аргумент fullname указывает имя модуля, который должен поддерживаться загрузчиком. Аргумент path — путь к файлу модуля расширения.
Добавлена в версии 3.3.
-
name -
Имя модуля, поддерживаемого загрузчиком.
-
path -
Путь к модулю расширения.
-
create_module(spec) -
Создаёт объект модуля из заданного описания в соответствии с PEP 489.
Добавлена в версии 3.5.
-
exec_module(module) -
Инициализирует заданный объект модуля в соответствии с PEP 489.
Добавлена в версии 3.5.
-
is_package(fullname) -
Возвращает
True, если путь к файлу указывает на пакетный__init__модуль на основеEXTENSION_SUFFIXES.
-
get_code(fullname) -
Возвращает
None, так как модули расширения не имеют объекта кода.
-
get_source(fullname) -
Возвращает
None, так как модули расширения не имеют исходного кода.
-
get_filename(fullname) -
Возвращает
path.Добавлена в версии 3.4.
-
-
class importlib.machinery.NamespaceLoader(name, path, path_finder) -
Конкретная реализация
importlib.abc.InspectLoaderдля пакетов пространств имён. Это псевдоним для закрытого класса и используется только для получения доступа к атрибуту__loader__пакетов пространств имён:>>> from importlib.machinery import NamespaceLoader >>> import my_namespace >>> isinstance(my_namespace.__loader__, NamespaceLoader) True >>> import importlib.abc >>> isinstance(my_namespace.__loader__, importlib.abc.Loader) True
Добавлена в версии 3.11.
-
class importlib.machinery.ModuleSpec(name, loader, *, origin=None, loader_state=None, is_package=None) -
Спецификация для состояния модуля, связанного с системой импорта. Обычно она предоставляется как атрибут модуля
__spec__. В описаниях ниже, имена в скобках указывают соответствующие атрибуты, доступные непосредственно в объекте модуля, напримерmodule.__spec__.origin == module.__file__. Однако следует отметить, что, хотя значения обычно эквивалентны, они могут отличаться, так как нет синхронизации между двумя объектами. Например, можно обновить атрибут модуля__file__во время выполнения, и это не будет автоматически отражено в атрибуте модуля__spec__.origin, и наоборот.Добавлена в версии 3.4.
-
name
(
__name__)Полное квалифицированное имя модуля. Найденный объект должен всегда устанавливать этот атрибут в непустую строку.
-
loader
Загрузчик, используемый для загрузки модуля. Найденный объект должен всегда установить этот атрибут.
-
origin
(
__file__)Местоположение, которое должен использовать загрузчик для загрузки модуля. Например, для модулей, загруженных из файла .py, это имя файла. Найденный объект должен всегда установить этот атрибут в осмысленное значение для использования загрузчиком. В редких случаях, когда такого места нет (например, для пакетов пространств имен), оно должно устанавливаться в
None.-
submodule_search_locations
(
__path__)Список расположений, где будут находиться подмодули пакета. В большинстве случаев это один каталог. Найденный объект должен устанавливать этот атрибут в список, даже в пустой, чтобы указать системе импорта, что модуль является пакетом. Для модулей, которые не являются пакетами, он должен быть установлен в
None. Для пакетов пространств имён он автоматически устанавливается в специальный объект.-
loader_state
Найденный объект может установить этот атрибут в объект, содержащий дополнительные данные, специфичные для модуля, используемые при загрузке модуля. В противном случае он должен устанавливаться в
None.-
cached
Имя файла скомпилированной версии кода модуля. Найденный объект должен всегда устанавливать этот атрибут, но он может быть
Noneдля модулей, которым не нужно хранить скомпилированный код.-
parent
(Только для чтения) Полное квалифицированное имя пакета, в котором находится модуль (или пустая строка для модуля верхнего уровня). Если модуль является пакетом, то это то же самое, что и
name.-
has_location
-
importlib.util – Утилитарный код для импортеров
Исходный код: Lib/importlib/util.py
Этот модуль содержит различные объекты, которые помогают в построении импортера.
-
importlib.util.MAGIC_NUMBER -
Байты, представляющие номер версии байткода. Если вам нужна помощь с загрузкой/записью байткода, обратитесь к
importlib.abc.SourceLoader.Добавлена в версии 3.4.
-
importlib.util.cache_from_source(path, debug_override=None, *, optimization=None) -
Возвращает путь к файлу с байткодом, ассоциированный с исходным путем path, согласно PEP 3147/PEP 488. Например, если path равен
/foo/bar/baz.py, то возвращаемое значение будет/foo/bar/__pycache__/baz.cpython-32.pycдля Python 3.2. Строкаcpython-32взята из текущего магического тега (см.get_tag(); еслиsys.implementation.cache_tagне определено, то будет поднято исключениеNotImplementedError).Параметр optimization используется для указания уровня оптимизации файла байткода. Пустая строка обозначает отсутствие оптимизации, поэтому
/foo/bar/baz.pyс optimization равным''приведет к пути байткода/foo/bar/__pycache__/baz.cpython-32.pyc.Noneприводит к использованию уровня оптимизации интерпретатора. Любое другое значение используется в виде строки, так/foo/bar/baz.pyс optimization равным2приведёт к пути байткода/foo/bar/__pycache__/baz.cpython-32.opt-2.pyc. Строковое представление optimization может содержать только символы латинского алфавита и цифры; в противном случае будет поднято исключениеValueError.Параметр debug_override устарел и может быть использован для переопределения системного значения для
__debug__. ЗначениеTrueэквивалентно установке optimization в пустую строку. ЗначениеFalseэквивалентно установке optimization в1. Если оба параметра debug_override и optimization неNone, то будет поднято исключениеTypeError.Добавлена в версии 3.4.
Изменено в версии 3.5: Добавлен параметр optimization, параметр debug_override устарел.
Изменено в версии 3.6: Принимает объект-путь.
-
importlib.util.source_from_cache(path) -
Учитывая путь path к имени файла PEP 3147, возвращает ассоциированный путь к файлу исходного кода. Например, если path равен
/foo/bar/__pycache__/baz.cpython-32.pyc, возвращаемый путь будет/foo/bar/baz.py. path может не существовать, однако, если он не соответствует формату PEP 3147 или PEP 488, будет поднято исключениеValueError. Еслиsys.implementation.cache_tagне определено, будет поднято исключениеNotImplementedError.Добавлена в версии 3.4.
Изменено в версии 3.6: Принимает объект-путь.
-
importlib.util.decode_source(source_bytes) -
Декодирует заданные байты, представляющие исходный код, и возвращает его как строку с универсальными разделителями строк (как требуется в
importlib.abc.InspectLoader.get_source()).Добавлена в версии 3.4.
-
importlib.util.resolve_name(name, package) -
Преобразует относительное имя модуля в абсолютное.
Если у name нет ведущих точек, то возвращается просто name. Это позволяет использовать, например,
importlib.util.resolve_name('sys', __spec__.parent)без проверки необходимости аргумента package.Если name является относительным именем модуля, но package имеет ложное значение (например,
Noneили пустая строка), то поднимается исключениеImportError.ImportErrorтакже поднимается, если относительное имя выходит за пределы содержащего пакета (например, запрос..baconизнутри пакетаspam).Добавлена в версии 3.3.
Изменено в версии 3.9: Для повышения согласованности с операторами импорта, для неверных попыток относительного импорта будет подниматься исключение
ImportErrorвместоValueError.
-
importlib.util.find_spec(name, package=None) -
Находит спецификацию (спецификацию) модуля, необязательно относительно указанного имени пакета package. Если модуль находится в
sys.modules, то возвращаетсяsys.modules[name].__spec__(за исключением случаев, когда спецификация будетNoneили не установлена, в этом случае поднимается исключениеValueError). В противном случае выполняется поиск с использованиемsys.meta_path.Noneвозвращается, если спецификация не найдена.Если name относится к подмодулю (содержит точку), родительский модуль импортируется автоматически.
name и package работают так же, как и для
import_module().Добавлена в версии 3.4.
Изменено в версии 3.7: Поднимает исключение
ModuleNotFoundErrorвместоAttributeError, если package фактически не является пакетом (т.е. не имеет атрибута__path__).
-
importlib.util.module_from_spec(spec) -
Создаёт новый модуль на основе spec и
spec.loader.create_module.Если
spec.loader.create_moduleне возвращаетNone, то любые ранее существовавшие атрибуты не будут сброшены. Также не будет поднято исключениеAttributeError, если оно возникнет при доступе к spec или при установке атрибута в модуле.Эта функция предпочтительнее использования
types.ModuleTypeдля создания нового модуля, так как spec используется для установки по возможности всех контролируемых импортом атрибутов в модуле.Добавлена в версии 3.5.
-
@importlib.util.module_for_loader -
Декоратор для
importlib.abc.Loader.load_module(), который обрабатывает выбор правильного объекта модуля для загрузки. Ожидается, что декорированный метод будет принимать два позиционных аргумента (например,load_module(self, module)), при этом второй аргумент будет объектом модуля, используемым загрузчиком. Обратите внимание, что декоратор не будет работать со статическими методами из-за предположения о двух аргументах.Декорированный метод будет принимать имя загружаемого модуля, как ожидается для загрузчика. Если модуль не найден в
sys.modules, то создаётся новый. Независимо от источника модуля,__loader__устанавливается в self, а__package__устанавливается на основе того, что возвращаетimportlib.abc.InspectLoader.is_package()(если доступно). Эти атрибуты устанавливаются безусловно для поддержки перезагрузки.Если декорированный метод вызывает исключение, а модуль был добавлен в
sys.modules, то модуль будет удалён, чтобы предотвратить оставление частично инициализированного модуля вsys.modules. Если модуль уже присутствует вsys.modules, он остаётся без изменений.Изменено в версии 3.3:
__loader__и__package__автоматически устанавливаются (если это возможно).Изменено в версии 3.4: Устанавливаются
__name__,__loader__и__package__безусловно для поддержки перезагрузки.Устарело начиная с версии 3.4: Механизм импорта теперь напрямую выполняет все функции, предоставляемые этой функцией.
-
@importlib.util.set_loader -
Декоратор для
importlib.abc.Loader.load_module(), который устанавливает атрибут__loader__возвращённого модуля. Если атрибут уже установлен, декоратор ничего не делает. Предполагается, что первый позиционный аргумент обернутого метода (т.е.self) — это значение, которое должно быть установлено для__loader__.Изменено в версии 3.4: Устанавливает
__loader__если установленоNone, как если бы атрибут не существовал.Устарело начиная с версии 3.4: Механизм импорта теперь выполняет это автоматически.
-
@importlib.util.set_package -
Декоратор для
importlib.abc.Loader.load_module(), который устанавливает атрибут__package__возвращённого модуля. Если__package__установлен и имеет значение, отличное отNone, он не будет изменён.Устарело начиная с версии 3.4: Механизм импорта теперь выполняет это автоматически.
-
importlib.util.spec_from_loader(name, loader, *, origin=None, is_package=None) -
Функция-фабрика для создания экземпляра
ModuleSpecна основе загрузчика. Параметры имеют то же значение, что и для ModuleSpec. Функция использует доступные API загрузчика, такие какInspectLoader.is_package(), чтобы заполнить любые отсутствующие данные в спецификации.Добавлена в версии 3.4.
-
importlib.util.spec_from_file_location(name, location, *, loader=None, submodule_search_locations=None) -
Функция-фабрика для создания экземпляра
ModuleSpecна основе пути к файлу. Отсутствующие данные в спецификации будут заполнены путём использования API загрузчика и предположения, что модуль будет основан на файле.Добавлена в версии 3.4.
Изменено в версии 3.6: Принимает объект-путь.
-
importlib.util.source_hash(source_bytes) -
Возвращает хеш source_bytes в виде байтов. Файл модуля с хешем
.pycвстраивает хешsource_hash()содержимого соответствующего исходного файла в свой заголовок.Добавлена в версии 3.7.
-
class importlib.util.LazyLoader(loader) -
Класс, откладывающий выполнение загрузчика модуля до тех пор, пока к модулю не будет обращено внимание.
Этот класс только работает с загрузчиками, которые определяют
exec_module()для управления типом модуля, необходимым для модуля. По тем же причинам метод загрузчикаcreate_module()должен возвращатьNoneили тип, для которого его атрибут__class__может быть изменён, а также не использовать __slots__. Наконец, модули, которые подменяют объект, помещённый вsys.modules, не будут работать, так как нет способа безопасно заменить ссылки на модуль во всём интерпретаторе; в случае такой подмены генерируетсяValueError.Примечание
Для проектов, где время запуска имеет решающее значение, этот класс позволяет потенциально минимизировать стоимость загрузки модуля, если он никогда не используется. Для проектов, где время запуска не имеет решающего значения, использование этого класса крайне нежелательно, так как сообщения об ошибках, возникающие во время загрузки, откладываются и, следовательно, появляются вне контекста.
Добавлена в версии 3.5.
Изменено в версии 3.6: Начал вызывать
create_module(), убрал предупреждение о совместимости дляimportlib.machinery.BuiltinImporterиimportlib.machinery.ExtensionFileLoader.-
classmethod factory(loader) -
Метод класса, который возвращает вызываемый объект, создающий ленивый загрузчик. Это предназначено для ситуаций, когда загрузчик передаётся по классу, а не по экземпляру.
suffixes = importlib.machinery.SOURCE_SUFFIXES loader = importlib.machinery.SourceFileLoader lazy_loader = importlib.util.LazyLoader.factory(loader) finder = importlib.machinery.FileFinder(path, (lazy_loader, suffixes))
-
Примеры
Программный импорт
Для программного импорта модуля используйте importlib.import_module().
import importlib
itertools = importlib.import_module('itertools')
Проверка возможности импорта модуля
Если вам нужно узнать, можно ли импортировать модуль, не выполняя сам импорт, используйте importlib.util.find_spec().
Обратите внимание, что если name является подмодулем (содержит точку), importlib.util.find_spec() импортирует родительский модуль.
import importlib.util
import sys
# For illustrative purposes.
name = 'itertools'
if name in sys.modules:
print(f"{name!r} already in sys.modules")
elif (spec := importlib.util.find_spec(name)) is not None:
# If you chose to perform the actual import ...
module = importlib.util.module_from_spec(spec)
sys.modules[name] = module
spec.loader.exec_module(module)
print(f"{name!r} has been imported")
else:
print(f"can't find the {name!r} module")
Импорт исходного файла напрямую
Для импорта Python-исходного файла напрямую используйте следующий рецепт:
import importlib.util import sys # For illustrative purposes. import tokenize file_path = tokenize.__file__ module_name = tokenize.__name__ spec = importlib.util.spec_from_file_location(module_name, file_path) module = importlib.util.module_from_spec(spec) sys.modules[module_name] = module spec.loader.exec_module(module)
Реализация ленивых импортов
В примере ниже показано, как реализовать ленивые импорты:
>>> import importlib.util
>>> import sys
>>> def lazy_import(name):
... spec = importlib.util.find_spec(name)
... loader = importlib.util.LazyLoader(spec.loader)
... spec.loader = loader
... module = importlib.util.module_from_spec(spec)
... sys.modules[name] = module
... loader.exec_module(module)
... return module
...
>>> lazy_typing = lazy_import("typing")
>>> #lazy_typing is a real module object,
>>> #but it is not loaded in memory yet.
>>> lazy_typing.TYPE_CHECKING
False
Настройка импортера
Для глубокой настройки импорта, как правило, нужно реализовать импортер. Это означает управление как поисковиком, так и загрузчиком. Для поисковиков есть два варианта в зависимости от ваших потребностей: поисковик мета-пути или поисковик элемента пути. Первый — то, что вы помещаете в sys.meta_path, а второй — то, что вы создаёте с помощью обработчика элемента пути в sys.path_hooks, который работает с записями в sys.path, чтобы потенциально создать поисковик. В этом примере показано, как зарегистрировать собственные импортеры, чтобы импорт использовал их (для создания собственного импортера, прочитайте документацию по соответствующим классам, определённым в этом пакете):
import importlib.machinery
import sys
# For illustrative purposes only.
SpamMetaPathFinder = importlib.machinery.PathFinder
SpamPathEntryFinder = importlib.machinery.FileFinder
loader_details = (importlib.machinery.SourceFileLoader,
importlib.machinery.SOURCE_SUFFIXES)
# Setting up a meta path finder.
# Make sure to put the finder in the proper location in the list in terms of
# priority.
sys.meta_path.append(SpamMetaPathFinder)
# Setting up a path entry finder.
# Make sure to put the path hook in the proper location in the list in terms
# of priority.
sys.path_hooks.append(SpamPathEntryFinder.path_hook(loader_details))
Приближение importlib.import_module()
Сам импорт реализован на языке Python, что позволяет экспонировать большую часть механизма импорта через importlib. Следующее помогает проиллюстрировать различные API, которые предоставляет importlib, предоставляя приблизительную реализацию importlib.import_module():
import importlib.util
import sys
def import_module(name, package=None):
"""An approximate implementation of import."""
absolute_name = importlib.util.resolve_name(name, package)
try:
return sys.modules[absolute_name]
except KeyError:
pass
path = None
if '.' in absolute_name:
parent_name, _, child_name = absolute_name.rpartition('.')
parent_module = import_module(parent_name)
path = parent_module.__spec__.submodule_search_locations
for finder in sys.meta_path:
spec = finder.find_spec(absolute_name, path)
if spec is not None:
break
else:
msg = f'No module named {absolute_name!r}'
raise ModuleNotFoundError(msg, name=absolute_name)
module = importlib.util.module_from_spec(spec)
sys.modules[absolute_name] = module
spec.loader.exec_module(module)
if path is not None:
setattr(parent_module, child_name, module)
return module
© 2001–2023 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.11/library/importlib.html