def test_create_substitutions(self, mock_create_substitution):
        ns = "xsdata"
        classes = [
            ClassFactory.create(
                substitutions=[build_qname(ns, "foo"),
                               build_qname(ns, "bar")],
                abstract=True,
            ),
            ClassFactory.create(substitutions=[build_qname(ns, "foo")],
                                abstract=True),
        ]

        reference_attrs = AttrFactory.list(3)
        mock_create_substitution.side_effect = reference_attrs

        self.processor.container.extend(classes)
        self.processor.create_substitutions()

        expected = {
            build_qname(ns, "foo"): [reference_attrs[0], reference_attrs[2]],
            build_qname(ns, "bar"): [reference_attrs[1]],
        }
        self.assertEqual(expected, self.processor.substitutions)

        mock_create_substitution.assert_has_calls([
            mock.call(classes[0]),
            mock.call(classes[0]),
            mock.call(classes[1])
        ])
Exemple #2
0
    def build(self, clazz: Type, parent_ns: Optional[str] = None) -> XmlMeta:
        """
        Fetch from cache or build the binding metadata for the given class and
        parent namespace.

        :param clazz: A dataclass type
        :param parent_ns: The inherited parent namespace
        """

        if clazz not in self.cache:

            # Ensure the given type is a dataclass.
            if not is_dataclass(clazz):
                raise XmlContextError(f"Object {clazz} is not a dataclass.")

            # Fetch the dataclass meta settings and make sure we don't inherit
            # the parent class meta.
            meta = clazz.Meta if "Meta" in clazz.__dict__ else None
            name = getattr(meta, "name", None) or self.local_name(
                clazz.__name__)
            nillable = getattr(meta, "nillable", False)
            namespace = getattr(meta, "namespace", parent_ns)
            module = sys.modules[clazz.__module__]
            source_namespace = getattr(module, "__NAMESPACE__", None)

            self.cache[clazz] = XmlMeta(
                clazz=clazz,
                qname=build_qname(namespace, name),
                source_qname=build_qname(source_namespace, name),
                nillable=nillable,
                vars=list(self.get_type_hints(clazz, namespace)),
            )
        return self.cache[clazz]
    def test_build_parts_attributes(self, mock_warning):
        p_one = Part(element="a:bar")
        p_one.ns_map["a"] = "great"
        p_two = Part(name="arg0", type="xs:string")
        p_two.ns_map["xs"] = Namespace.XS.uri
        p_three = Part(name="arg1", type="b:cafe")
        p_three.ns_map["b"] = "boo"
        p_four = Part(name="arg2")

        ns_map = {}
        parts = [p_one, p_two, p_three, p_four]
        result = DefinitionsMapper.build_parts_attributes(parts, ns_map)
        expected = [
            DefinitionsMapper.build_attr("bar",
                                         build_qname("great", "bar"),
                                         namespace="great",
                                         native=False),
            DefinitionsMapper.build_attr("arg0",
                                         str(DataType.STRING),
                                         namespace="",
                                         native=True),
            DefinitionsMapper.build_attr("arg1",
                                         build_qname("boo", "cafe"),
                                         namespace="",
                                         native=False),
        ]
        self.assertIsInstance(result, Generator)
        self.assertEqual(expected, list(result))
        mock_warning.assert_called_once_with("Skip untyped message part %s",
                                             "arg2")
Exemple #4
0
    def test_build_with_meta_namespace(self, mock_get_type_hints):
        namespace = Product.Meta.namespace
        result = self.ctx.build(Product, None)

        self.assertEqual(build_qname(namespace, "product"), result.qname)
        self.assertEqual(build_qname(namespace, "product"),
                         result.source_qname)
        mock_get_type_hints.assert_called_once_with(Product, namespace)
