|
19 | 19 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
20 | 20 | from __future__ import annotations |
21 | 21 |
|
| 22 | +from contextvars import ContextVar, copy_context |
22 | 23 | from inspect import iscoroutinefunction |
23 | 24 | from types import FunctionType |
24 | 25 | from typing import ( |
|
42 | 43 | from .dbus_exceptions import DbusFailedError |
43 | 44 | from .sd_bus_internals import DbusNoReplyFlag, SdBusMessage |
44 | 45 |
|
| 46 | +CURRENT_MESSAGE: ContextVar[SdBusMessage] = ContextVar('CURRENT_MESSAGE') |
| 47 | + |
| 48 | + |
| 49 | +def get_current_message() -> SdBusMessage: |
| 50 | + return CURRENT_MESSAGE.get() |
| 51 | + |
| 52 | + |
45 | 53 | T_input = TypeVar('T_input') |
46 | 54 | T = TypeVar('T') |
47 | 55 |
|
@@ -118,24 +126,38 @@ def __call__(self, *args: Any, **kwargs: Any) -> Any: |
118 | 126 | return self.dbus_method.original_method( |
119 | 127 | interface, *args, **kwargs) |
120 | 128 |
|
| 129 | + async def _call_method_from_dbus( |
| 130 | + self, |
| 131 | + request_message: SdBusMessage, |
| 132 | + interface: DbusInterfaceBaseAsync) -> Any: |
| 133 | + request_data = request_message.get_contents() |
| 134 | + |
| 135 | + local_method = self.dbus_method.original_method.__get__( |
| 136 | + interface, None) |
| 137 | + |
| 138 | + CURRENT_MESSAGE.set(request_message) |
| 139 | + |
| 140 | + if isinstance(request_data, tuple): |
| 141 | + return await local_method(*request_data) |
| 142 | + elif request_data is None: |
| 143 | + return await local_method() |
| 144 | + else: |
| 145 | + return await local_method(request_data) |
| 146 | + |
121 | 147 | async def _call_from_dbus( |
122 | 148 | self, |
123 | 149 | request_message: SdBusMessage) -> None: |
124 | 150 | interface = self.interface_ref() |
125 | 151 | assert interface is not None |
126 | 152 |
|
127 | | - request_data = request_message.get_contents() |
128 | | - |
129 | | - local_method = self.dbus_method.original_method.__get__( |
130 | | - interface, None) |
| 153 | + call_context = copy_context() |
131 | 154 |
|
132 | 155 | try: |
133 | | - if isinstance(request_data, tuple): |
134 | | - reply_data = await local_method(*request_data) |
135 | | - elif request_data is None: |
136 | | - reply_data = await local_method() |
137 | | - else: |
138 | | - reply_data = await local_method(request_data) |
| 156 | + reply_data = await call_context.run( |
| 157 | + self._call_method_from_dbus, |
| 158 | + request_message, |
| 159 | + interface, |
| 160 | + ) |
139 | 161 | except DbusFailedError as e: |
140 | 162 | if not request_message.expect_reply: |
141 | 163 | return |
|
0 commit comments