Bug 50370 - dbus-python doesn't automatically convert strings to variants/object-paths
Summary: dbus-python doesn't automatically convert strings to variants/object-paths
Status: RESOLVED NOTOURBUG
Alias: None
Product: dbus
Classification: Unclassified
Component: python (show other bugs)
Version: 1.5
Hardware: x86 (IA32) Linux (All)
: medium normal
Assignee: Simon McVittie
QA Contact: John (J5) Palmieri
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-05-26 07:47 UTC by Dmitry Shachnev
Modified: 2012-05-30 04:32 UTC (History)
1 user (show)

See Also:
i915 platform:
i915 features:


Attachments

Description Dmitry Shachnev 2012-05-26 07:47:31 UTC
I'm using dbus-python 1.1.0-1 from Debian unstable.

As described in http://dbus.freedesktop.org/doc/dbus-python/doc/tutorial.html#container-types:

> If a non-variant is passed as an argument but introspection indicates that a variant is expected, it'll automatically be wrapped in a variant.

However, it doesn't seem to work. This example tries to open a SecretService session, but fails:

import dbus

bus = dbus.SessionBus()
service_obj = bus.get_object('org.freedesktop.secrets', '/org/freedesktop/secrets')
service_iface = dbus.Interface(service_obj, 'org.freedesktop.Secret.Service')

# This doesn't work
service_iface.OpenSession('plain', '')
    
# This works
service_iface.OpenSession('plain', dbus.String(variant_level=1))

Here, the signature of OpenSession is 'sv'. Trying to do "service_iface.OpenSession('plain', '')" results in the following exception:

Traceback (most recent call last):
  File "dbus-test.py", line 8, in <module>
    service_iface.OpenSession('plain', '')
  File "/usr/lib/python3/dist-packages/dbus/proxies.py", line 70, in __call__
    return self._proxy_method(*args, **keywords)
  File "/usr/lib/python3/dist-packages/dbus/proxies.py", line 145, in __call__
    **keywords)
  File "/usr/lib/python3/dist-packages/dbus/connection.py", line 651, in call_blocking
    message, timeout)
dbus.exceptions.DBusException: org.freedesktop.DBus.Error.UnknownMethod: Method "OpenSession" with signature "ss" on interface "org.freedesktop.Secret.Service" doesn't exist

The same code was working about two weeks ago, so this is probably a regression since 1.0 (however, I can't reproduce it now with dbus-python 1.0, which I had installed at that time).
Comment 1 Dmitry Shachnev 2012-05-26 08:05:19 UTC
It seems that things are even worse: I can't pass an argument of dbus.ObjectPath type to functions that expect it (like org.freedesktop.Secret.Serice::Unlock which has signature "as"): it is automatically converted to string, and then not converted back.
Comment 2 Dmitry Shachnev 2012-05-26 08:13:12 UTC
Sorry, in comment #1 I meant:

… which has signature "ao" on input …
Comment 3 Simon McVittie 2012-05-29 04:11:09 UTC
(In reply to comment #0)
> The same code was working about two weeks ago, so this is probably a regression
> since 1.0 (however, I can't reproduce it now with dbus-python 1.0, which I had
> installed at that time).

I don't think anything has changed in that area since 1.0 (and not much has changed since 0.8x, in fact). Could the regression have been caused by a newer Secret.Service implementation?

If you do this:

service_obj = bus.get_object('org.freedesktop.secrets',
'/org/freedesktop/secrets')
introspectable = dbus.Interface(service_obj, 'org.freedesktop.DBus.Introspectable')
print introspectable.Introspect()

what do you get? You should get some XML describing the methods (the "introspection" mentioned in the documentation you quoted).

Alternatively, the introspection parsing might not be working correctly under Python 3 (using dbus-python under Python 3 is still rather experimental).

I consider this reliance on introspection to be a design flaw in dbus-python, but unfortunately, removing it would be a compatibility break. You can force a particular signature (ignoring introspection) with something like:

service_iface.OpenSession('plain', '', signature='sv')

or by wrapping arguments in dbus.String, dbus.ObjectPath and so on.

Alternatively, you could use GDBus via gobject-introspection. GDBus also uses explicit signatures, similar to dbus-python's signature='x'.

I recommend using the signature='x' form where possible - if you don't know what the signature is meant to be, your code isn't going to work reliably anyway.
Comment 4 Dmitry Shachnev 2012-05-29 06:01:40 UTC
> I don't think anything has changed in that area since 1.0 (and not much has
> changed since 0.8x, in fact). Could the regression have been caused by a newer
> Secret.Service implementation?

You are right, that's probably caused by gnome-keyring 3.2 -> 3.4 upgrade.

> If you do this:

> service_obj = bus.get_object('org.freedesktop.secrets',
> '/org/freedesktop/secrets')
> introspectable = dbus.Interface(service_obj,
> 'org.freedesktop.DBus.Introspectable')
> print introspectable.Introspect()

> what do you get? You should get some XML describing the methods (the
> "introspection" mentioned in the documentation you quoted).

http://paste.debian.net/171732/

Very strange, it lists only org.freedesktop.Secret.Collection methods (there should be 5 interfaces, see [1]).

[1]: http://standards.freedesktop.org/secret-service/ch13.html

> Alternatively, the introspection parsing might not be working correctly under
> Python 3 (using dbus-python under Python 3 is still rather experimental).

The same happens with Python 2.7.
Comment 5 Dmitry Shachnev 2012-05-29 06:16:03 UTC
> I recommend using the signature='x' form where possible - if you don't know
> what the signature is meant to be, your code isn't going to work reliably
> anyway.

Thanks, that helped me!
Comment 6 Simon McVittie 2012-05-30 04:32:11 UTC
(In reply to comment #4)
> You are right, that's probably caused by gnome-keyring 3.2 -> 3.4 upgrade.
...
> Very strange, it lists only org.freedesktop.Secret.Collection methods (there
> should be 5 interfaces, see [1]).

Closing, then (there's nothing dbus-python can do about this, unless you provide extra information like signature=... to disambiguate).


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.