[pygobject/pygobject-2-28] [gi] Do not require signature for D-BUS methods without arguments



commit 115c4750f071270b648218c9678931a65a4b3e3d
Author: Martin Pitt <martin pitt ubuntu com>
Date:   Tue Mar 15 10:22:39 2011 +0100

    [gi] Do not require signature for D-BUS methods without arguments
    
    Calling methods on DBusProxy objects usually requires specifying the signature
    as first argument. However, if the D-BUS method does not take any arguments,
    specifying the empty '()' signature does not give any additional information,
    so allow the caller to just call the proxy method without any arguments.
    
    Also ensure that passing a non-string signature raises a comprehensible
    exception, instead of crashing deep in the GVariant leaf constructor.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=644260

 gi/overrides/Gio.py |   16 +++++++++++++++-
 tests/test_gdbus.py |   13 +++++++++++++
 2 files changed, 28 insertions(+), 1 deletions(-)
---
diff --git a/gi/overrides/Gio.py b/gi/overrides/Gio.py
index aa37784..20adf0c 100644
--- a/gi/overrides/Gio.py
+++ b/gi/overrides/Gio.py
@@ -122,7 +122,17 @@ class _DBusProxyMethodCall:
 
         result_callback(obj, self._unpack_result(ret), real_user_data)
 
-    def __call__(self, signature, *args, **kwargs):
+    def __call__(self, *args, **kwargs):
+        # the first positional argument is the signature, unless we are calling
+        # a method without arguments; then signature is implied to be '()'.
+        if args:
+            signature = args[0]
+            args = args[1:]
+            if not isinstance(signature, str):
+                raise TypeError('first argument must be the method signature string: %r' % signature)
+        else:
+            signature = '()'
+
         arg_variant = GLib.Variant(signature, tuple(args))
 
         if 'result_handler' in kwargs:
@@ -166,6 +176,10 @@ class DBusProxy(Gio.DBusProxy):
       proxy = Gio.DBusProxy.new_sync(...)
       result = proxy.MyMethod('(is)', 42, 'hello')
 
+    The exception are methods which take no arguments, like
+    proxy.MyMethod('()'). For these you can omit the signature and just write
+    proxy.MyMethod().
+
     Optional keyword arguments:
 
     - timeout: timeout for the call in milliseconds (default to D-Bus timeout)
diff --git a/tests/test_gdbus.py b/tests/test_gdbus.py
index b40492c..a9442fe 100644
--- a/tests/test_gdbus.py
+++ b/tests/test_gdbus.py
@@ -142,6 +142,13 @@ class TestGDBusClient(unittest.TestCase):
 
             self.assertTrue('Timeout' in str(e), str(e))
 
+    def test_python_calls_sync_noargs(self):
+        # methods without arguments don't need an explicit signature
+        result = self.dbus_proxy.ListNames()
+        self.assertTrue(isinstance(result, list))
+        self.assertTrue(len(result) > 1)
+        self.assertTrue('org.freedesktop.DBus' in result)
+
     def test_python_calls_sync_errors(self):
         # error case: invalid argument types
         try:
@@ -152,6 +159,12 @@ class TestGDBusClient(unittest.TestCase):
 
             self.assertTrue('InvalidArgs' in str(e), str(e))
 
+        try:
+            self.dbus_proxy.GetConnectionUnixProcessID(None, 'foo')
+            self.fail('call with None signature should raise an exception')
+        except TypeError as e:
+            self.assertTrue('signature' in str(e), str(e))
+
     def test_python_calls_async(self):
         def call_done(obj, result, user_data):
             user_data['result'] = result



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]