Импорт хуков в питоне - PullRequest
0 голосов
/ 31 января 2019

Здравствуйте, я хочу внедрить для себя немного контроля доступа к библиотеке в моей копии python, и я хочу знать, есть ли какой-нибудь способ создать Hook в системе импорта, чтобы моя программа могла проверять файл каждый раз при импортепроизводится, если эта программа имеет разрешение на импорт этой библиотеки.Я видел кое-что о библиотеке sys и pep 302 (https://www.python.org/dev/peps/pep-0302/), но я не понял.

1 Ответ

0 голосов
/ 31 января 2019

Вы можете изменить импорт модулей, внедрив свой собственный объект загрузчика импорта.Отправную точку в документации можно найти здесь: https://docs.python.org/3/library/importlib.html

Вам нужно создать загрузчик, который будет работать с пакетами, которые вы хотите проверить, а затем либо загрузить их, либо поднятьжелаемое исключение.В случае модулей, которых нет в вашем списке контроля доступа, вы должны вернуть None, это заставит импортирующее оборудование нормально их загружать.Я создал минимальный пример функциональности этого типа, с которого вы можете начинать и расширять для создания желаемой функциональности.

import sys
import importlib

class ImportInterceptor(importlib.abc.Loader):
    def __init__(self, package_permissions):
        self.package_permissions = package_permissions

    def find_module(self, fullname, path=None):
        if fullname in self.package_permissions:
            if self.package_permissions[fullname]:
                return self
            else:
                raise ImportError("Package import was not allowed")

    def load_module(self, fullname):
        sys.meta_path = [x for x in sys.meta_path[1:] if x is not self]
        module = importlib.import_module(fullname)
        sys.meta_path = [self] + sys.meta_path
        return module


if not hasattr(sys,'frozen'):
    sys.meta_path = [ImportInterceptor({'textwrap': True, 'Pathlib': False})] + sys.meta_path


import textwrap

print(textwrap.dedent('    test'))
# Works fine

from pathlib import Path
# Raises exception

Обратите внимание, что загрузчик удаляет себя из sys.meta_path при загрузке пакета.Это сделано для того, чтобы избежать бесконечного цикла, когда он продолжает вызывать себя каждый раз, когда пытается загрузить модуль «по-настоящему».

...