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



commit 029a79d1af1e0998aa6bc88ce1c1f48ce0ccd2a0
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 20343a2..2a6594d 100644
--- a/gi/overrides/Gio.py
+++ b/gi/overrides/Gio.py
@@ -119,7 +119,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:
@@ -163,6 +173,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 ade62d1..19fd76d 100644
--- a/tests/test_gdbus.py
+++ b/tests/test_gdbus.py
@@ -131,6 +131,13 @@ class TestGDBusClient(unittest.TestCase):
         except Exception as e:
             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:
@@ -139,6 +146,12 @@ class TestGDBusClient(unittest.TestCase):
         except Exception as e:
             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]