altdesktop / python-dbus-next

🚌 The next great DBus library for Python with asyncio support
https://python-dbus-next.readthedocs.io/en/latest/
MIT License
191 stars 60 forks source link

Message handler receives METHOD_RETURN message despite match_rule for type=`signal` #76

Closed elParaguayo closed 3 years ago

elParaguayo commented 3 years ago

This may be me misunderstanding the message handler but I'm still confused.

My code is as follows:

from dbus_next.aio import MessageBus

import asyncio

loop = asyncio.get_event_loop()

async def main():
    bus = await MessageBus().connect()

    def mess(message):
        for att in dir(message):
            if not att.startswith("_"):
                print("{}: {}".format(att, getattr(message, att)))

        print()

    bus._add_match_rule("type='signal',sender='org.mpris.MediaPlayer2.vlc',member='PropertiesChanged',interface='org.freedesktop.DBus.Properties',path='/org/mpris/MediaPlayer2'")
    bus.add_message_handler(mess)

    while True:
        await asyncio.sleep(1)

loop.run_until_complete(main())

While this runs correctly and does give me the messages I want. When I first run it, I also get this output:

body: []
destination: :1.113
error_name: None
flags: MessageFlag.NO_REPLY_EXPECTED
interface: None
member: None
message_type: MessageType.METHOD_RETURN
new_error: <function Message.new_error at 0x7fad51ed0160>
new_method_return: <function Message.new_method_return at 0x7fad51ed01f0>
new_signal: <function Message.new_signal at 0x7fad51ed0280>
path: None
reply_serial: 2
sender: org.freedesktop.DBus
serial: 3
signature:
signature_tree: <dbus_next.signature.SignatureTree object at 0x7fad5173ef40>
unix_fds: []

None of these properties match my rule so I'm not sure why I'm receiving it.

I can test for the message_type in the handler but I would have preferred the handler not to receive this message at all.

What have I missed?

acrisci commented 3 years ago

Don't use _add_match_rule(). It's private and undocumented. In the future I might add this method to the public interface and it will work like you expect. Add the match rule manually like this:

    reply = await bus.call(
        Message(destination='org.freedesktop.DBus',
                path='/org/freedesktop/DBus',
                member='AddMatch',
                signature='s',
                body=["sender=':23'"]))