Exemplo n.º 1
0
    def test_find_value_choice(self):
        c = make_dataclass("C", fields=[])
        d = make_dataclass("D", fields=[], bases=(c, ))

        var = XmlVar(
            elements=True,
            name="compound",
            qname="compound",
            choices=[
                XmlVar(element=True, qname="a", name="a", types=[int]),
                XmlVar(element=True,
                       qname="b",
                       name="b",
                       types=[int],
                       tokens=True),
                XmlVar(element=True,
                       qname="c",
                       name="c",
                       types=[c],
                       dataclass=True),
                XmlVar(element=True,
                       qname="d",
                       name="d",
                       types=[float],
                       nillable=True),
            ],
        )

        self.assertIsNone(var.find_value_choice("foo"))
        self.assertEqual(var.choices[0], var.find_value_choice(1))
        self.assertEqual(var.choices[1], var.find_value_choice([1, 2]))
        self.assertEqual(var.choices[2], var.find_value_choice(d()))
        self.assertEqual(var.choices[2], var.find_value_choice(c()))
        self.assertEqual(var.choices[3], var.find_value_choice(None))
Exemplo n.º 2
0
    def write_choice(self, value: Any, var: XmlVar,
                     namespace: NoneStr) -> Generator:
        """
        Produce an events stream for the given value of a compound elements
        field.

        The value can be anything as long as we can match the qualified
        name or its type to a choice.
        """
        if isinstance(value, DerivedElement):
            choice = var.find_choice(value.qname)
            value = value.value
            func = self.write_xsi_type if is_dataclass(
                value) else self.write_element
        elif isinstance(value, AnyElement) and value.qname:
            choice = var.find_choice(value.qname)
            func = self.write_any_type
        else:
            choice = var.find_value_choice(value)
            func = self.write_value

        if not choice:
            raise SerializerError(
                f"XmlElements undefined choice: `{var.name}` for `{type(value)}`"
            )

        yield from func(value, choice, namespace)
Exemplo n.º 3
0
    def bind_choice_simple(self, value: Any, var: XmlVar) -> Any:
        """Bind data to one of the simple choice types and return the first
        that succeeds."""
        choice = var.find_value_choice(value)
        if choice:
            return self.bind_value(choice, value)

        # Sometimes exact type match doesn't work, eg Decimals, try all of them
        is_list = isinstance(value, list)
        for choice in var.choices:
            if choice.dataclass or choice.tokens != is_list:
                continue

            with warnings.catch_warnings(record=True) as w:
                result = self.bind_value(choice, value)
                if not w:
                    return result

        return value