Skip to content

Commit

Permalink
fix(picologging): updates to handle unsupported environments (python …
Browse files Browse the repository at this point in the history
…3.13, etc.)
  • Loading branch information
cofin committed Dec 30, 2024
1 parent ebdb6e5 commit aeec0e7
Show file tree
Hide file tree
Showing 4 changed files with 189 additions and 60 deletions.
7 changes: 5 additions & 2 deletions litestar/logging/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,13 +292,16 @@ def configure(self) -> GetLogger:

if self.logging_module == "picologging":
try:
from picologging import config, getLogger
from picologging import ( # pyright: ignore[reportMissingImports,reportGeneralTypeIssues]
config, # pyright: ignore[reportMissingImports,reportGeneralTypeIssues]
getLogger, # pyright: ignore[reportMissingImports,reportGeneralTypeIssues]
)
except ImportError as e:
raise MissingDependencyException("picologging") from e

excluded_fields.add("incremental")
else:
from logging import config, getLogger # type: ignore[no-redef, assignment]
from logging import config, getLogger # type: ignore[no-redef,assignment,unused-ignore]

values = {
_field.name: getattr(self, _field.name)
Expand Down
12 changes: 6 additions & 6 deletions litestar/logging/picologging.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@


try:
import picologging # noqa: F401
import picologging # noqa: F401 # pyright: ignore[reportMissingImports]
except ImportError as e:
raise MissingDependencyException("picologging") from e

from picologging import StreamHandler
from picologging.handlers import QueueHandler, QueueListener
from picologging import StreamHandler # pyright: ignore[reportMissingImports]
from picologging.handlers import QueueHandler, QueueListener # pyright: ignore[reportMissingImports]


class QueueListenerHandler(QueueHandler):
class QueueListenerHandler(QueueHandler): # type: ignore[misc,unused-ignore]
"""Configure queue listener and handler to support non-blocking logging configuration."""

def __init__(self, handlers: list[Any] | None = None) -> None:
Expand All @@ -32,8 +32,8 @@ def __init__(self, handlers: list[Any] | None = None) -> None:
- Requires ``picologging`` to be installed.
"""
super().__init__(Queue(-1))
handlers = resolve_handlers(handlers) if handlers else [StreamHandler()]
self.listener = QueueListener(self.queue, *handlers)
handlers = resolve_handlers(handlers) if handlers else [StreamHandler()] # pyright: ignore[reportGeneralTypeIssues]
self.listener = QueueListener(self.queue, *handlers) # pyright: ignore[reportGeneralTypeIssues]
self.listener.start()

atexit.register(self.listener.stop)
15 changes: 12 additions & 3 deletions tests/helpers.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
from __future__ import annotations

import atexit
import importlib.util
import inspect
import logging
import random
import sys
from contextlib import AbstractContextManager, contextmanager
from pathlib import Path
from typing import Any, AsyncContextManager, Awaitable, ContextManager, Generator, TypeVar, cast, overload

import picologging
import pytest
from _pytest.logging import LogCaptureHandler, _LiveLoggingNullHandler

from litestar._openapi.schema_generation import SchemaCreator
Expand Down Expand Up @@ -90,9 +92,9 @@ def cleanup_logging_impl() -> Generator:
# Don't interfere with PyTest handler config
if not isinstance(std_handler, (_LiveLoggingNullHandler, LogCaptureHandler)):
std_root_logger.removeHandler(std_handler)

picologging = pytest.importorskip("picologging")
# Reset root logger (`picologging` module)
pico_root_logger: picologging.Logger = picologging.getLogger()
pico_root_logger: picologging.Logger = picologging.getLogger() # type: ignore[name-defined,unused-ignore] # pyright: ignore[reportPrivateUsage,reportGeneralTypeIssues,reportAssignmentType,reportInvalidTypeForm]
for pico_handler in pico_root_logger.handlers:
pico_root_logger.removeHandler(pico_handler)

Expand All @@ -111,3 +113,10 @@ def cleanup_logging_impl() -> Generator:
def not_none(val: T | None) -> T:
assert val is not None
return val


def purge_module(module_names: list[str], path: str | Path) -> None:
for name in module_names:
if name in sys.modules:
del sys.modules[name]
Path(importlib.util.cache_from_source(path)).unlink(missing_ok=True) # type: ignore[arg-type]
Loading

0 comments on commit aeec0e7

Please sign in to comment.