xibus

experimental pure python async D-Bus library
git clone https://git.ce9e.org/xibus.git

commit
16d0005ef362b5ff8e257f03d4a46f636c39f94d
parent
3bc253e4d8737c98084defcd0ccb1a54a7da05fd
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2026-02-16 08:58
add magic client

Diffstat

M xibus/__init__.py 4 ++--
M xibus/client.py 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++

2 files changed, 54 insertions, 2 deletions


diff --git a/xibus/__init__.py b/xibus/__init__.py

@@ -1,6 +1,6 @@
    1     1 import contextlib
    2     2 
    3    -1 from .client import Client
   -1     3 from .client import MagicClient
    4     4 from .client import Proxy  # noqa
    5     5 from .connection import DBusError  # noqa
    6     6 from .connection import get_connection
@@ -9,4 +9,4 @@ from .connection import get_connection
    9     9 @contextlib.asynccontextmanager
   10    10 async def get_client(bus):
   11    11     async with get_connection(bus) as con:
   12    -1         yield Client(con)
   -1    12         yield MagicClient(con)

diff --git a/xibus/client.py b/xibus/client.py

@@ -130,3 +130,55 @@ class Client:
  130   130                         yield changed[prop][1]
  131   131                     elif prop in invalidated:
  132   132                         yield None
   -1   133 
   -1   134 
   -1   135 class MagicClient(Client):
   -1   136     async def _iter_paths(self, name, path=''):
   -1   137         schema = await self.introspect(name, path or '/')
   -1   138         if schema.interfaces:
   -1   139             yield path or '/'
   -1   140         for child in schema.nodes:
   -1   141             async for p in self._iter_paths(name, f'{path}/{child}'):
   -1   142                 yield p
   -1   143 
   -1   144     async def _guess_iface(self, name, key, value, path, iface=None):
   -1   145         if iface:
   -1   146             return iface
   -1   147         schema = await self.introspect(name, path)
   -1   148         for iface, s in schema.interfaces.items():
   -1   149             if value in getattr(s, key):
   -1   150                 return iface
   -1   151         raise ValueError((name, key, value, path))
   -1   152 
   -1   153     async def _guess_path(self, name, key, value, path=None, iface=None):
   -1   154         if path:
   -1   155             return path, await self._guess_iface(name, key, value, path, iface)
   -1   156         async for path in self._iter_paths(name):
   -1   157             try:
   -1   158                 return path, await self._guess_iface(name, key, value, path, iface)
   -1   159             except ValueError:
   -1   160                 pass
   -1   161         raise ValueError((name, key, value))
   -1   162 
   -1   163     async def call(self, name, path, iface, method, params=(), sig=None):
   -1   164         path, iface = await self._guess_path(name, 'methods', method, path, iface)
   -1   165         return await super().call(name, path, iface, method, params, sig)
   -1   166 
   -1   167     @contextlib.asynccontextmanager
   -1   168     async def subscribe_signal(self, name, path, iface, signal):
   -1   169         path, iface = await self._guess_path(name, 'signals', signal, path, iface)
   -1   170         async with super().subscribe_signal(name, path, iface, signal) as queue:
   -1   171             yield queue
   -1   172 
   -1   173     async def get_property(self, name, path, iface, prop):
   -1   174         path, iface = await self._guess_path(name, 'properties', prop, path, iface)
   -1   175         return await super().get_property(name, path, iface, prop)
   -1   176 
   -1   177     async def set_property(self, name, path, iface, prop, value, sig=None):
   -1   178         path, iface = await self._guess_path(name, 'properties', prop, path, iface)
   -1   179         await super().set_property(name, path, iface, prop, value, sig)
   -1   180 
   -1   181     async def watch_property(self, name, path, iface, prop):
   -1   182         path, iface = await self._guess_path(name, 'properties', prop, path, iface)
   -1   183         async for value in super().watch_property(name, path, iface, prop):
   -1   184             yield value