2020from __future__ import annotations
2121
2222import threading
23+ from contextvars import ContextVar , Token
2324from logging import getLogger
2425from typing import TYPE_CHECKING
2526
@@ -43,6 +44,7 @@ class DefaultBusTLStorage(threading.local):
4344
4445
4546bus_tls = DefaultBusTLStorage ()
47+ bus_contextvar : ContextVar [SdBus ] = ContextVar ("DEFAULT_BUS" )
4648
4749
4850def _get_defaul_bus_tls () -> Optional [SdBus ]:
@@ -54,10 +56,20 @@ def _set_default_bus_tls(new_bus: Optional[SdBus]) -> None:
5456
5557
5658def get_default_bus () -> SdBus :
57- """Get default thread-local bus."""
58- current_bus = _get_defaul_bus_tls ()
59- if current_bus is not None :
60- return current_bus
59+ """Get default bus.
60+
61+ Returns context-local default bus if set or
62+ thread-local otherwise.
63+
64+ If no default bus is set initializes a new bus using
65+ :py:func:`sdbus.sd_bus_open` and sets it as a thread-local
66+ default bus.
67+ """
68+ if (context_bus := bus_contextvar .get (None )) is not None :
69+ return context_bus
70+
71+ if (tls_bus := _get_defaul_bus_tls ()) is not None :
72+ return tls_bus
6173 else :
6274 new_bus = sd_bus_open ()
6375 logger .info (
@@ -69,7 +81,7 @@ def get_default_bus() -> SdBus:
6981
7082
7183def set_default_bus (new_default : SdBus ) -> None :
72- """Set default thread-local bus.
84+ """Set thread-local default bus.
7385
7486 Should be called before creating any objects that will use
7587 default bus.
@@ -80,6 +92,25 @@ def set_default_bus(new_default: SdBus) -> None:
8092 _set_default_bus_tls (new_default )
8193
8294
95+ def set_context_default_bus (new_default : SdBus ) -> Token [SdBus ]:
96+ """Set context-local default bus.
97+
98+ Should be called before creating any objects that will use
99+ default bus.
100+
101+ Default bus can be replaced but the change will only affect
102+ newly created objects.
103+
104+ Context-local default bus has higher priority over thread-local one
105+ but has to be explicitly set.
106+
107+ :returns:
108+ Token that can be used to reset context bus back.
109+ See ``contextvars`` documentation for details.
110+ """
111+ return bus_contextvar .set (new_default )
112+
113+
83114def _prepare_request_name_flags (
84115 allow_replacement : bool ,
85116 replace_existing : bool ,
@@ -167,6 +198,7 @@ def request_default_bus_name(
167198__all__ = (
168199 "get_default_bus" ,
169200 "set_default_bus" ,
201+ "set_context_default_bus" ,
170202 "request_default_bus_name_async" ,
171203 "request_default_bus_name" ,
172204)
0 commit comments