def build(self) -> str: val = "<node>\n <interface name='%s'>\n" % self._interface_name for name, sig in self._ro_props.items(): val += " <property name='%s' type='%s' access='read' />\n" % \ (snake_to_camel(name), sig) for name, sig in self._rw_props.items(): val += " <property name='%s' type='%s' access='readwrite'>\n" % \ (snake_to_camel(name), sig) val += " <annotation name='org.freedesktop.DBus.Property.EmitsChangedSignal' value='true' />\n" val += " </property>\n" for method in self._methods: name = snake_to_camel(method['name']) if not 'args' in method: val += " <method name='%s' />\n" % name else: val += " <method name='%s'>\n" % name for argspec in method['args']: val += " <arg direction='%s' type='%s' name='%s' />\n" % \ (argspec.direction, argspec.type, argspec.name) val += " </method>\n" for signal in self._signals: name = snake_to_camel(signal['name']) if not 'args' in signal: val += " <signal name='%s' />\n" % name else: val += " <signal name='%s'>\n" % name for argspec in signal['args']: val += " <arg direction='%s' type='%s' name='%s' />\n" % \ (argspec.direction, argspec.type, argspec.name) val += " </signal>\n" val += " </interface>\n</node>" return val
def _parse_traits(self): for name, trait in self._obj.traits().items(): if self._exclude is not None and name in self._exclude: continue sig = None if hasattr(self._obj, name): sig = dbus_prepare(getattr(self._obj, name))[1] write_once = False if hasattr(trait, 'write_once'): write_once = trait.write_once self.add_property(snake_to_camel(name), sig, not (trait.read_only or write_once))
def _get_descriptor(self): exclude = ('blend_mode', 'opacity') if self._delegate.zindex > 0: exclude = ('background_color',) builder = DescriptorBuilder(self._delegate, 'org.chemlab.UChroma.Layer', exclude) for k, v in self._delegate.meta._asdict().items(): attrib = snake_to_camel(k) setattr(self, attrib, v) builder.add_property(attrib, 's') setattr(self, 'Key', '%s.%s' % (self._delegate.__module__, self._delegate.__class__.__name__)) builder.add_property('Key', 's') return builder.build()
def dbus_prepare(obj, variant: bool = False, camel_keys: bool = False) -> tuple: """ Recursively walks obj and builds a D-Bus signature by inspecting types. Variant types are created as necessary, and the returned obj may have changed. :param obj: An arbitrary primitive or container type :param variant: Force wrapping contained objects with variants :param camel_keys: Convert dict keys to CamelCase """ sig = '' use_variant = variant try: if isinstance(obj, Variant): sig = 'v' elif isinstance(obj, bool): sig = 'b' elif isinstance(obj, str): sig = 's' elif isinstance(obj, int): if obj < pow(2, 16): sig = 'n' elif obj < pow(2, 32): sig = 'i' else: sig = 'x' elif isinstance(obj, float): sig = 'd' elif isinstance(obj, Color): sig = 's' obj = obj.html elif isinstance(obj, TraitType): obj, sig = dbus_prepare(trait_as_dict(obj), variant=True) elif isinstance(obj, HasTraits): obj, sig = dbus_prepare(class_traits_as_dict(obj), variant=True) elif hasattr(obj, '_asdict') and hasattr(obj, '_field_types'): # typing.NamedTuple obj, sig = dbus_prepare(obj._asdict(), variant=True) elif isinstance(obj, type) and issubclass(obj, enum.Enum): # top level enum, tuple of string keys obj = tuple(obj.__members__.keys()) sig = '(%s)' % ('s' * len(obj)) elif isinstance(obj, enum.Enum): obj = obj.name sig = 's' elif isinstance(obj, np.ndarray): dtype = obj.dtype.kind if dtype == 'f': dtype = 'd' sig = 'a' * obj.ndim + dtype obj = obj.tolist() elif isinstance(obj, tuple): tmp = [] sig = '(' for item in obj: if item is None and use_variant: continue # struct of all items r_obj, r_sig = dbus_prepare(item) if r_obj is None: continue sig += r_sig tmp.append(r_obj) if len(tmp) > 0: sig += ')' obj = tuple(tmp) else: sig = '' obj = None elif isinstance(obj, list): tmp = [] sig = 'a' is_variant = use_variant or _check_variance(obj) for item in obj: if item is None and is_variant: continue r_obj, r_sig = dbus_prepare(item, variant=is_variant) if r_obj is None: continue tmp.append(r_obj) if is_variant: sig += 'v' else: sig += dbus_prepare(tmp[0])[1] obj = tmp elif isinstance(obj, (dict, frozendict)): if isinstance(obj, frozendict): tmp = {} else: tmp = obj.__class__() sig = 'a{s' vals = [x for x in obj.values() if x is not None] is_variant = use_variant or _check_variance(vals) for k, v in obj.items(): if v is None: continue r_obj, r_sig = dbus_prepare(v) if r_obj is None: continue if camel_keys: k = snake_to_camel(k) if is_variant: tmp[k] = Variant(r_sig, r_obj) else: tmp[k] = r_obj if is_variant: sig += 'v' else: sig += dbus_prepare(vals[0])[1] obj = tmp sig += '}' elif isinstance(obj, type): obj = obj.__name__ sig = 's' except Exception as err: logger.exception('obj: %s sig: %s variant: %s', obj, sig, variant, exc_info=err) raise return obj, sig