7
7
Python 3.7 as :mod:`contextvars`.
8
8
9
9
.. versionadded:: 20.1.0
10
+ .. versionchanged:: 14.0.0
11
+ Reimplement code without dict
10
12
11
13
See :doc:`contextvars`.
12
14
"""
15
17
16
18
from typing import Any , Dict
17
19
18
- from .types import Context , EventDict , WrappedLogger
20
+ from .types import EventDict , WrappedLogger
19
21
20
22
21
- _CONTEXT : contextvars .ContextVar [Dict [str , Any ]] = contextvars .ContextVar (
22
- "structlog_context"
23
- )
23
+ STRUCTLOG_KEY_PREFIX = "structlog_"
24
+ _CONTEXT_VARS : Dict [str , contextvars .ContextVar [Any ]] = {}
24
25
25
26
26
27
def merge_contextvars (
@@ -33,11 +34,15 @@ def merge_contextvars(
33
34
context-local context is included in all log calls.
34
35
35
36
.. versionadded:: 20.1.0
37
+ .. versionchanged:: 20.2.0 See toplevel note
36
38
"""
37
- ctx = _get_context ().copy ()
38
- ctx .update (event_dict )
39
+ ctx = contextvars .copy_context ()
39
40
40
- return ctx
41
+ for k in ctx :
42
+ if k .name .startswith (STRUCTLOG_KEY_PREFIX ) and ctx [k ] is not Ellipsis :
43
+ event_dict .setdefault (k .name [len (STRUCTLOG_KEY_PREFIX ) :], ctx [k ])
44
+
45
+ return event_dict
41
46
42
47
43
48
def clear_contextvars () -> None :
@@ -48,9 +53,12 @@ def clear_contextvars() -> None:
48
53
handling code.
49
54
50
55
.. versionadded:: 20.1.0
56
+ .. versionchanged:: 20.2.0 See toplevel note
51
57
"""
52
- ctx = _get_context ()
53
- ctx .clear ()
58
+ ctx = contextvars .copy_context ()
59
+ for k in ctx :
60
+ if k .name .startswith (STRUCTLOG_KEY_PREFIX ):
61
+ k .set (Ellipsis )
54
62
55
63
56
64
def bind_contextvars (** kw : Any ) -> None :
@@ -61,8 +69,17 @@ def bind_contextvars(**kw: Any) -> None:
61
69
context to be global (context-local).
62
70
63
71
.. versionadded:: 20.1.0
72
+ .. versionchanged:: 20.2.0 See toplevel note
64
73
"""
65
- _get_context ().update (kw )
74
+ for k , v in kw .items ():
75
+ structlog_k = f"{ STRUCTLOG_KEY_PREFIX } { k } "
76
+ try :
77
+ var = _CONTEXT_VARS [structlog_k ]
78
+ except KeyError :
79
+ var = contextvars .ContextVar (structlog_k , default = Ellipsis )
80
+ _CONTEXT_VARS [structlog_k ] = var
81
+
82
+ var .set (v )
66
83
67
84
68
85
def unbind_contextvars (* keys : str ) -> None :
@@ -73,15 +90,9 @@ def unbind_contextvars(*keys: str) -> None:
73
90
remove keys from a global (context-local) context.
74
91
75
92
.. versionadded:: 20.1.0
93
+ .. versionchanged:: 20.2.0 See toplevel note
76
94
"""
77
- ctx = _get_context ()
78
- for key in keys :
79
- ctx .pop (key , None )
80
-
81
-
82
- def _get_context () -> Context :
83
- try :
84
- return _CONTEXT .get ()
85
- except LookupError :
86
- _CONTEXT .set ({})
87
- return _CONTEXT .get ()
95
+ for k in keys :
96
+ structlog_k = f"{ STRUCTLOG_KEY_PREFIX } { k } "
97
+ if structlog_k in _CONTEXT_VARS :
98
+ _CONTEXT_VARS [structlog_k ].set (Ellipsis )
0 commit comments