diff --git a/a_sync/primitives/_debug.pyi b/a_sync/primitives/_debug.pyi new file mode 100644 index 00000000..7d913243 --- /dev/null +++ b/a_sync/primitives/_debug.pyi @@ -0,0 +1,12 @@ +import abc +from a_sync.primitives._loggable import _LoggerMixin + +class _DebugDaemonMixin(_LoggerMixin, metaclass=abc.ABCMeta): + """ + A mixin class that provides a framework for debugging capabilities using a daemon task. + + This mixin sets up the structure for managing a debug daemon task. Subclasses are responsible for implementing the specific behavior of the daemon, including any logging functionality. + + See Also: + :class:`_LoggerMixin` for logging capabilities. + """ diff --git a/a_sync/primitives/_debug.py b/a_sync/primitives/_debug.pyx similarity index 95% rename from a_sync/primitives/_debug.py rename to a_sync/primitives/_debug.pyx index b31bece2..1cfc650b 100644 --- a/a_sync/primitives/_debug.py +++ b/a_sync/primitives/_debug.pyx @@ -8,6 +8,7 @@ import asyncio from typing import Optional +import a_sync.asyncio from a_sync.primitives._loggable import _LoggerMixin @@ -72,9 +73,10 @@ def _start_debug_daemon(self, *args, **kwargs) -> "asyncio.Future[None]": See Also: :meth:`_ensure_debug_daemon` for ensuring the daemon is running. """ - if self.debug_logs_enabled and asyncio.get_event_loop().is_running(): - return asyncio.create_task(self._debug_daemon(*args, **kwargs)) - return asyncio.get_event_loop().create_future() + loop = asyncio.get_event_loop() + if self.debug_logs_enabled and loop.is_running(): + return a_sync.asyncio.create_task(self._debug_daemon(*args, **kwargs)) + return loop.create_future() def _ensure_debug_daemon(self, *args, **kwargs) -> "asyncio.Future[None]": """ diff --git a/a_sync/primitives/_loggable.pyi b/a_sync/primitives/_loggable.pyi new file mode 100644 index 00000000..614db33f --- /dev/null +++ b/a_sync/primitives/_loggable.pyi @@ -0,0 +1,62 @@ +from functools import cached_property as cached_property +from logging import Logger + +class _LoggerMixin: + """ + A mixin class that adds logging capabilities to other classes. + + This mixin provides a cached property for accessing a logger instance and a property to check if debug logging is enabled. + + See Also: + - :func:`logging.getLogger` + - :class:`logging.Logger` + """ + + @cached_property + def logger(self) -> Logger: + """ + Provides a logger instance specific to the class using this mixin. + + The logger ID is constructed from the module and class name, and optionally includes an instance name if available. + + Examples: + >>> class MyClass(_LoggerMixin): + ... _name = "example" + ... + >>> instance = MyClass() + >>> logger = instance.logger + >>> logger.name + \'module_name.MyClass.example\' + + >>> class AnotherClass(_LoggerMixin): + ... pass + ... + >>> another_instance = AnotherClass() + >>> another_logger = another_instance.logger + >>> another_logger.name + \'module_name.AnotherClass\' + + Note: + Replace `module_name` with the actual module name where the class is defined. + + See Also: + - :func:`logging.getLogger` + - :class:`logging.Logger` + """ + + @property + def debug_logs_enabled(self) -> bool: + """ + Checks if debug logging is enabled for the logger. + + Examples: + >>> class MyClass(_LoggerMixin): + ... pass + ... + >>> instance = MyClass() + >>> instance.debug_logs_enabled + False + + See Also: + - :attr:`logging.Logger.isEnabledFor` + """ diff --git a/a_sync/primitives/_loggable.py b/a_sync/primitives/_loggable.pyx similarity index 100% rename from a_sync/primitives/_loggable.py rename to a_sync/primitives/_loggable.pyx