Exemple #5
0
    def test_dependencies(self):
        obj = ClassFactory.create(
            attrs=[
                AttrFactory.create(
                    types=[AttrTypeFactory.native(DataType.DECIMAL)]),
                AttrFactory.create(
                    types=[
                        AttrTypeFactory.create(
                            qname=build_qname(Namespace.XS.uri, "annotated"),
                            forward=True,
                        )
                    ],
                    choices=[
                        AttrFactory.create(
                            name="x",
                            types=[
                                AttrTypeFactory.create(qname="choiceAttr"),
                                AttrTypeFactory.native(DataType.STRING),
                            ],
                        ),
                        AttrFactory.create(
                            name="x",
                            types=[
                                AttrTypeFactory.create(qname="choiceAttrTwo"),
                                AttrTypeFactory.create(qname="choiceAttrEnum"),
                            ],
                        ),
                    ],
                ),
                AttrFactory.create(types=[
                    AttrTypeFactory.create(
                        qname=build_qname(Namespace.XS.uri, "openAttrs")),
                    AttrTypeFactory.create(
                        qname=build_qname(Namespace.XS.uri, "localAttribute")),
                ]),
            ],
            extensions=[
                ExtensionFactory.reference(
                    build_qname(Namespace.XS.uri, "foobar")),
                ExtensionFactory.reference(
                    build_qname(Namespace.XS.uri, "foobar")),
            ],
            inner=[
                ClassFactory.create(attrs=AttrFactory.list(
                    2, types=AttrTypeFactory.list(1, qname="{xsdata}foo")))
            ],
        )

        expected = [
            "choiceAttr",
            "choiceAttrTwo",
            "choiceAttrEnum",
            "{http://www.w3.org/2001/XMLSchema}openAttrs",
            "{http://www.w3.org/2001/XMLSchema}localAttribute",
            "{http://www.w3.org/2001/XMLSchema}foobar",
            "{xsdata}foo",
        ]
        self.assertCountEqual(expected, list(obj.dependencies()))
    def test_create_substitution(self):
        item = ClassFactory.elements(1, qname=build_qname("foo", "bar"))
        actual = self.processor.create_substitution(item)

        expected = AttrFactory.create(
            name=item.name,
            default=None,
            types=[AttrType(qname=build_qname("foo", "bar"))],
            tag=item.type.__name__,
        )

        self.assertEqual(expected, actual)
Exemple #7
0
    def copy_inner_class(cls, source: Class, target: Class, attr: Attr,
                         attr_type: AttrType):
        """
        Check if the given attr type is a forward reference and copy its inner
        class from the source to the target class.

        Checks:
            1. Update type if inner class in a circular reference
            2. Copy inner class, rename it if source is a simple type.
        """
        if not attr_type.forward:
            return

        # This will fail if no inner class is found, too strict???
        inner = ClassUtils.find_inner(source, attr_type.qname)

        if inner is target:
            attr_type.circular = True
        else:
            clone = inner.clone()
            clone.package = target.package
            clone.module = target.module

            # Simple type, update the name
            if clone.name == "@value":
                namespace, _ = split_qname(clone.qname)
                clone.qname = attr_type.qname = build_qname(
                    namespace, attr.name)

            target.inner.append(clone)
Exemple #8
0
    def build_inner_class(cls,
                          target: Class,
                          name: str,
                          namespace: Optional[str] = None) -> Class:
        """
        Build or retrieve an inner class for the given target class by the
        given name.

        This helper will also create a forward reference attribute for
        the parent class.
        """
        inner = first(inner for inner in target.inner if inner.name == name)
        if not inner:
            inner = Class(
                qname=build_qname(name),
                tag=Tag.BINDING_MESSAGE,
                module=target.module,
                ns_map=target.ns_map.copy(),
            )
            attr = cls.build_attr(name,
                                  inner.qname,
                                  forward=True,
                                  namespace=namespace)

            target.inner.append(inner)
            target.attrs.append(attr)

        return inner
