mirror of
https://github.com/arcan1s/ahriman.git
synced 2026-07-24 03:11:14 +00:00
refactor: implement generic optional import mechanisms
this project is actively using optional imports, which leads to duplicate handling here and there. This commit implements logic in special method to reduce complexity and simplify tests paths
This commit is contained in:
@@ -21,6 +21,8 @@
|
||||
from logging import NullHandler
|
||||
from typing import Any
|
||||
|
||||
from ahriman.core.module_loader import optional_module
|
||||
|
||||
|
||||
__all__ = ["JournalHandler"]
|
||||
|
||||
@@ -40,7 +42,5 @@ class _JournalHandler(NullHandler):
|
||||
del args, kwargs
|
||||
|
||||
|
||||
try:
|
||||
from systemd.journal import JournalHandler # type: ignore[import-untyped]
|
||||
except ImportError:
|
||||
JournalHandler = _JournalHandler
|
||||
systemd_journal = optional_module("systemd.journal")
|
||||
JournalHandler = systemd_journal.JournalHandler if systemd_journal else _JournalHandler
|
||||
|
||||
@@ -26,6 +26,7 @@ from typing import ClassVar, Literal
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.log.http_log_handler import HttpLogHandler
|
||||
from ahriman.core.log.log_context import LogContext
|
||||
from ahriman.core.module_loader import optional_module
|
||||
from ahriman.models.log_handler import LogHandler
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
|
||||
@@ -65,14 +66,11 @@ class LogLoader:
|
||||
if selected is not None:
|
||||
return selected
|
||||
|
||||
try:
|
||||
from systemd.journal import JournalHandler # type: ignore[import-untyped]
|
||||
del JournalHandler
|
||||
if optional_module("systemd.journal"):
|
||||
return LogHandler.Journald # journald import was found
|
||||
except ImportError:
|
||||
if LogLoader.DEFAULT_SYSLOG_DEVICE.exists():
|
||||
return LogHandler.Syslog
|
||||
return LogHandler.Console
|
||||
if LogLoader.DEFAULT_SYSLOG_DEVICE.exists():
|
||||
return LogHandler.Syslog
|
||||
return LogHandler.Console
|
||||
|
||||
@staticmethod
|
||||
def load(repository_id: RepositoryId, configuration: Configuration, handler: LogHandler, *,
|
||||
|
||||
@@ -26,8 +26,7 @@ from pkgutil import ModuleInfo, walk_packages
|
||||
from types import ModuleType
|
||||
from typing import Any, TypeGuard, TypeVar
|
||||
|
||||
|
||||
__all__ = ["implementations"]
|
||||
__all__ = ["implementations", "optional_module"]
|
||||
|
||||
|
||||
T = TypeVar("T")
|
||||
@@ -74,3 +73,19 @@ def implementations(root_module: ModuleType, base_class: type[T]) -> Iterator[ty
|
||||
|
||||
for _, attribute in inspect.getmembers(module, is_base_class):
|
||||
yield attribute
|
||||
|
||||
|
||||
def optional_module(module_name: str) -> ModuleType | None:
|
||||
"""
|
||||
import an optional module
|
||||
|
||||
Args:
|
||||
module_name(str): fully qualified module name
|
||||
|
||||
Returns:
|
||||
ModuleType | None: imported module or ``None`` when it cannot be imported
|
||||
"""
|
||||
try:
|
||||
return import_module(module_name)
|
||||
except ImportError:
|
||||
return None
|
||||
|
||||
@@ -2,7 +2,7 @@ import ahriman.web.views
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from ahriman.core.module_loader import _modules, implementations
|
||||
from ahriman.core.module_loader import _modules, implementations, optional_module
|
||||
from ahriman.web.views.base import BaseView
|
||||
|
||||
|
||||
@@ -23,3 +23,17 @@ def test_implementations() -> None:
|
||||
assert routes
|
||||
assert all(isinstance(view, type) for view in routes)
|
||||
assert all(issubclass(view, BaseView) for view in routes)
|
||||
|
||||
|
||||
def test_optional_module() -> None:
|
||||
"""
|
||||
must import an available module
|
||||
"""
|
||||
assert optional_module("ahriman.web.views") is ahriman.web.views
|
||||
|
||||
|
||||
def test_optional_module_fallback() -> None:
|
||||
"""
|
||||
must return none when the module cannot be imported
|
||||
"""
|
||||
assert optional_module("missing_ahriman_module") is None
|
||||
|
||||
Reference in New Issue
Block a user