Bug 50740 - py3dbus is downcasting the ObjectPaths to signature 's' when the server is advertising 'o'
Summary: py3dbus is downcasting the ObjectPaths to signature 's' when the server is ad...
Status: RESOLVED FIXED
Alias: None
Product: dbus
Classification: Unclassified
Component: python (show other bugs)
Version: unspecified
Hardware: Other Linux (All)
: high major
Assignee: Simon McVittie
QA Contact: John (J5) Palmieri
URL: https://bugs.launchpad.net/ubuntu/+so...
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-06-05 09:50 UTC by Fabio Marconi
Modified: 2012-06-05 11:14 UTC (History)
1 user (show)

See Also:
i915 platform:
i915 features:


Attachments
Py3: correctly guess the signature of ObjectPath(...) and Signature(...) (2.94 KB, patch)
2012-06-05 11:14 UTC, Simon McVittie
Details | Splinter Review

Description Fabio Marconi 2012-06-05 09:50:56 UTC
TEST CASE
1. Start an installation with Ubiquity on Hardware, without wired connection and with a Wifi Card
2. Proceed to Wireless setup page
3. Select a network
4. Enter password
5. Click on 'Connect'

ACTUAL RESULT:
Crash below

WORKAROUND:
Setup the Wifi connection from network-manager before starting Ubiquity

Jun 5 07:59:45 ubuntu ubiquity[3109]: Step_before = stepPrepare
Jun 5 07:59:45 ubuntu ubiquity[3109]: switched to page wireless
Jun 5 08:00:19 ubuntu ubiquity[3109]: Exception in GTK frontend (invoking crash handler):
Jun 5 08:00:19 ubuntu ubiquity[3109]: Traceback (most recent call last):
Jun 5 08:00:19 ubuntu ubiquity[3109]: File "/usr/lib/ubiquity/ubiquity/frontend/gtk_ui.py", line 1328, in on_next_clicked
Jun 5 08:00:19 ubuntu ubiquity[3109]: if ui.plugin_on_next_clicked():
Jun 5 08:00:19 ubuntu ubiquity[3109]: File "/usr/lib/ubiquity/plugins/ubi-wireless.py", line 134, in plugin_on_next_clicked
Jun 5 08:00:19 ubuntu ubiquity[3109]: self.nmwidget.connect_to_ap()
Jun 5 08:00:19 ubuntu ubiquity[3109]: File "/usr/lib/ubiquity/ubiquity/nm.py", line 443, in connect_to_ap
Jun 5 08:00:19 ubuntu ubiquity[3109]: self.view.connect_to_selection(passphrase)
Jun 5 08:00:19 ubuntu ubiquity[3109]: File "/usr/lib/ubiquity/ubiquity/nm.py", line 384, in connect_to_selection
Jun 5 08:00:19 ubuntu ubiquity[3109]: self.wifi_model.connect_to_ap(model[parent][0], ssid, passphrase)
Jun 5 08:00:19 ubuntu ubiquity[3109]: File "/usr/lib/ubiquity/ubiquity/nm.py", line 126, in connect_to_ap
Jun 5 08:00:19 ubuntu ubiquity[3109]: obj, dbus.ObjectPath(device), dbus.ObjectPath(saved_path))[1]
Jun 5 08:00:19 ubuntu ubiquity[3109]: File "/usr/lib/python3/dist-packages/dbus/proxies.py", line 145, in __call__
Jun 5 08:00:19 ubuntu ubiquity[3109]: **keywords)
Jun 5 08:00:19 ubuntu ubiquity[3109]: File "/usr/lib/python3/dist-packages/dbus/connection.py", line 651, in call_blocking
Jun 5 08:00:19 ubuntu ubiquity[3109]: message, timeout)
Jun 5 08:00:19 ubuntu ubiquity[3109]: dbus.exceptions.DBusException: org.freedesktop.DBus.Error.UnknownMethod: Method "AddAndActivateConnection" with signature "a{sa{sv}}ss" on interface "(null)" doesn't exist
Jun 5 08:00:19 ubuntu ubiquity[3109]:
Jun 5 08:00:19 ubuntu ubiquity[3109]:
Jun 5 08:00:20 ubuntu ubiquity[3109]: log-output -t ubiquity /usr/share/apport/apport-gtk
Comment 1 Fabio Marconi 2012-06-05 09:52:03 UTC
Original report on Launchpad:
https://bugs.launchpad.net/ubuntu/+source/ubiquity/+bug/1008898
Comment 2 Stéphane Graber 2012-06-05 10:25:28 UTC
To try and give a bit more background on what's going on here.

