Exemplo n.º 1
0
    def reset_unsupported_types(cls, target: Class):
        for attr in target.attrs:

            if not cls.validate_default_value(attr, target.ns_map):
                attr.types.clear()
                attr.types.append(AttrType(qname=str(DataType.STRING), native=True))
                attr.restrictions.format = None

            attr.types = collections.unique_sequence(attr.types, key="qname")
Exemplo n.º 2
0
    def process(self, target: Class):
        """
        Process the given class attributes and their types.

        Ensure all types are unique.
        """
        for attr in list(target.attrs):
            for attr_type in list(attr.types):
                self.process_type(target, attr, attr_type)

            attr.types = unique_sequence(attr.types, key="name")
Exemplo n.º 3
0
    def build_class_extensions(cls, obj: ElementBase, target: Class):
        """Build the item class extensions from the given ElementBase
        children."""

        restrictions = obj.get_restrictions()
        extensions = [
            cls.build_class_extension(target, base, restrictions)
            for base in obj.bases
        ]
        extensions.extend(cls.children_extensions(obj, target))
        target.extensions = collections.unique_sequence(extensions)
Exemplo n.º 4
0
    def flatten(cls, target: Class, module: str) -> Iterator[Class]:
        target.module = module

        while target.inner:
            yield from cls.flatten(target.inner.pop(), module)

        for attr in target.attrs:
            attr.types = collections.unique_sequence(attr.types, key="qname")
            for tp in attr.types:
                tp.forward = False

        yield target
Exemplo n.º 5
0
    def flatten_attribute_types(self, target: Class, attr: Attr):
        """
        Loop over the the given attribute types to flatten simple definitions.

        Notes:
            * xs:pattern is not yet supported reset all native types to xs:string.
            * skip over forward references aka inner classes
        """
        for current_type in list(attr.types):
            if current_type.native:
                if attr.restrictions.pattern:
                    self.reset_attribute_type(current_type)
            elif not current_type.forward_ref:
                self.flatten_attribute_type(target, attr, current_type)

        attr.types = unique_sequence(attr.types, key="name")
Exemplo n.º 6
0
    def build_class_attribute_types(cls, target: Class,
                                    obj: ElementBase) -> List[AttrType]:
        """Convert real type and anonymous inner types to an attribute type
        list."""

        types = [cls.build_data_type(target, tp) for tp in obj.attr_types]

        module = target.module
        namespace = target.target_namespace
        for inner in cls.build_inner_classes(obj, module, namespace):
            target.inner.append(inner)
            types.append(AttrType(qname=inner.qname, forward=True))

        if len(types) == 0:
            types.append(cls.build_data_type(target, name=obj.default_type))

        return collections.unique_sequence(types)
Exemplo n.º 7
0
    def field_type(self, attr: Attr, parents: List[str]) -> str:
        """Generate type hints for the given attribute."""

        type_names = unique_sequence(
            self.field_type_name(x, parents) for x in attr.types)

        result = ", ".join(type_names)
        if len(type_names) > 1:
            result = f"Union[{result}]"

        if attr.is_tokens:
            result = f"List[{result}]"

        if attr.is_list:
            result = f"List[{result}]"
        elif attr.is_dict:
            result = "Dict"
        elif attr.default is None and not attr.is_factory:
            result = f"Optional[{result}]"

        return result
Exemplo n.º 8
0
    def choice_type(self, choice: Attr, parents: List[str]) -> str:
        """
        Generate type hints for the given choice.

        Choices support a subset of features from normal attributes.
        First of all we don't have a proper type hint but a type
        metadata key. That's why we always need to wrap as Type[xxx].
        The second big difference is that our choice belongs to a
        compound field that might be a list, that's why list restriction
        is also ignored.
        """
        type_names = unique_sequence(
            self.field_type_name(x, parents) for x in choice.types)

        result = ", ".join(type_names)
        if len(type_names) > 1:
            result = f"Union[{result}]"

        if choice.is_tokens:
            result = f"List[{result}]"

        return f"Type[{result}]"
Exemplo n.º 9
0
    def filter_types(cls, types: List[AttrType]) -> List[AttrType]:
        """
        Remove duplicate and invalid types.

        Invalid:
            1. xs:error
            2. xs:anyType and xs:anySimpleType when there are other types present
        """
        types = collections.unique_sequence(types, key="qname")
        types = collections.remove(types,
                                   lambda x: x.datatype == DataType.ERROR)

        if len(types) > 1:
            types = collections.remove(
                types,
                lambda x: x.datatype in
                (DataType.ANY_TYPE, DataType.ANY_SIMPLE_TYPE),
            )

        if not types:
            types.append(AttrType(qname=str(DataType.STRING), native=True))

        return types
Exemplo n.º 10
0
def collapse_whitespace(string: str) -> str:
    """Remove excess whitespace and duplicate words."""
    return " ".join(
        unique_sequence([part for part in string.split(" ") if part.strip()]))
Exemplo n.º 11
0
 def __post_init__(self):
     self.namespace = " ".join(unique_sequence(self.namespace.split()))
Exemplo n.º 12
0
def collapse_whitespace(string: str) -> str:
    """Remove excess whitespace and duplicate words."""
    return " ".join(unique_sequence(string.split()))