diff --git a/docs/contextvars.rst b/docs/contextvars.rst index 6ed9e28b..f581900f 100644 --- a/docs/contextvars.rst +++ b/docs/contextvars.rst @@ -46,7 +46,8 @@ The general flow is: >>> # middleware), clear the threadlocal context and bind some common >>> # values: >>> clear_contextvars() - >>> bind_contextvars(a=1, b=2) + >>> bind_contextvars(a=1) + >>> bind_contextvars(b=2) >>> # Then use loggers as per normal >>> # (perhaps by using structlog.get_logger() to create them). >>> log.msg("hello") diff --git a/src/structlog/contextvars.py b/src/structlog/contextvars.py index e6f86a0a..7c8a5a1f 100644 --- a/src/structlog/contextvars.py +++ b/src/structlog/contextvars.py @@ -8,7 +8,8 @@ .. versionadded:: 20.1.0 .. versionchanged:: 21.1.0 - Reimplement code without dict + Reimplemented without using a single dict as context carrier for improved + isolation. Every key-value pair is a separate `contextvars.ContextVar` now. See :doc:`contextvars`. """ diff --git a/tests/test_contextvars.py b/tests/test_contextvars.py index 892f7056..df016612 100644 --- a/tests/test_contextvars.py +++ b/tests/test_contextvars.py @@ -3,6 +3,7 @@ # repository for complete details. import asyncio +import secrets import pytest @@ -112,7 +113,7 @@ async def coro(): assert {} == await event_loop.create_task(coro()) - async def test_undbind(self, event_loop): + async def test_unbind(self, event_loop): """ Unbinding a previously bound variable causes it to be removed from the result of merge_contextvars. @@ -125,13 +126,16 @@ async def coro(): assert {"b": 2} == await event_loop.create_task(coro()) - async def test_undbind_not_bound(self, event_loop): + async def test_unbind_not_bound(self, event_loop): """ Unbinding a not bound variable causes doesn't raise an exception. """ async def coro(): - unbind_contextvars("a") + # Since unbinding means "setting to Ellipsis", we have to make + # some effort to ensure that the ContextVar never existed. + unbind_contextvars("a" + secrets.token_hex()) + return merge_contextvars(None, None, {"b": 2}) assert {"b": 2} == await event_loop.create_task(coro())