We have a piece of python called nm.py in the Ubuntu Installer that talks over DBUS to Network Manager.

That piece of code was designed to work with both python2 and python3, however we noticed that it completely fails on python3 because of invalid signature.

The script can be found at: http://paste.ubuntu.com/1025375/
The workaround we applied is: http://paste.ubuntu.com/1025377/

Basically, with python2, the following:
self.manager.AddAndActivateConnection(obj, dbus.ObjectPath(device), dbus.ObjectPath(saved_path))

Would match the service signature of "a{sa{sv}}oo".

But the same code running with python3 doesn't as the objects appear to get downcasted to strings, before checking for the existing signatures.

This obviously makes the program crash as "a{sa{sv}}ss" (python3) != "a{sa{sv}}oo" (service).
Comment 3 Simon McVittie 2012-06-05 10:55:07 UTC
(In reply to comment #0)
> Jun 5 08:00:19 ubuntu ubiquity[3109]: dbus.exceptions.DBusException:
> org.freedesktop.DBus.Error.UnknownMethod: Method "AddAndActivateConnection"
> with signature "a{sa{sv}}ss" on interface "(null)" doesn't exist

For D-Bus calls to be reliable, you should specify an interface (use dbus_interface=... in the call, or call the method via a dbus.Interface wrapper). I don't know whether that's what causes this signature mismatch or not, though; it's just best-practice.

When you introspect the object represented by self.manager, what do you get? (To find out, run "gdbus introspect --system -d org.freedesktop.NetworkManager -o /org/freedesktop/NetworkManager -x", assuming self.manager represents the /org/freedesktop/NetworkManager object on org.freedesktop.NetworkManager on the system bus.) I get this, among other things:

...
    <method name="AddAndActivateConnection">
      <arg name="connection" type="a{sa{sv}}" direction="in"/>
      <arg name="device" type="o" direction="in"/>
      <arg name="specific_object" type="o" direction="in"/>
      <arg name="path" type="o" direction="out"/>
      <arg name="active_connection" type="o" direction="out"/>
    </method>
...
Comment 4 Simon McVittie 2012-06-05 11:13:35 UTC
OK, so this is actually a combination of two things.

(In reply to comment #3)
> For D-Bus calls to be reliable, you should specify an interface (use
> dbus_interface=... in the call, or call the method via a dbus.Interface
> wrapper).

Because you didn't do this, dbus-python couldn't correlate the signature of the method with the signature in the Introspect() result, and had to guess what you meant. Normally that'd be OK, because you used ObjectPath as a hint that you thought the service would expect object paths.

However, the signature-guessing function in dbus-python was broken for ObjectPath and Signature objects under Python 3, because those objects have changed from a subtype of the old meaning of str (= bytes) in Python 2, to a subtype of the new meaning of str (= unicode) in Python 3. I've fixed that in git, I'll attach a patch here.

The precedence is:

* using dbus.SomeType (lowest)
* Introspect() result
* signature="..." (highest)

If dbus-python wasn't constrained by backwards-compatibility, the signature would be required (like it is in GDBus), but unfortunately that's not really an option.
Comment 5 Simon McVittie 2012-06-05 11:14:10 UTC
Created attachment 62596 [details] [review]
Py3: correctly guess the signature of ObjectPath(...) and  Signature(...)

Under Python 2, ObjectPath and Signature are subtypes of str (= bytes),
and the existing type-guessing worked.

The type-guessing code assumed that all unicode objects were just
strings, but that assumption became false in the Python 3 port:
ObjectPath and Signature are still subtypes of str, but str now means
unicode, not bytes.

Bug: https://bugs.freedesktop.org/show_bug.cgi?id=50740


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.