From e5cef62c8ed04f5842257653bc6ec70abbdd20bb Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Tue, 9 Jan 2007 15:27:02 +0000 Subject: [PATCH] dbus.Interface, dbus.ProxyObject: add get_dbus_method(), which can be used to call awkwardly-named methods like __getattr__ --- dbus/_dbus.py | 26 ++++++++++++++++++++++++++ dbus/proxies.py | 47 ++++++++++++++++++++++++++++++++++++----------- test/test-client.py | 4 ++++ 3 files changed, 66 insertions(+), 11 deletions(-) diff --git a/dbus/_dbus.py b/dbus/_dbus.py index 5290b17..69f12a2 100644 --- a/dbus/_dbus.py +++ b/dbus/_dbus.py @@ -813,6 +813,32 @@ class Interface: ret = self._obj.__getattr__(member, dbus_interface=_dbus_interface) return ret + def get_dbus_method(self, member, dbus_interface=None): + """Return a proxy method representing the given D-Bus method. The + returned proxy method can be called in the usual way. For instance, :: + + iface.get_dbus_method("Foo")(123) + + is equivalent to:: + + iface.Foo(123) + + or even:: + + getattr(iface, "Foo")(123) + + However, using `get_dbus_method` is the only way to call D-Bus + methods with certain awkward names - if the author of a service + implements a method called ``connect_to_signal`` or even + ``__getattr__``, you'll need to use `get_dbus_method` to call them. + + For services which follow the D-Bus convention of CamelCaseMethodNames + this won't be a problem. + """ + if dbus_interface is None: + dbus_interface = self._dbus_interface + return self._obj.get_dbus_method(member, dbus_interface=dbus_interface) + def __repr__(self): return ''%( self._obj, self._dbus_interface, id(self)) diff --git a/dbus/proxies.py b/dbus/proxies.py index 7094006..ba774af 100644 --- a/dbus/proxies.py +++ b/dbus/proxies.py @@ -309,8 +309,8 @@ class ProxyObject: call_object = self.ProxyMethodClass(self._bus.get_connection(), self._named_service, - self._object_path, - iface, + self._object_path, + iface, member, introspect_sig) @@ -337,15 +337,40 @@ class ProxyObject: elif member.startswith('__') and member.endswith('__'): raise AttributeError(member) else: - ret = self.ProxyMethodClass(self, self._bus.get_connection(), - self._named_service, - self._object_path, member, - dbus_interface) - - if self._introspect_state == self.INTROSPECT_STATE_INTROSPECT_IN_PROGRESS: - ret = self.DeferedMethodClass(ret) - - return ret + return self.get_dbus_method(member, dbus_interface) + + def get_dbus_method(self, member, dbus_interface=None): + """Return a proxy method representing the given D-Bus method. The + returned proxy method can be called in the usual way. For instance, :: + + proxy.get_dbus_method("Foo", dbus_interface='com.example.Bar')(123) + + is equivalent to:: + + proxy.Foo(123, dbus_interface='com.example.Bar') + + or even:: + + getattr(proxy, "Foo")(123, dbus_interface='com.example.Bar') + + However, using `get_dbus_method` is the only way to call D-Bus + methods with certain awkward names - if the author of a service + implements a method called ``connect_to_signal`` or even + ``__getattr__``, you'll need to use `get_dbus_method` to call them. + + For services which follow the D-Bus convention of CamelCaseMethodNames + this won't be a problem. + """ + + ret = self.ProxyMethodClass(self, self._bus.get_connection(), + self._named_service, + self._object_path, member, + dbus_interface) + + if self._introspect_state == self.INTROSPECT_STATE_INTROSPECT_IN_PROGRESS: + ret = self.DeferedMethodClass(ret) + + return ret def __repr__(self): return ''%( diff --git a/test/test-client.py b/test/test-client.py index 5471b6b..8c4c3e2 100755 --- a/test/test-client.py +++ b/test/test-client.py @@ -83,6 +83,10 @@ class TestDBusBindings(unittest.TestCase): print self.iface.Echo("dbus_interface on Interface test Passed", dbus_interface = "org.freedesktop.DBus.TestSuiteInterface") self.assert_(True) + def testGetDBusMethod(self): + self.assertEquals(self.iface.get_dbus_method('AcceptListOfByte')('\1\2\3'), [1,2,3]) + self.assertEquals(self.remote_object.get_dbus_method('AcceptListOfByte', dbus_interface='org.freedesktop.DBus.TestSuiteInterface')('\1\2\3'), [1,2,3]) + def testCallingConventionOptions(self): self.assertEquals(self.iface.AcceptListOfByte('\1\2\3'), [1,2,3]) self.assertEquals(self.iface.AcceptListOfByte('\1\2\3', byte_arrays=True), '\1\2\3') -- 2.11.4.GIT