Exemple #9
0
    def test_promote(self):
        target = ClassFactory.elements(2)
        inner = ClassFactory.enumeration(3)

        target.inner.append(inner)
        target.inner.append(ClassFactory.simple_type())  # Irrelevant
        attr_type = AttrTypeFactory.create(qname=inner.qname, forward=True)

        target.attrs[0].types.append(attr_type.clone())
        target.attrs[1].types.append(attr_type.clone())

        self.container.add(target)
        self.assertEqual(3, len(self.container.data))

        self.processor.process(target)

        new_qname = build_qname(inner.target_namespace,
                                f"{target.name}_{inner.name}")

        self.assertEqual(4, len(self.container.data))
        new_inner = self.container.find(new_qname)

        self.assertEqual(1, len(target.inner))
        self.assertNotEqual(new_inner.qname, inner.qname)
        self.assertEqual(new_inner.attrs, inner.attrs)
        self.assertEqual(new_inner.qname, target.attrs[0].types[1].qname)
        self.assertEqual(new_inner.qname, target.attrs[1].types[1].qname)
        self.assertFalse(target.attrs[0].types[1].forward)
        self.assertFalse(target.attrs[1].types[1].forward)
Exemple #10
0
    def test_build_with_parent_ns(self, mock_get_type_hints):
        result = self.ctx.build(ProductType, "http://xsdata")

        self.assertEqual(build_qname("http://xsdata", "ProductType"),
                         str(result.qname))
        mock_get_type_hints.assert_called_once_with(ProductType,
                                                    "http://xsdata")
Exemple #11
0
    def build_class(
        cls,
        obj: ElementBase,
        container: str,
        module: str,
        target_namespace: Optional[str],
    ) -> Class:
        """Build and return a class instance."""
        instance = Class(
            qname=build_qname(target_namespace, obj.real_name),
            abstract=obj.is_abstract,
            namespace=cls.element_namespace(obj, target_namespace),
            mixed=obj.is_mixed,
            nillable=obj.is_nillable,
            tag=obj.class_name,
            container=container,
            help=obj.display_help,
            ns_map=obj.ns_map,
            module=module,
            default=obj.default_value,
            fixed=obj.is_fixed,
            substitutions=cls.build_substitutions(obj, target_namespace),
        )

        cls.build_class_extensions(obj, instance)
        cls.build_class_attributes(obj, instance)
        return instance
Exemple #12
0
    def parse_any_attribute(cls, value: str, ns_map: Dict) -> str:
        """Attempt to parse any attribute."""
        prefix, suffix = text.split(value)
        if prefix and prefix in ns_map and not suffix.startswith("//"):
            value = build_qname(ns_map[prefix], suffix)

        return value
Exemple #13
0
    def build_parts_attributes(cls, parts: List[Part],
                               ns_map: Dict) -> Iterator[Attr]:
        """
        Build attributes for the given list of parts.

        :param parts: List of parts
        :param ns_map: Namespace prefix-URI map
        """
        for part in parts:
            if part.element:
                prefix, type_name = text.split(part.element)
                name = type_name
            elif part.type:
                prefix, type_name = text.split(part.type)
                name = part.name
            else:
                logger.warning("Skip untyped message part %s", part.name)
                continue

            ns_map.update(part.ns_map)
            namespace = part.ns_map.get(prefix)
            type_qname = build_qname(namespace, type_name)
            native = namespace == Namespace.XS.uri
            namespace = "" if part.type else namespace

            yield cls.build_attr(name,
                                 type_qname,
                                 namespace=namespace,
                                 native=native)
