diff --git a/README.md b/README.md index 5b3ef8b..67c187d 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ Every keyword that is not one of stdlib's four (`exc_info`, `stack_info`, `LogurichLogger`; the original adapter is never mutated. `None` is a real context value. Remove bound values with `unbind()` or `try_unbind()`, remove selected ambient values with `global_context_unset()`, or clear all ambient -values with `clear_context()`. +values with `global_clear_context()`. ## Standard-library compatibility diff --git a/docs/migration-v1.md b/docs/migration-v1.md index ece81e1..6fae5b7 100644 --- a/docs/migration-v1.md +++ b/docs/migration-v1.md @@ -45,10 +45,12 @@ and receive no legacy interpretation. All context values now display their keys, including values built with `ctx()`, which hid the key in 0.9. Pass `ctx(value, show_key=False)` to hide a key, or `label=` to rename it; styling a value no longer changes whether its key is -shown. `None` is now a real value: `bind(key=None)` and +shown. Rename `global_context_configure(...)` to `global_context(...)` for a +temporary ambient context, and `clear_context()` to `global_clear_context()`. +`None` is now a real value: `bind(key=None)` and `global_context_set(key=None)` retain the key. Call `unbind("key")` to remove a bound value, `global_context_unset("key")` to remove an ambient value, or -`clear_context()` to clear all ambient values in the current execution. +`global_clear_context()` to clear all ambient values in the current execution. Logurich reserves no call keywords of its own and never will: every keyword that is not one of stdlib's four (`exc_info`, `stack_info`, `stacklevel`, `extra`) is diff --git a/examples/async_context.py b/examples/async_context.py index 9dd523b..73963a1 100644 --- a/examples/async_context.py +++ b/examples/async_context.py @@ -7,7 +7,7 @@ ctx, get_log_queue, get_logger, - global_context_configure, + global_context, init_logger, ) @@ -38,7 +38,7 @@ def background_thread_step() -> None: def background_process_step(log_queue: mp.Queue, request_id: str) -> None: configure_child_logging(log_queue) - with global_context_configure(request_id=ctx(request_id, style="bold cyan")): + with global_context(request_id=ctx(request_id, style="bold cyan")): process_log.info("Process task started") time.sleep(0.03) process_log.info("Process task finished") @@ -64,7 +64,7 @@ async def run_process_step(log_queue: mp.Queue, request_id: str) -> None: async def handle_request(request_id: str, log_queue: mp.Queue) -> None: - with global_context_configure(request_id=ctx(request_id, style="bold cyan")): + with global_context(request_id=ctx(request_id, style="bold cyan")): request_log.info("Request started") await fetch_user_profile() await asyncio.gather( diff --git a/examples/mp_adv_data_processing.py b/examples/mp_adv_data_processing.py index a4e9aca..6024f19 100644 --- a/examples/mp_adv_data_processing.py +++ b/examples/mp_adv_data_processing.py @@ -14,7 +14,7 @@ get_log_levels, get_log_queue, get_logger, - global_context_configure, + global_context, global_context_set, init_logger, ) @@ -92,7 +92,7 @@ def main(): log_levels = get_log_levels() logger = get_logger("processor.main") - with global_context_configure(group=ctx("DataProcessor", style="green")): + with global_context(group=ctx("DataProcessor", style="green")): logger.rich( "INFO", Panel( diff --git a/examples/mp_example.py b/examples/mp_example.py index 24c214a..be863b1 100644 --- a/examples/mp_example.py +++ b/examples/mp_example.py @@ -11,7 +11,7 @@ get_log_levels, get_log_queue, get_logger, - global_context_configure, + global_context, init_logger, ) @@ -20,7 +20,7 @@ def worker_function(log_queue, log_levels, worker_id): configure_child_logging(log_queue, levels=log_levels) logger = get_logger(f"workers.{worker_id}") - with global_context_configure(worker=ctx(f"Worker-{worker_id}")): + with global_context(worker=ctx(f"Worker-{worker_id}")): logger.info("Worker %s starting", worker_id) logger.debug("Worker %s debug message", worker_id) @@ -61,7 +61,7 @@ def main() -> None: get_logger("main").info("Multiprocessing example starting") - with global_context_configure(process=ctx("Main-Process", style="magenta")): + with global_context(process=ctx("Main-Process", style="magenta")): processes = [ mp.Process(target=worker_function, args=(log_queue, log_levels, i + 1)) for i in range(3) diff --git a/examples/serialize.py b/examples/serialize.py index 277d3ba..1effa8e 100644 --- a/examples/serialize.py +++ b/examples/serialize.py @@ -1,7 +1,7 @@ from rich.panel import Panel from rich.table import Table -from logurich import ctx, get_logger, global_context_configure, init_logger +from logurich import ctx, get_logger, global_context, init_logger def build_table() -> Table: @@ -33,7 +33,7 @@ def build_table() -> Table: nested={"key": "value"}, ) - with global_context_configure(request_id=ctx("req-42")): + with global_context(request_id=ctx("req-42")): logger.info("Message with scoped context") logger.rich( diff --git a/pyproject.toml b/pyproject.toml index 3fa48b2..27f825a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "logurich" -version = "1.0.0b1" +version = "1.0.0b2" description = "A Python library combining standard logging and Rich for beautiful logging." authors = [ { name = "PakitoSec", email = "jeromep83@gmail.com" } diff --git a/src/logurich/__init__.py b/src/logurich/__init__.py index 16c0488..60b870b 100644 --- a/src/logurich/__init__.py +++ b/src/logurich/__init__.py @@ -1,6 +1,6 @@ """Public package exports for logurich.""" -__version__ = "1.0.0b1" +__version__ = "1.0.0b2" from .console import ( console, @@ -12,9 +12,9 @@ ) from .context import ( ContextValue, - clear_context, ctx, - global_context_configure, + global_clear_context, + global_context, global_context_set, global_context_unset, ) @@ -45,10 +45,10 @@ "ctx", "ContextValue", "LogurichLogger", - "global_context_configure", + "global_context", "global_context_set", "global_context_unset", - "clear_context", + "global_clear_context", "console", "reset_console_after_fork", "rich_configure_console", diff --git a/src/logurich/context.py b/src/logurich/context.py index f6dfbe3..e61c0f3 100644 --- a/src/logurich/context.py +++ b/src/logurich/context.py @@ -138,7 +138,7 @@ def get_context() -> dict[str, ContextValue]: @contextlib.contextmanager -def global_context_configure(**values: Any) -> Iterator[None]: +def global_context(**values: Any) -> Iterator[None]: """Temporarily extend the context of the current execution. ``ContextVar`` propagation follows Python's normal rules: asyncio tasks @@ -172,7 +172,7 @@ def global_context_unset(*keys: str) -> None: _context_state.set(updated) -def clear_context() -> None: +def global_clear_context() -> None: """Clear all context in the current execution.""" _context_state.set({}) diff --git a/src/logurich/core.py b/src/logurich/core.py index c74f963..b95f494 100644 --- a/src/logurich/core.py +++ b/src/logurich/core.py @@ -27,10 +27,10 @@ from .console import rich_get_console, rich_to_str from .context import ( ContextValue, - clear_context, ctx, get_context, - global_context_configure, + global_clear_context, + global_context, normalize_context, ) from .handler import ( @@ -305,7 +305,7 @@ def try_unbind(self, *keys: str) -> LogurichLogger: def contextualize(self, **values: Any) -> contextlib.AbstractContextManager[None]: """Temporarily extend context for the current execution.""" - return global_context_configure(**values) + return global_context(**values) def process(self, msg: Any, kwargs: Any) -> tuple[Any, Any]: """Split stdlib options from per-call context.""" @@ -720,7 +720,7 @@ def shutdown_logger() -> None: "original_root_level": None, } ) - clear_context() + global_clear_context() def _ensure_shutdown_atexit_registered() -> None: diff --git a/tests/test_core.py b/tests/test_core.py index 7f2fd69..ed51fa4 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -16,10 +16,10 @@ CONSOLE_MODE_CHOICES, FILE_MODE_CHOICES, LogurichLogger, - clear_context, ctx, get_logger, - global_context_configure, + global_clear_context, + global_context, global_context_set, global_context_unset, init_logger, @@ -172,9 +172,9 @@ def test_context_priority_global_bound_call(enqueue, buffer): def test_nested_context_restores_outer_value(logger, buffer): - with global_context_configure(request="outer"): + with global_context(request="outer"): logger.info("first") - with global_context_configure(request="inner"): + with global_context(request="inner"): logger.info("second") logger.info("third") logger.info("fourth") @@ -196,8 +196,8 @@ def test_global_context_set_and_none_are_values(logger, buffer): def test_context_removal_api_is_public(): assert logurich.global_context_unset is global_context_unset - assert logurich.clear_context is clear_context - assert {"global_context_unset", "clear_context"} <= set(logurich.__all__) + assert logurich.global_clear_context is global_clear_context + assert {"global_context_unset", "global_clear_context"} <= set(logurich.__all__) def test_global_context_unset_removes_only_requested_keys(logger, buffer): @@ -212,9 +212,9 @@ def test_global_context_unset_removes_only_requested_keys(logger, buffer): assert "result=None" in output -def test_clear_context_removes_all_ambient_context(logger, buffer): +def test_global_clear_context_removes_all_ambient_context(logger, buffer): global_context_set(request="req-1", tenant="acme") - clear_context() + global_clear_context() logger.info("done") shutdown_logger() @@ -493,7 +493,7 @@ def test_init_is_idempotent_and_force_reconfigures(buffer): def test_context_is_isolated_from_new_thread(logger, buffer): - with global_context_configure(request="main"): + with global_context(request="main"): thread = threading.Thread(target=lambda: logger.info("thread")) thread.start() thread.join() @@ -510,7 +510,7 @@ async def child() -> None: logger.info("async child") async def run() -> None: - with global_context_configure(request="async"): + with global_context(request="async"): await asyncio.create_task(child()) asyncio.run(run()) diff --git a/tests/test_mp.py b/tests/test_mp.py index b047e9d..ca25837 100644 --- a/tests/test_mp.py +++ b/tests/test_mp.py @@ -18,7 +18,7 @@ get_log_levels, get_log_queue, get_logger, - global_context_configure, + global_context, init_logger, rich_get_console, shutdown_logger, @@ -33,7 +33,7 @@ def worker_process(queue): def worker_process_context(queue): configure_child_logging(queue) - with global_context_configure(task_id=ctx("task-id", show_key=True)): + with global_context(task_id=ctx("task-id", show_key=True)): logging.getLogger("workers.context").info("Message with context") diff --git a/uv.lock b/uv.lock index 1c037a9..a12e1be 100644 --- a/uv.lock +++ b/uv.lock @@ -164,7 +164,7 @@ wheels = [ [[package]] name = "logurich" -version = "1.0.0b1" +version = "1.0.0b2" source = { editable = "." } dependencies = [ { name = "rich" },