samschott / desktop-notifier

Python library for cross-platform desktop notifications
https://desktop-notifier.readthedocs.io
MIT License
81 stars 8 forks source link

Notification failed on Linux due to dbus-next type mismatch #143

Closed mimre25 closed 1 week ago

mimre25 commented 1 week ago

Description

I'm trying to send a simple desktop notification, but run into

dbus_next.errors.SignatureBodyMismatchError: DBus STRING type "s" must be Python type "str", got <class 'dbus_next.signature.Variant'>                 

What I Did

    notifier = DesktopNotifier()
    notifier.send_sync(title="Sit up", message="Bad Posture Detected")
Full Stacktrace ```py Notification failed Traceback (most recent call last): File "/home/martin/micromamba/envs/learnopencv/lib/python3.12/site-packages/desktop_notifier/base.py", line 218, in send await self._send(notification, notification_to_replace) File "/home/martin/micromamba/envs/learnopencv/lib/python3.12/site-packages/desktop_notifier/dbus.py", line 159, in _send platform_nid = await self.interface.call_notify( # type:ignore[attr-defined] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/martin/micromamba/envs/learnopencv/lib/python3.12/site-packages/dbus_next/aio/proxy_object.py", line 79, in method_fn msg = await self.bus.call( ^^^^^^^^^^^^^^^^^^^^ File "/home/martin/micromamba/envs/learnopencv/lib/python3.12/site-packages/dbus_next/aio/message_bus.py", line 303, in call self._call(msg, reply_handler) File "/home/martin/micromamba/envs/learnopencv/lib/python3.12/site-packages/dbus_next/message_bus.py", line 588, in _call self.send(msg) File "/home/martin/micromamba/envs/learnopencv/lib/python3.12/site-packages/dbus_next/aio/message_bus.py", line 326, in send self._writer.schedule_write(msg, future) File "/home/martin/micromamba/envs/learnopencv/lib/python3.12/site-packages/dbus_next/aio/message_bus.py", line 82, in schedule_write self.buffer_message(msg, future) File "/home/martin/micromamba/envs/learnopencv/lib/python3.12/site-packages/dbus_next/aio/message_bus.py", line 78, in buffer_message (msg._marshall(negotiate_unix_fd=self.negotiate_unix_fd), copy(msg.unix_fds), future)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/martin/micromamba/envs/learnopencv/lib/python3.12/site-packages/dbus_next/message.py", line 215, in _marshall body_block = Marshaller(self.signature, self.body) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/martin/micromamba/envs/learnopencv/lib/python3.12/site-packages/dbus_next/_private/marshaller.py", line 8, in __init__ self.signature_tree.verify(body) File "/home/martin/micromamba/envs/learnopencv/lib/python3.12/site-packages/dbus_next/signature.py", line 359, in verify type_.verify(body[i]) File "/home/martin/micromamba/envs/learnopencv/lib/python3.12/site-packages/dbus_next/signature.py", line 287, in verify self._verify_array(body) File "/home/martin/micromamba/envs/learnopencv/lib/python3.12/site-packages/dbus_next/signature.py", line 217, in _verify_array child_type.children[1].verify(value) File "/home/martin/micromamba/envs/learnopencv/lib/python3.12/site-packages/dbus_next/signature.py", line 283, in verify self._verify_string(body) File "/home/martin/micromamba/envs/learnopencv/lib/python3.12/site-packages/dbus_next/signature.py", line 196, in _verify_string raise SignatureBodyMismatchError( dbus_next.errors.SignatureBodyMismatchError: DBus STRING type "s" must be Python type "str", got ```
samschott commented 1 week ago

Thanks for the report! Could you narrow down which argument in particular raises the error? Looking at the code, only "hints" are passed at variants, which conforms to the spec at https://specifications.freedesktop.org/notification-spec/notification-spec-latest.html#protocol.

If you replace the hints that are passed with an empty dict instead, does the error persist?

https://github.com/samschott/desktop-notifier/blob/f8f6803aae12e94a60c534429ea9ba557fe95a14/src/desktop_notifier/dbus.py#L170-L179

mimre25 commented 1 week ago

Spot on, using hints={} makes it work just fine.

samschott commented 1 week ago

In that case, I suspect that Ubuntu 20.04 does not exactly conform to the notification spec.

Could you run the following in a Python interpreter and post the return value?

import asyncio
from desktop_notifier import *

dn = DesktopNotifier()

impl = dn._impl
interface = asyncio.run(impl._init_dbus())

notify_method = next(m for m in interface.introspection.methods if m.name == "Notify")
notify_method.in_signature

The output should help explain what arguments exactly Ubuntu is expecting.

mimre25 commented 1 week ago

'susssasa{ss}i'

samschott commented 1 week ago

Thanks! That does indeed not conform to the current spec where hints are given as a dictionary of dict[str, Variant]. Instead, Ubuntu 20.04 seems to expect a dict of dict[str, str].

I don't have a VM with Ubuntu 20.04 unfortunately, so could you try one more command?

import asyncio
from desktop_notifier import *

dn = DesktopNotifier()

async def send_notification():
  interface = await dn._impl._init_dbus()
  await interface.call_notify('', 0, '', 'title', 'message', [], {'urgency': '2'}, -1)

asyncio.run(send_notification())

Does this also raise an error? Or does the notification succeed?

mimre25 commented 1 week ago

This works fine and the notification is sent.