Exemple #14
0
    def test_apply_aliases(self):
        self.resolver.aliases = {
            build_qname("xsdata", "d"): "IamD",
            build_qname("xsdata", "a"): "IamA",
        }
        type_a = AttrTypeFactory.create(qname="{xsdata}a")
        type_b = AttrTypeFactory.create(qname="{xsdata}b")
        type_c = AttrTypeFactory.create(qname="{xsdata}c")
        type_d = AttrTypeFactory.create(qname="{xsdata}d")

        obj = ClassFactory.create(
            qname="a",
            attrs=[
                AttrFactory.create(name="a", types=[type_a]),
                AttrFactory.create(name="b", types=[type_b]),
                AttrFactory.create(name="c", types=[type_a, type_d]),
            ],
            inner=[
                ClassFactory.create(
                    qname="b",
                    attrs=[
                        AttrFactory.create(name="c", types=[type_c]),
                        AttrFactory.create(name="d", types=[type_d]),
                    ],
                )
            ],
        )

        self.resolver.apply_aliases(obj)

        self.assertEqual(3, len(obj.attrs))
        self.assertEqual(1, len(obj.attrs[0].types))
        self.assertEqual(1, len(obj.attrs[1].types))
        self.assertEqual(2, len(obj.attrs[2].types))

        self.assertEqual("IamA", obj.attrs[0].types[0].alias)
        self.assertIsNone(obj.attrs[1].types[0].alias)
        self.assertEqual("IamA", obj.attrs[2].types[0].alias)
        self.assertEqual("IamD", obj.attrs[2].types[1].alias)

        self.assertEqual(1, len(obj.inner))
        self.assertEqual(2, len(obj.inner[0].attrs))
        self.assertEqual(1, len(obj.inner[0].attrs[0].types))
        self.assertEqual(1, len(obj.inner[0].attrs[1].types))
        self.assertIsNone(obj.inner[0].attrs[0].types[0].alias)
        self.assertEqual("IamD", obj.inner[0].attrs[1].types[0].alias)
Exemple #15
0
 def map_port_type_message(cls, message: PortTypeMessage,
                           namespace: Optional[str]) -> Iterator[Attr]:
     """Build an attribute for the given port type message."""
     prefix, name = text.split(message.message)
     source_namespace = message.ns_map.get(prefix)
     yield cls.build_attr(name,
                          qname=build_qname(source_namespace, name),
                          namespace=namespace)
Exemple #16
0
    def xsi_type(cls, attrs: Dict, ns_map: Dict) -> Optional[str]:
        """Parse the xsi:type attribute if present."""
        xsi_type = attrs.get(QNames.XSI_TYPE)
        if not xsi_type:
            return None

        namespace, name = QNameConverter.resolve(xsi_type, ns_map)
        return build_qname(namespace, name)
Exemple #17
0
    def test_build_qname(self):
        self.assertEqual("{a}b", build_qname("a", "b"))
        self.assertEqual("b", build_qname("", "b"))
        self.assertEqual("b", build_qname(None, "b"))

        self.assertEqual("b", build_qname("b", ""))
        self.assertEqual("b", build_qname("b"))
        self.assertEqual("b", build_qname("b", None))

        with self.assertRaises(ValueError):
            build_qname(None, None)
Exemple #18
0
    def test_build_class(
        self,
        mock_real_name,
        mock_display_help,
        mock_is_nillable,
        mock_is_abstract,
        mock_substitutions,
        mock_build_class_extensions,
        mock_build_class_attributes,
        mock_element_namespace,
    ):
        mock_real_name.return_value = "name"
        mock_display_help.return_value = "sos"
        mock_is_abstract.return_value = True
        mock_is_nillable.return_value = True
        mock_substitutions.return_value = ["foo", "sm:bar"]
        mock_element_namespace.return_value = "foo:name"

        element = Element()
        element.ns_map["sm"] = "sm_ns"
        result = SchemaMapper.build_class(element, "container", "module",
                                          "target_ns")

        mock_build_class_attributes.assert_called_once_with(element, result)
        mock_build_class_extensions.assert_called_once_with(element, result)
        mock_element_namespace.assert_called_once_with(element, "target_ns")

        expected = ClassFactory.create(
            qname=build_qname("target_ns", "name"),
            type=Element,
            help="sos",
            abstract=True,
            nillable=True,
            namespace="foo:name",
            ns_map=element.ns_map,
            package=None,
            module="module",
            substitutions=[
                build_qname("target_ns", "foo"),
                build_qname("sm_ns", "bar"),
            ],
            container="container",
        )
        self.assertEqual(expected, result)
Exemple #19
0
 def next_qname(self, namespace: str, name: str) -> str:
     """Append the next available index number for the given namespace and
     local name."""
     index = 0
     reserved = set(map(alnum, self.container.data.keys()))
     while True:
         index += 1
         qname = build_qname(namespace, f"{name}_{index}")
         if alnum(qname) not in reserved:
             return qname
