def _create_dict(self, format, args): """Handle the case where the outermost type of format is a dict.""" builder = None if args is None or not args[0]: # empty value: we need to call _create() to parse the subtype, # and specify the element type precisely rest_format = self._create(format[2:], None)[1] rest_format = self._create(rest_format, None)[1] if not rest_format.startswith('}'): raise TypeError('dictionary type string not closed with }') rest_format = rest_format[1:] # eat the } element_type = format[:len(format) - len(rest_format)] builder = GLib.VariantBuilder.new( variant_type_from_string(element_type)) else: builder = GLib.VariantBuilder.new( variant_type_from_string('a{?*}')) for k, v in args[0].items(): (key_v, rest_format, _) = self._create(format[2:], [k]) (val_v, rest_format, _) = self._create(rest_format, [v]) if not rest_format.startswith('}'): raise TypeError('dictionary type string not closed with }') rest_format = rest_format[1:] # eat the } entry = GLib.VariantBuilder.new( variant_type_from_string('{?*}')) entry.add_value(key_v) entry.add_value(val_v) builder.add_value(entry.end()) if args is not None: args = args[1:] return (builder.end(), rest_format, args)
def __getitem__(self, key): # dict if self.get_type_string().startswith('a{'): try: val = self.lookup_value(key, variant_type_from_string('*')) if val is None: raise KeyError(key) return val.unpack() except TypeError: # lookup_value() only works for string keys, which is certainly # the common case; we have to do painful iteration for other # key types for i in range(self.n_children()): v = self.get_child_value(i) if v.get_child_value(0).unpack() == key: return v.get_child_value(1).unpack() raise KeyError(key) # array/tuple if self.get_type_string().startswith( 'a') or self.get_type_string().startswith('('): key = int(key) if key < 0: key = self.n_children() + key if key < 0 or key >= self.n_children(): raise IndexError('list index out of range') return self.get_child_value(key).unpack() # string if self.get_type_string() in ['s', 'o', 'g']: return self.get_string().__getitem__(key) raise TypeError('GVariant type %s is not a container' % self.get_type_string())
def _create_tuple(self, format, args): """Handle the case where the outermost type of format is a tuple.""" format = format[1:] # eat the '(' if args is None: # empty value: we need to call _create() to parse the subtype rest_format = format while rest_format: if rest_format.startswith(')'): break rest_format = self._create(rest_format, None)[1] else: raise TypeError('tuple type string not closed with )') rest_format = rest_format[1:] # eat the ) return (None, rest_format, None) else: if not args or not isinstance(args[0], tuple): raise TypeError('expected tuple argument') builder = GLib.VariantBuilder.new(variant_type_from_string('r')) for i in range(len(args[0])): if format.startswith(')'): raise TypeError('too many arguments for tuple signature') (v, format, _) = self._create(format, args[0][i:]) builder.add_value(v) args = args[1:] if not format.startswith(')'): raise TypeError('tuple type string not closed with )') rest_format = format[1:] # eat the ) return (builder.end(), rest_format, args)
def _create_array(self, format, args): """Handle the case where the outermost type of format is an array.""" builder = None if args is None or not args[0]: # empty value: we need to call _create() to parse the subtype, # and specify the element type precisely rest_format = self._create(format[1:], None)[1] element_type = format[:len(format) - len(rest_format)] builder = GLib.VariantBuilder.new( variant_type_from_string(element_type)) else: builder = GLib.VariantBuilder.new(variant_type_from_string('a*')) for i in range(len(args[0])): (v, rest_format, _) = self._create(format[1:], args[0][i:]) builder.add_value(v) if args is not None: args = args[1:] return (builder.end(), rest_format, args)