Skip to content

code

xsdata.formats.dataclass.serializers.code

PycodeSerializer dataclass

Pycode serializer for data class instances.

Generate python pretty representation code from a model instance.

Parameters:

Name Type Description Default
context XmlContext

The models context instance

XmlContext()
Source code in xsdata/formats/dataclass/serializers/code.py
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
@dataclass
class PycodeSerializer:
    """Pycode serializer for data class instances.

    Generate python pretty representation code from a model instance.

    Args:
        context: The models context instance
    """

    context: XmlContext = field(default_factory=XmlContext)

    def render(self, obj: object, var_name: str = "obj") -> str:
        """Serialize the input model instance to python representation string.

        Args:
            obj: The input model instance to serialize
            var_name: The var name to assign the model instance

        Returns:
            The serialized representation string.
        """
        output = StringIO()
        self.write(output, obj, var_name)
        return output.getvalue()

    def write(self, out: TextIO, obj: Any, var_name: str):
        """Write the given object to the output text stream.

        Args:
            out: The output text stream
            obj: The input model instance to serialize
            var_name: The var name to assign the model instance
        """
        types: Set[Type] = set()

        tmp = StringIO()
        for chunk in self.repr_object(obj, 0, types):
            tmp.write(chunk)

        imports = self.build_imports(types)
        out.write(imports)
        out.write("\n\n")
        out.write(f"{var_name} = ")
        out.write(tmp.getvalue())
        out.write("\n")

    @classmethod
    def build_imports(cls, types: Set[Type]) -> str:
        """Build a list of imports from the given types.

        Args:
            types: A set of types

        Returns:
            The `from x import y` statements as string.
        """
        imports = set()
        for tp in types:
            module = tp.__module__
            name = tp.__qualname__
            if module != "builtins":
                if "." in name:
                    name = name.split(".")[0]

                imports.add(f"from {module} import {name}\n")

        return "".join(sorted(set(imports)))

    def repr_object(self, obj: Any, level: int, types: Set[Type]) -> Iterator[str]:
        """Write the given object as repr code.

        Args:
            obj: The input object to serialize
            level: The current object level
            types: The parent object types

        Yields:
            An iterator of the representation strings.
        """
        types.add(type(obj))
        if collections.is_array(obj):
            yield from self.repr_array(obj, level, types)
        elif isinstance(obj, dict):
            yield from self.repr_mapping(obj, level, types)
        elif self.context.class_type.is_model(obj):
            yield from self.repr_model(obj, level, types)
        elif isinstance(obj, Enum):
            yield str(obj)
        else:
            yield literal_value(obj)

    def repr_array(
        self,
        obj: Union[List, Set, Tuple],
        level: int,
        types: Set[Type],
    ) -> Iterator[str]:
        """Convert an iterable object to repr code.

        Args:
            obj: A list, set, tuple instance
            level: The current object level
            types: The parent object types

        Yields:
            An iterator of the representation strings.
        """
        if not obj:
            yield str(obj)
            return

        next_level = level + 1
        yield "[\n"
        for val in obj:
            yield spaces * next_level
            yield from self.repr_object(val, next_level, types)
            yield ",\n"

        yield f"{spaces * level}]"

    def repr_mapping(self, obj: Mapping, level: int, types: Set[Type]) -> Iterator[str]:
        """Convert a map object to repr code.

        Args:
            obj: A map instance
            level: The current object level
            types: The parent object types

        Yields:
            An iterator of the representation strings.
        """
        if not obj:
            yield str(obj)
            return

        next_level = level + 1
        yield "{\n"
        for key, value in obj.items():
            yield spaces * next_level
            yield from self.repr_object(key, next_level, types)
            yield ": "
            yield from self.repr_object(value, next_level, types)
            yield ",\n"

        yield f"{spaces * level}}}"

    def repr_model(self, obj: Any, level: int, types: Set[Type]) -> Iterator[str]:
        """Convert a data model instance to repr code.

        Args:
            obj: A map instance
            level: The current object level
            types: The parent object types

        Yields:
            An iterator of the representation strings.
        """
        yield f"{obj.__class__.__qualname__}(\n"

        next_level = level + 1
        index = 0
        for f in self.context.class_type.get_fields(obj):
            if not f.init:
                continue

            value = getattr(obj, f.name, types)
            default = self.context.class_type.default_value(f, default=unset)
            if default is not unset and (
                (callable(default) and default() == value) or default == value
            ):
                continue

            if index:
                yield f",\n{spaces * next_level}{f.name}="
            else:
                yield f"{spaces * next_level}{f.name}="

            yield from self.repr_object(value, next_level, types)

            index += 1

        yield f"\n{spaces * level})"

render(obj, var_name='obj')

Serialize the input model instance to python representation string.

Parameters:

Name Type Description Default
obj object

The input model instance to serialize

required
var_name str

The var name to assign the model instance

'obj'

Returns:

Type Description
str

The serialized representation string.

Source code in xsdata/formats/dataclass/serializers/code.py
28
29
30
31
32
33
34
35
36
37
38
39
40
def render(self, obj: object, var_name: str = "obj") -> str:
    """Serialize the input model instance to python representation string.

    Args:
        obj: The input model instance to serialize
        var_name: The var name to assign the model instance

    Returns:
        The serialized representation string.
    """
    output = StringIO()
    self.write(output, obj, var_name)
    return output.getvalue()

write(out, obj, var_name)

Write the given object to the output text stream.

Parameters:

Name Type Description Default
out TextIO

The output text stream

required
obj Any