Exemple #20
0
    def get_type_hints(self, clazz: Type,
                       parent_ns: Optional[str]) -> Iterator[XmlVar]:
        """
        Build the model fields binding metadata.

        :param clazz: The requested dataclass type
        :param parent_ns: The inherited parent namespace
        """
        type_hints = get_type_hints(clazz)
        default_xml_type = self.default_xml_type(clazz)

        for var in fields(clazz):
            tokens = var.metadata.get("tokens", False)
            xml_type = var.metadata.get("type")
            local_name = var.metadata.get("name")
            namespace = var.metadata.get("namespace")
            choices = var.metadata.get("choices", EMPTY_SEQUENCE)
            mixed = var.metadata.get("mixed", False)
            nillable = var.metadata.get("nillable", False)
            sequential = var.metadata.get("sequential", False)

            type_hint = type_hints[var.name]
            types = self.real_types(type_hint)
            any_type = object in types
            element_list = self.is_element_list(type_hint, tokens)
            is_class = any(is_dataclass(clazz) for clazz in types)
            xml_type = xml_type or (XmlType.ELEMENT
                                    if is_class else default_xml_type)
            local_name = local_name or self.local_name(var.name, xml_type)

            namespaces = self.resolve_namespaces(xml_type, namespace,
                                                 parent_ns)
            default_namespace = self.default_namespace(namespaces)
            choice_vars = list(
                self.build_choices(clazz, var.name, parent_ns, choices))
            qname = build_qname(default_namespace, local_name)
            default_value = self.default_value(var)

            yield XmlVar(
                xml_type=xml_type,
                name=var.name,
                qname=qname,
                init=var.init,
                mixed=mixed,
                tokens=tokens,
                any_type=any_type,
                nillable=nillable,
                dataclass=is_class,
                sequential=sequential,
                list_element=element_list,
                default=default_value,
                types=types,
                choices=choice_vars,
                namespaces=namespaces,
            )
Exemple #21
0
    def test_map_binding_operation(self, mock_operation_namespace,
                                   mock_map_binding_operation_messages):
        definitions = Definitions(location="foo.wsdl",
                                  target_namespace="xsdata")
        operation = BindingOperation(name="Add")
        operation.ns_map["foo"] = "bar"
        port_operation = PortTypeOperation()
        config = {"a": "one", "b": "two", "style": "rpc"}
        name = "Calc"
        namespace = "SomeNS"
        first = ClassFactory.create(qname="some_name_first",
                                    meta_name="Envelope")
        second = ClassFactory.create(qname="some_name_second",
                                     meta_name="Envelope")
        other = ClassFactory.create()
        service = ClassFactory.create(
            qname=build_qname("xsdata", "Calc_Add"),
            status=Status.PROCESSED,
            tag=Tag.BINDING_OPERATION,
            module="foo",
            package=None,
            ns_map={"foo": "bar"},
            attrs=[
                DefinitionsMapper.build_attr("a",
                                             str(DataType.STRING),
                                             native=True,
                                             default="one"),
                DefinitionsMapper.build_attr("b",
                                             str(DataType.STRING),
                                             native=True,
                                             default="two"),
                DefinitionsMapper.build_attr("style",
                                             str(DataType.STRING),
                                             native=True,
                                             default="rpc"),
                DefinitionsMapper.build_attr("first", first.qname),
                DefinitionsMapper.build_attr("second", second.qname),
            ],
        )
        mock_operation_namespace.return_value = namespace
        mock_map_binding_operation_messages.return_value = [
            first, second, other
        ]

        result = DefinitionsMapper.map_binding_operation(
            definitions, operation, port_operation, config, name)
        expected = [first, second, other, service]

        self.assertIsInstance(result, Generator)
        self.assertEqual(expected, list(result))
        mock_operation_namespace.assert_called_once_with(config)
        mock_map_binding_operation_messages.assert_called_once_with(
            definitions, operation, port_operation, service.name, "rpc",
            namespace)
