Example #1
0
    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)
Example #2
0
    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())
Example #3
0
    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)
Example #4
0
    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)