Skip to content

mixins

xsdata.formats.mixins

GeneratorResult

Bases: NamedTuple

Generator result transfer object.

Attributes:

Name Type Description
path Path

The target file path

title str

The result title for misc usage

source str

The source code/output to be written

Source code in xsdata/formats/mixins.py
15
16
17
18
19
20
21
22
23
24
25
26
class GeneratorResult(NamedTuple):
    """Generator result transfer object.

    Attributes:
        path: The target file path
        title: The result title for misc usage
        source: The source code/output to be written
    """

    path: Path
    title: str
    source: str

AbstractGenerator

Bases: ABC

Abstract code generator class.

Parameters:

Name Type Description Default
config GeneratorConfig

The generator config instance

required
Source code in xsdata/formats/mixins.py
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
class AbstractGenerator(abc.ABC):
    """Abstract code generator class.

    Args:
        config: The generator config instance
    """

    __slots__ = "config"

    def __init__(self, config: GeneratorConfig):
        self.config = config

    def module_name(self, module: str) -> str:
        """Convert the given module name to match the generator conventions."""
        return module

    def package_name(self, package: str) -> str:
        """Convert the given module name to match the generator conventions."""
        return package

    @abc.abstractmethod
    def render(self, classes: list[Class]) -> Iterator[GeneratorResult]:
        """Return an iterator of the generated results."""

    @classmethod
    def group_by_package(cls, classes: list[Class]) -> dict[Path, list[Class]]:
        """Group the given list of classes by the target package directory."""
        return group_by(classes, lambda x: package_path(x.target_module))

    @classmethod
    def group_by_module(cls, classes: list[Class]) -> dict[Path, list[Class]]:
        """Group the given list of classes by the target module directory."""
        return group_by(classes, lambda x: module_path(x.target_module))

    def render_header(self) -> str:
        """Generate a header for the writer to prepend on the output files."""
        if not self.config.output.include_header:
            return ""

        now = datetime.datetime.now().isoformat(sep=" ", timespec="seconds")
        return (
            f'"""This file was generated by xsdata, v{__version__}, on {now}'
            f"\n\nGenerator: {self.__class__.__qualname__}\n"
            f"See: https://xsdata.readthedocs.io/\n"
            '"""\n'
        )

    def normalize_packages(self, classes: list[Class]):
        """Normalize the classes module and package names.

        Args:
            classes: A list of class instances

        Raises:
            CodeGenerationError: If the analyzer failed to
                designate a class to a package and module.
        """
        modules = {}
        packages = {}
        for obj in classes:
            if obj.package is None or obj.module is None:
                raise CodegenError(
                    f"Class `{obj.name}` has not been assigned to a package"
                )

            if obj.module not in modules:
                modules[obj.module] = self.module_name(obj.module)

            if obj.package not in packages:
                packages[obj.package] = self.package_name(obj.package)

            obj.module = modules[obj.module]
            obj.package = packages[obj.package]

module_name(module)

Convert the given module name to match the generator conventions.

Source code in xsdata/formats/mixins.py
41
42
43
def module_name(self, module: str) -> str:
    """Convert the given module name to match the generator conventions."""
    return module

package_name(package)

Convert the given module name to match the generator conventions.

Source code in xsdata/formats/mixins.py
45
46
47
def package_name(self, package: str) -> str:
    """Convert the given module name to match the generator conventions."""
    return package

render(classes) abstractmethod

Return an iterator of the generated results.

Source code in xsdata/formats/mixins.py
49
50
51
@abc.abstractmethod
def render(self, classes: list[Class]) -> Iterator[GeneratorResult]:
    """Return an iterator of the generated results."""

group_by_package(classes) classmethod

Group the given list of classes by the target package directory.

Source code in xsdata/formats/mixins.py
53
54
55
56
@classmethod
def group_by_package(cls, classes: list[Class]) -> dict[Path, list[Class]]:
    """Group the given list of classes by the target package directory."""
    return group_by(classes, lambda x: package_path(x.target_module))

group_by_module(classes) classmethod

Group the given list of classes by the target module directory.

Source code in xsdata/formats/mixins.py
58
59
60
61
@classmethod
def group_by_module(cls, classes: list[Class]) -> dict[Path, list[Class]]:
    """Group the given list of classes by the target module directory."""
    return group_by(classes, lambda x: module_path(x.target_module))

render_header()

Generate a header for the writer to prepend on the output files.

Source code in xsdata/formats/mixins.py
63
64
65
66
67
68
69
70
71
72
73
74
def render_header(self) -> str:
    """Generate a header for the writer to prepend on the output files."""
    if not self.config.output.include_header:
        return ""

    now = datetime.datetime.now().isoformat(sep=" ", timespec="seconds")
    return (
        f'"""This file was generated by xsdata, v{__version__}, on {now}'
        f"\n\nGenerator: {self.__class__.__qualname__}\n"
        f"See: https://xsdata.readthedocs.io/\n"
        '"""\n'
    )

normalize_packages(classes)

Normalize the classes module and package names.

Parameters:

Name Type Description Default
classes list[Class]

A list of class instances

required

Raises:

Type Description
CodeGenerationError

If the analyzer failed to designate a class to a package and module.

Source code in xsdata/formats/mixins.py
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
def normalize_packages(self, classes: list[Class]):
    """Normalize the classes module and package names.

    Args:
        classes: A list of class instances

    Raises:
        CodeGenerationError: If the analyzer failed to
            designate a class to a package and module.
    """
    modules = {}
    packages = {}
    for obj in classes:
        if obj.package is None or obj.module is None:
            raise CodegenError(
                f"Class `{obj.name}` has not been assigned to a package"
            )

        if obj.module not in modules:
            modules[obj.module] = self.module_name(obj.module)

        if obj.package not in packages:
            packages[obj.package] = self.package_name(obj.package)

        obj.module = modules[obj.module]
        obj.package = packages[obj.package]