Exemple #22
0
    def test_children_extensions(self):
        complex_type = ComplexType(
            attributes=[Attribute() for _ in range(2)],
            simple_content=SimpleContent(restriction=Restriction(base="bk:b")),
            complex_content=ComplexContent(extension=Extension(base="bk:c")),
        )
        complex_type.simple_content.restriction.index = 4
        complex_type.complex_content.extension.index = 7

        item = ClassFactory.create(ns_map={"bk": "book"})
        children = SchemaMapper.children_extensions(complex_type, item)
        expected = list(
            map(
                ExtensionFactory.create,
                [
                    AttrTypeFactory.create(qname=build_qname("book", "b")),
                    AttrTypeFactory.create(qname=build_qname("book", "c")),
                ],
            ))

        self.assertIsInstance(children, GeneratorType)
        self.assertEqual(expected, list(children))
Exemple #23
0
    def startElementNS(self, name: Tuple[Optional[str], str], qname: Any,
                       attrs: Dict):
        """
        Start element notification receiver.

        The receiver will flush any previous active element, append a
        new data frame to collect data content for the next active
        element and notify the main parser to prepare for next binding
        instruction.

        Converts name and attribute keys to fully qualified tags to
        respect the main parser api, eg (foo, bar) -> {foo}bar

        :param name: Namespace-name tuple
        :param qname: Not used
        """
        attrs = {
            build_qname(key[0], key[1]): value
            for key, value in attrs.items()
        }
        self.start(build_qname(name[0], name[1]), attrs, self.ns_map)
        self.ns_map = {}
Exemple #24
0
    def test_map_port_type_message(self):
        port_type_message = PortTypeMessage(message="foo:bar")
        port_type_message.ns_map["foo"] = "foobar"
        target_namespace = "xsdata"

        actual = DefinitionsMapper.map_port_type_message(
            port_type_message, target_namespace)
        expected = DefinitionsMapper.build_attr("bar",
                                                qname=build_qname(
                                                    "foobar", "bar"),
                                                namespace=target_namespace)

        self.assertIsInstance(actual, Generator)
        self.assertEqual([expected], list(actual))
Exemple #25
0
    def endElementNS(self, name: Tuple, qname: Any):
        """
        End element notification receiver.

        The receiver will flush any previous active element and set
        the next element to be flushed.

        Converts name and attribute keys to fully qualified tags to
        respect the ain parser api, eg (foo, bar) -> {foo}bar

        :param name: Namespace-name tuple
        :param qname: Not used
        """
        self.end(build_qname(name[0], name[1]))
Exemple #26
0
    def build_class(cls, element: AnyElement,
                    target_namespace: Optional[str]) -> Class:

        assert element.qname is not None

        namespace, name = split_qname(element.qname)
        target = Class(
            qname=build_qname(target_namespace, name),
            namespace=cls.select_namespace(namespace, target_namespace),
            tag=Tag.ELEMENT,
            module="",
        )
        children = [c for c in element.children if isinstance(c, AnyElement)]
        sequential_set = cls.sequential_names(children)

        for key, value in element.attributes.items():
            attr_type = cls.build_attribute_type(key, value)
            cls.build_attribute(target, key, attr_type, target_namespace,
                                Tag.ATTRIBUTE)

        for child in children:

            assert child.qname is not None

            if child.tail:
                target.mixed = True

            if child.attributes or child.children:
                inner = cls.build_class(child, target_namespace)
                attr_type = AttrType(qname=inner.qname, forward=True)
                target.inner.append(inner)
            else:
                attr_type = cls.build_attribute_type(child.qname, child.text)

            cls.build_attribute(
                target,
                child.qname,
                attr_type,
                target_namespace,
                Tag.ELEMENT,
                child.qname in sequential_set,
            )

        if element.text:
            attr_type = cls.build_attribute_type("value", element.text)
            cls.build_attribute(target, "value", attr_type, None,
                                Tag.SIMPLE_TYPE)

        return target
