Skip to content

Commit

Permalink
Added properties_get_all_dict() method
Browse files Browse the repository at this point in the history
Equivalent to `GetAll` method of the
``org.freedesktop.DBus.Properties`` interface but the member
names are automatically translated to python names.
  • Loading branch information
igo95862 committed Jul 31, 2022
1 parent bbe9efc commit ae5b0a9
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 3 deletions.
13 changes: 13 additions & 0 deletions docs/asyncio_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,19 @@ Classes
:return: string with introspection XML
:rtype: str

.. py:method:: properties_get_all_dict()
:async:

Get all object properties as a dictionary where keys are member
names and values are properties values.

Equivalent to ``GetAll`` method of the ``org.freedesktop.DBus.Properties``
interface but the member names are automatically translated to python
names. (internally calls it for each interface used in class definition)

:return: dictionary of properties
:rtype: Dict[str, Any]

.. py:attribute:: properties_changed
:type: Tuple[str, Dict[str, Tuple[str, Any]], List[str]]

Expand Down
12 changes: 12 additions & 0 deletions docs/sync_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,18 @@ Classes
:return: string with introspection XML
:rtype: str

.. py:method:: properties_get_all_dict()
Get all object properties as a dictionary where keys are member
names and values are properties values.

Equivalent to ``GetAll`` method of the ``org.freedesktop.DBus.Properties``
interface but the member names are automatically translated to python
names. (internally calls it for each interface used in class definition)

:return: dictionary of properties
:rtype: Dict[str, Any]

Example: ::

