Исходный код EJIO.utils.interface.disposable

## /utils/interface/disposable.py

import typing
from typing import Any, Protocol, runtime_checkable
from loguru import logger

__all__ = [
    'Disposable',
    'DisposableMeta',
]


[документация] class DisposableMeta(typing._ProtocolMeta): """ Метакласс для автоматического рантайм-учета всех уничтожаемых и очищаемых структур. """ __slots__ = () _registry: list[type] = [] def __new__( mcs, name: str, bases: tuple[type, ...], attrs: dict[str, Any] ) -> type: """ Добавляет на учет все классы, метаклассом которых является DisposableMeta. :param name: Имя создаваемого класса. :param bases: Список классов родителей. :param attrs: Словарь методов и аттрибутов класса. :return: Новый класс - наследник DisposableMeta. """ cls = super().__new__(mcs, name, bases, attrs) # Пропускаем сам базовый протокол Disposable if name != 'Disposable': # Проверяем наличие методов clear или destroy в атрибутах или у предков has_clear = 'clear' in attrs or any(hasattr(b, 'clear') for b in bases) has_destroy = 'destroy' in attrs or any(hasattr(b, 'destroy') for b in bases) # Проверяем, реализует ли класс метод clear или destroy if has_clear or has_destroy: if cls not in mcs._registry: mcs._registry.append(cls) logger.debug(f"Struct '{name}' taken into automatic runtime accounting Disposable.") return cls
[документация] @classmethod def dispose_all(mcs) -> None: """ Централизованно и каскадно уничтожает и очищает абсолютно все зарегистрированные структуры. """ logger.info( f"Automatic global runtime cleaning launched of ({len(mcs._registry)} Disposable structures)...") for cls_target in list(mcs._registry): cleaned = False try: # 1. Если у структуры объявлен метод clear if hasattr(cls_target, 'clear') and callable(getattr(cls_target, 'clear')): cls_target.clear() logger.debug(f"Auto-cleaning: structure'{cls_target.__name__}' method .clear() successfully completed.") cleaned = True # 2. Если у структуры объявлен метод destroy elif hasattr(cls_target, 'destroy') and callable(getattr(cls_target, 'destroy')): cls_target.destroy() logger.debug(f"Auto-cleaning: structure '{cls_target.__name__}' method .destroy() successfully completed.") cleaned = True if not cleaned: raise AttributeError(f"Struct '{cls_target.__name__}' does not have a callable attribute 'clear' or 'destroy'.") except Exception as e: logger.error(f"Error auto-clearing structure '{cls_target.__name__}': {e}") logger.info("Global auto-clear runtime Disposable completed.")
[документация] @runtime_checkable class Disposable(Protocol, metaclass=DisposableMeta): """ Единый интерфейс-протокол для всех долгоживущих рантайм-структур. Гарантирует автоматическую очистку памяти при завершении работы приложения. """ __slots__ = ()
[документация] def clear(self) -> None: """ Метод полной очистки внутреннего хранилища/состояния. :raises NotImplementedError: должен быть реализован в подклассах. """ raise NotImplementedError
[документация] def destroy(self) -> None: """ Метод полной очистки внутреннего хранилища/состояния. :raises NotImplementedError: должен быть реализован в подклассах. """ raise NotImplementedError