Exemple #27
0
    def create(
        cls,
        qname: Optional[str] = None,
        meta_name: Optional[str] = None,
        namespace: Optional[str] = None,
        tag: Optional[str] = None,
        abstract: bool = False,
        mixed: bool = False,
        nillable: bool = False,
        extensions: Optional[List[Extension]] = None,
        substitutions: Optional[List[str]] = None,
        attrs: Optional[List[Attr]] = None,
        inner: Optional[List[Class]] = None,
        ns_map: Optional[Dict] = None,
        package: Optional[str] = None,
        module: str = "tests",
        status: Status = Status.RAW,
        container: Optional[str] = None,
        default: Any = None,
        fixed: bool = False,
        **kwargs: Any,
    ) -> Class:
        if not qname:
            qname = build_qname("xsdata", f"class_{cls.next_letter()}")

        if ns_map is None:
            ns_map = copy.deepcopy(DEFAULT_NS_MAP)

        return Class(
            qname=qname,
            meta_name=meta_name,
            namespace=namespace,
            abstract=abstract,
            mixed=mixed,
            nillable=nillable,
            tag=tag or random.choice(cls.tags),
            extensions=extensions or [],
            substitutions=substitutions or [],
            attrs=attrs or [],
            inner=inner or [],
            package=package,
            module=module,
            ns_map=ns_map,
            status=status,
            container=container,
            default=default,
            fixed=fixed,
            **kwargs,
        )
Exemple #28
0
    def build_data_type(cls,
                        target: Class,
                        name: str,
                        forward: bool = False) -> AttrType:
        """Create an attribute type for the target class."""
        prefix, suffix = text.split(name)
        namespace = target.ns_map.get(prefix, target.target_namespace)
        qname = build_qname(namespace, suffix)
        datatype = DataType.from_qname(qname)

        return AttrType(
            qname=qname,
            native=datatype is not None,
            forward=forward,
        )
Exemple #29
0
    def build_choices(
        self,
        clazz: Type,
        parent_name: str,
        parent_namespace: Optional[str],
        choices: List[Dict],
    ):
        existing_types = set()
        globalns = sys.modules[clazz.__module__].__dict__
        for choice in choices:
            xml_type = XmlType.WILDCARD if choice.get(
                "wildcard") else XmlType.ELEMENT
            namespace = choice.get("namespace")
            tokens = choice.get("tokens", False)
            nillable = choice.get("nillable", False)
            format_str = choice.get("format", None)
            default_value = choice.get("default_factory",
                                       choice.get("default"))

            types = self.real_types(_eval_type(choice["type"], globalns, None))
            is_class = any(is_dataclass(clazz) for clazz in types)
            any_type = xml_type == XmlType.ELEMENT and object in types
            derived = any(True
                          for tp in types if tp in existing_types) or any_type

            namespaces = self.resolve_namespaces(xml_type, namespace,
                                                 parent_namespace)
            default_namespace = self.default_namespace(namespaces)
            qname = build_qname(default_namespace, choice.get("name", "any"))

            existing_types.update(types)

            yield XmlVar(
                xml_type=xml_type,
                name=parent_name,
                qname=qname,
                tokens=tokens,
                format=format_str,
                derived=derived,
                any_type=any_type,
                nillable=nillable,
                dataclass=is_class,
                default=default_value,
                types=types,
                namespaces=namespaces,
            )
Exemple #30
0
    def build_message_class(cls, definitions: Definitions,
                            port_type_message: PortTypeMessage) -> Class:
        """Step 6.2: Build the input/output message class of an rpc style
        operation."""
        message_name = text.suffix(port_type_message.message)
        definition_message = definitions.find_message(message_name)
        ns_map = definition_message.ns_map.copy()

        return Class(
            qname=build_qname(definitions.target_namespace, message_name),
            status=Status.PROCESSED,
            tag=Tag.ELEMENT,
            module=definitions.module,
            ns_map=ns_map,
            attrs=list(
                cls.build_parts_attributes(definition_message.parts, ns_map)),
        )