from sdbus import (DbusInterfaceCommon,
Expand Down
12 changes: 12 additions & 0 deletions src/sdbus/dbus_proxy_async_interface_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
Dict,
List,
Optional,
Set,
Tuple,
Type,
TypeVar,
Expand Down Expand Up @@ -64,6 +65,11 @@ def __new__(cls, name: str,
serving_enabled: bool = True,
) -> DbusInterfaceMetaAsync:

dbus_served_interfaces_names = (
{interface_name}
if serving_enabled and interface_name is not None
else set()
)
dbus_to_python_name_map: Dict[str, str] = {}
superclass_members: Dict[str, DbusBindedAsync] = {}

Expand All @@ -72,6 +78,9 @@ def __new__(cls, name: str,
dbus_to_python_name_map.update(
base._dbus_to_python_name_map
)
dbus_served_interfaces_names.update(
base._dbus_served_interfaces_names
)

for name, value in getmembers(base):
if isinstance(
Expand Down Expand Up @@ -139,6 +148,8 @@ def __new__(cls, name: str,
" without using @dbus_overload decorator"
)

namespace['_dbus_served_interfaces_names'] = \
dbus_served_interfaces_names
namespace['_dbus_to_python_name_map'] = dbus_to_python_name_map
namespace['_dbus_interface_name'] = interface_name
namespace['_dbus_serving_enabled'] = serving_enabled
Expand All @@ -155,6 +166,7 @@ class DbusInterfaceBaseAsync(metaclass=DbusInterfaceMetaAsync):
_dbus_interface_name: Optional[str]
_dbus_serving_enabled: bool
_dbus_to_python_name_map: Dict[str, str]
_dbus_served_interfaces_names: Set[str]

def __init__(self) -> None:
self._activated_interfaces: List[SdBusInterface] = []
Expand Down
17 changes: 17 additions & 0 deletions src/sdbus/dbus_proxy_async_interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,23 @@ def __init__(self) -> None:
def properties_changed(self) -> DBUS_PROPERTIES_CHANGED_TYPING:
...

@dbus_method_async('s', 'a{sv}', method_name='GetAll')
async def _properties_get_all(
self, interface_name: str) -> Dict[str, Tuple[str, Any]]:
raise NotImplementedError

async def properties_get_all_dict(self) -> Dict[str, Any]:
properties: Dict[str, Any] = {}

for interface_name in self._dbus_served_interfaces_names:
dbus_properties_data = await self._properties_get_all(
interface_name)
for member_name, variant in dbus_properties_data.items():
python_name = self._dbus_to_python_name_map[member_name]
properties[python_name] = variant[1]

return properties


class DbusInterfaceCommonAsync(
DbusPeerInterfaceAsync, DbusPropertiesInterfaceAsync,
Expand Down
10 changes: 9 additions & 1 deletion src/sdbus/dbus_proxy_sync_interface_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ def __new__(cls, name: str,
serving_enabled: bool = True,
) -> DbusInterfaceMetaSync:

dbus_served_interfaces_names = (
{interface_name}
if serving_enabled and interface_name is not None
else set()
)
dbus_to_python_name_map: Dict[str, str] = {}
declared_interfaces = set()
# Set interface name
Expand Down Expand Up @@ -70,8 +75,10 @@ def __new__(cls, name: str,

for key in super_declared_interfaces & namespace.keys():
raise TypeError("Attempted to overload dbus definition"
" sync interfaces do not support overloading")
" blocking interfaces do not support overloading")

namespace['_dbus_served_interfaces_names'] = \
dbus_served_interfaces_names
namespace['_dbus_declared_interfaces'] = declared_interfaces
namespace['_dbus_to_python_name_map'] = dbus_to_python_name_map

Expand All @@ -88,6 +95,7 @@ class DbusInterfaceBase(metaclass=DbusInterfaceMetaSync):
_dbus_declared_interfaces: Set[str]
_dbus_serving_enabled: bool
_dbus_to_python_name_map: Dict[str, str]
_dbus_served_interfaces_names: Set[str]

def __init__(
self,
Expand Down
29 changes: 27 additions & 2 deletions src/sdbus/dbus_proxy_sync_interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
from __future__ import annotations

from typing import Any, Dict
from typing import Any, Dict, Tuple

from .dbus_proxy_sync_interface_base import DbusInterfaceBase
from .dbus_proxy_sync_method import dbus_method
Expand Down Expand Up @@ -51,8 +51,33 @@ def dbus_introspect(self) -> str:
raise NotImplementedError


class DbusPropertiesInterface(
DbusInterfaceBase,
interface_name='org.freedesktop.DBus.Properties',
serving_enabled=False,
):
@dbus_method('s', 'a{sv}', method_name='GetAll')
def _properties_get_all(
self, interface_name: str) -> Dict[str, Tuple[str, Any]]:
raise NotImplementedError

def properties_get_all_dict(self) -> Dict[str, Any]:
properties: Dict[str, Any] = {}

for interface_name in self._dbus_served_interfaces_names:
dbus_properties_data = self._properties_get_all(
interface_name)
for member_name, variant in dbus_properties_data.items():
python_name = self._dbus_to_python_name_map[member_name]
properties[python_name] = variant[1]

return properties


class DbusInterfaceCommon(
DbusPeerInterface, DbusIntrospectable):
DbusPeerInterface,
DbusIntrospectable,
DbusPropertiesInterface):
...


Expand Down
18 changes: 18 additions & 0 deletions test/test_sd_bus_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -759,3 +759,21 @@ def test(self) -> str:
'^Invalid signal name',
test_bad_signal_name,
)

async def test_properties_get_all_dict(self) -> None:
test_object, test_object_connection = initialize_object()

dbus_dict = await test_object_connection._properties_get_all(
'org.test.test')

self.assertEqual(
await test_object.test_property,
dbus_dict['TestProperty'][1],
)

self.assertEqual(
await test_object.test_property,
(
await test_object_connection.properties_get_all_dict()
)['test_property'],
)
3 changes: 3 additions & 0 deletions test/test_sd_bus_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ def test_invalid_assignment() -> None:
s._dbus_to_python_name_map['Features'],
)

with self.subTest('Test properties_get_all_dict'):
self.assertIn('features', s.properties_get_all_dict())

def test_docstring(self) -> None:
from pydoc import getdoc

Expand Down

0 comments on commit ae5b0a9

Please sign in to comment.