diff --git a/src/dbus_fast/message_bus.py b/src/dbus_fast/message_bus.py index a9058d51..82481059 100644 --- a/src/dbus_fast/message_bus.py +++ b/src/dbus_fast/message_bus.py @@ -693,11 +693,10 @@ def _introspect_export_path(self, path: str) -> intr.Node: children = set() for export_path in self._path_exports: - try: - child_path = export_path.split(path, maxsplit=1)[1] - except IndexError: + if not export_path.startswith(path): continue + child_path = export_path.split(path, maxsplit=1)[1] child_path = child_path.lstrip("/") child_name = child_path.split("/", maxsplit=1)[0] diff --git a/tests/service/test_standard_interfaces.py b/tests/service/test_standard_interfaces.py index dc8213ca..bc137fcb 100644 --- a/tests/service/test_standard_interfaces.py +++ b/tests/service/test_standard_interfaces.py @@ -83,6 +83,40 @@ async def test_introspectable_interface(): bus2.disconnect() +@pytest.mark.asyncio +async def test_introspect_matching_sub_paths(): + bus1 = await MessageBus().connect() + bus2 = await MessageBus().connect() + + interface = ExampleInterface("test.interface1") + + bus1.export("/a/test/path1", interface) + bus1.export("/a/subpath/a/test/path2", interface) + + async def introspect_subpath(path, expected_subnodes): + reply = await bus2.call( + Message( + destination=bus1.unique_name, + path=path, + interface="org.freedesktop.DBus.Introspectable", + member="Introspect", + ) + ) + assert reply.signature == "s" + node = intr.Node.parse(reply.body[0]) + assert {n.name for n in node.nodes} == expected_subnodes + + await introspect_subpath("/", {"a"}) + await introspect_subpath("/a", {"test", "subpath"}) + await introspect_subpath("/a/test", {"path1"}) + await introspect_subpath("/a/test/path1", set()) + await introspect_subpath("/a/subpath/a/test", {"path2"}) + await introspect_subpath("/a/subpath/a/test/path2", set()) + + bus1.disconnect() + bus2.disconnect() + + @pytest.mark.asyncio async def test_peer_interface(): bus1 = await MessageBus().connect()