The input model instance to serialize

required
var_name str

The var name to assign the model instance

required
Source code in xsdata/formats/dataclass/serializers/code.py
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
def write(self, out: TextIO, obj: Any, var_name: str):
    """Write the given object to the output text stream.

    Args:
        out: The output text stream
        obj: The input model instance to serialize
        var_name: The var name to assign the model instance
    """
    types: Set[Type] = set()

    tmp = StringIO()
    for chunk in self.repr_object(obj, 0, types):
        tmp.write(chunk)

    imports = self.build_imports(types)
    out.write(imports)
    out.write("\n\n")
    out.write(f"{var_name} = ")
    out.write(tmp.getvalue())
    out.write("\n")

build_imports(types) classmethod

Build a list of imports from the given types.

Parameters:

Name Type Description Default
types Set[Type]

A set of types

required

Returns:

Type Description
str

The from x import y statements as string.

Source code in xsdata/formats/dataclass/serializers/code.py
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
@classmethod
def build_imports(cls, types: Set[Type]) -> str:
    """Build a list of imports from the given types.

    Args:
        types: A set of types

    Returns:
        The `from x import y` statements as string.
    """
    imports = set()
    for tp in types:
        module = tp.__module__
        name = tp.__qualname__
        if module != "builtins":
            if "." in name:
                name = name.split(".")[0]

            imports.add(f"from {module} import {name}\n")

    return "".join(sorted(set(imports)))

repr_object(obj, level, types)

Write the given object as repr code.

Parameters:

Name Type Description Default
obj Any

The input object to serialize

required
level int

The current object level

required
types Set[Type]

The parent object types

required

Yields:

Type Description
str

An iterator of the representation strings.

Source code in xsdata/formats/dataclass/serializers/code.py
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
def repr_object(self, obj: Any, level: int, types: Set[Type]) -> Iterator[str]:
    """Write the given object as repr code.

    Args:
        obj: The input object to serialize
        level: The current object level
        types: The parent object types

    Yields:
        An iterator of the representation strings.
    """
    types.add(type(obj))
    if collections.is_array(obj):
        yield from self.repr_array(obj, level, types)
    elif isinstance(obj, dict):
        yield from self.repr_mapping(obj, level, types)
    elif self.context.class_type.is_model(obj):
        yield from self.repr_model(obj, level, types)
    elif isinstance(obj, Enum):
        yield str(obj)
    else:
        yield literal_value(obj)

repr_array(obj, level, types)

Convert an iterable object to repr code.

Parameters:

Name Type Description Default
obj Union[List, Set, Tuple]

A list, set, tuple instance

required
level int

The current object level

required
types Set[Type]

The parent object types

required

Yields:

Type Description
str

An iterator of the representation strings.

Source code in xsdata/formats/dataclass/serializers/code.py
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
def repr_array(
    self,
    obj: Union[List, Set, Tuple],
    level: int,
    types: Set[Type],
) -> Iterator[str]:
    """Convert an iterable object to repr code.

    Args:
        obj: A list, set, tuple instance
        level: The current object level
        types: The parent object types

    Yields:
        An iterator of the representation strings.
    """
    if not obj:
        yield str(obj)
        return

    next_level = level + 1
    yield "[\n"
    for val in obj:
        yield spaces * next_level
        yield from self.repr_object(val, next_level, types)
        yield ",\n"

    yield f"{spaces * level}]"

repr_mapping(obj, level, types)

Convert a map object to repr code.

Parameters:

Name Type Description Default
obj Mapping

A map instance

required
level int

The current object level

required
types Set[Type]

The parent object types

required

Yields:

Type Description
str

An iterator of the representation strings.

Source code in xsdata/formats/dataclass/serializers/code.py
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
def repr_mapping(self, obj: Mapping, level: int, types: Set[Type]) -> Iterator[str]:
    """Convert a map object to repr code.

    Args:
        obj: A map instance
        level: The current object level
        types: The parent object types

    Yields:
        An iterator of the representation strings.
    """
    if not obj:
        yield str(obj)
        return

    next_level = level + 1
    yield "{\n"
    for key, value in obj.items():
        yield spaces * next_level
        yield from self.repr_object(key, next_level, types)
        yield ": "
        yield from self.repr_object(value, next_level, types)
        yield ",\n"

    yield f"{spaces * level}}}"

repr_model(obj, level, types)

Convert a data model instance to repr code.

Parameters:

Name Type Description Default
obj Any

A map instance

required
level int

The current object level

required
types Set[Type]

The parent object types

required

Yields:

Type Description
str

An iterator of the representation strings.

Source code in xsdata/formats/dataclass/serializers/code.py
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
def repr_model(self, obj: Any, level: int, types: Set[Type]) -> Iterator[str]:
    """Convert a data model instance to repr code.

    Args:
        obj: A map instance
        level: The current object level
        types: The parent object types

    Yields:
        An iterator of the representation strings.
    """
    yield f"{obj.__class__.__qualname__}(\n"

    next_level = level + 1
    index = 0
    for f in self.context.class_type.get_fields(obj):
        if not f.init:
            continue

        value = getattr(obj, f.name, types)
        default = self.context.class_type.default_value(f, default=unset)
        if default is not unset and (
            (callable(default) and default() == value) or default == value
        ):
            continue

        if index:
            yield f",\n{spaces * next_level}{f.name}="
        else:
            yield f"{spaces * next_level}{f.name}="

        yield from self.repr_object(value, next_level, types)

        index += 1

    yield f"\n{spaces * level})"