6 if isinstance(o
, dbus
.proxies
.ProxyObject
):
11 class DBusMio(dbus
.proxies
.ProxyObject
):
12 """Multi-interface object
14 BUGS: 1st method call will block with introspection"""
16 def __init__(self
, conn
=None, bus_name
=None, object_path
=None, introspect
=True, follow_name_owner_changes
=False, **kwargs
):
17 # FIXME common for this class, all classes?
18 self
.__default
_interface
= kwargs
.pop("default_interface", None)
19 super(DBusMio
, self
).__init
__(conn
, bus_name
, object_path
, introspect
, follow_name_owner_changes
, **kwargs
)
21 def __getattr__(self
, name
):
23 # iface = self._interface_cache.get(name)
25 iface
= self
.__default
_interface
26 # _introspect_method_map comes from ProxyObject
27 # But it will be empty until the async introspection finishes
28 self
._introspect
_block
() # FIXME makeit work with async methods
29 methods
= self
._introspect
_method
_map
.keys()
31 (i
, m
) = im
.rsplit(".", 1)
34 # print "METHOD %s INTERFACE %s" %(name, iface)
35 callable = super(DBusMio
, self
).__getattr
__(name
)
36 return functools
.partial(callable, dbus_interface
=iface
)
39 def __getitem__(self
, key
):
40 iface
= self
.__default
_interface
# TODO cache
41 # TODO _introspect_property_map
42 pmi
= dbus
.Interface(self
, "org.freedesktop.DBus.Properties")
43 return pmi
.Get(iface
, key
)
45 def __setitem__(self
, key
, value
):
46 iface
= self
.__default
_interface
# TODO cache
47 # TODO _introspect_property_map
48 pmi
= dbus
.Interface(self
, "org.freedesktop.DBus.Properties")
49 return pmi
.Set(iface
, key
, value
)
52 if isinstance(x
, list):
54 elif isinstance(x
, tuple):
59 #class DBusClient(dbus.proxies.Interface):
60 class DBusClient(DBusMio
):
69 def _get_adaptor(cls
, kind
, name
):
70 # print "GET", cls, kind, name
72 return cls
._adaptors
[kind
][name
]
74 scls
= cls
.__mro
__[1] # can use "super"? how?
76 return scls
._get
_adaptor
(kind
, name
)
77 except AttributeError: # no _get_adaptor there
78 raise KeyError(":".join((kind
, name
)))
81 def _add_adaptor(cls
, kind
, name
, adaptor
):
82 # print "ADD", cls, kind, name, adaptor
83 adaptor
= mklist(adaptor
)
93 cls
._adaptors
[kind
][name
] = [adaptor
[0], args
, kwargs
]
97 def _add_adaptors(cls
, *args
, **kwargs
):
101 if not cls
.__dict
__.has_key("_adaptors"):
102 # do not use inherited attribute
103 cls
._adaptors
= {"methods":{}, "properties":{}, "signals":{}}
105 assert len(kwargs
) == 0
106 assert len(args
) == 1
109 for section
in cls
._adaptors
.keys():
110 secsource
= kwargs
.pop(section
, {})
111 for name
, adaptor
in secsource
.iteritems():
112 cls
._add
_adaptor
(section
, name
, adaptor
)
113 assert len(kwargs
) == 0
114 # print "AA", cls, cls._adaptors
116 def __getattr__(self
, name
):
119 callable = super(DBusClient
, self
).__getattr
__(name
)
121 adaptor
= self
._get
_adaptor
("methods", name
)
122 return callable_universal_adaptor(callable, adaptor
)
127 def __getitem__(self
, key
):
128 value
= super(DBusClient
, self
).__getitem
__(key
)
130 adaptor
= self
._get
_adaptor
("properties", key
)[0]
131 except KeyError, IndexError:
133 return adaptor(value
)
135 def __setitem__(self
, key
, value
):
137 adaptor
= self
._get
_adaptor
("properties", key
)[1][0]
138 except KeyError, IndexError:
140 value
= adaptor(value
)
141 return super(DBusClient
, self
).__setitem
__(key
, value
)
145 # overrides a ProxyObject method
146 def _connect_to_signal(self
, signame
, handler
, interface
=None, **kwargs
):
147 "Wrap signal handler, with arg adaptors"
149 # TODO also demarshal kwargs
150 adaptor
= self
._get
_adaptor
("signals", signame
)
151 wrap_handler
= callable_universal_adaptor(handler
, adaptor
)
152 return self
.connect_to_signal(signame
, wrap_handler
, interface
, **kwargs
)
154 #class ObjectAddress:
155 # """An object path, optionally with a service/connection where to find it"""