Skip to content

compat

xsdata.formats.dataclass.compat

FieldInfo

Bases: Protocol

A class field info wrapper.

Source code in xsdata/formats/dataclass/compat.py
11
12
13
14
15
16
17
18
class FieldInfo(Protocol):
    """A class field info wrapper."""

    name: str
    init: bool
    metadata: "MappingProxyType[Any, Any]"
    default: Any
    default_factory: Any

ClassType

Bases: ABC

An interface for class types like attrs, pydantic.

Source code in xsdata/formats/dataclass/compat.py
 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
class ClassType(abc.ABC):
    """An interface for class types like attrs, pydantic."""

    __slots__ = ()

    @property
    @abc.abstractmethod
    def any_element(self) -> Type:
        """Return the AnyElement used to bind wildcard element nodes."""

    @property
    @abc.abstractmethod
    def derived_element(self) -> Type:
        """Return the DerivedElement used to bind ambiguous element nodes."""

    @property
    def any_keys(self) -> Set[str]:
        """Return the field names of the AnyElement class."""
        return {field.name for field in self.get_fields(self.any_element)}

    @property
    def derived_keys(self) -> Set[str]:
        """Return the field names of the DerivedElement class."""
        return {field.name for field in self.get_fields(self.derived_element)}

    @abc.abstractmethod
    def is_model(self, obj: Any) -> bool:
        """Return whether the given value is binding model."""

    @abc.abstractmethod
    def verify_model(self, obj: Any):
        """Verify the given value is a binding model.

        Args:
            obj: The input model instance

        Raises:
            XmlContextError: if not supported
        """

    @abc.abstractmethod
    def get_fields(self, obj: Any) -> Iterator[FieldInfo]:
        """Return the models fields in the correct mro ordering."""

    @abc.abstractmethod
    def default_value(self, field: FieldInfo, default: Optional[Any] = None) -> Any:
        """Return the default value or factory of the given model field."""

    @abc.abstractmethod
    def default_choice_value(self, choice: Dict) -> Any:
        """Return the default value or factory of the given model field choice."""

    def score_object(self, obj: Any) -> float:
        """Score a binding model instance by its field values types.

        Weights:
            1. None: 0
            2. str: 1
            3. *: 1.5

        Args:
            obj: The input object

        Returns:
            The float score value.
        """
        if not obj:
            return -1.0

        def score(value: Any) -> float:
            if isinstance(value, str):
                return 1.0

            if value is not None:
                return 1.5

            return 0.0

        if self.is_model(obj):
            return sum(
                score(getattr(obj, var.name, None)) for var in self.get_fields(obj)
            )

        return score(obj)

any_element: Type abstractmethod property

Return the AnyElement used to bind wildcard element nodes.

derived_element: Type abstractmethod property

Return the DerivedElement used to bind ambiguous element nodes.

any_keys: Set[str] property

Return the field names of the AnyElement class.

derived_keys: Set[str] property

Return the field names of the DerivedElement class.

is_model(obj) abstractmethod

Return whether the given value is binding model.

Source code in xsdata/formats/dataclass/compat.py
46
47
48
@abc.abstractmethod
def is_model(self, obj: Any) -> bool:
    """Return whether the given value is binding model."""

verify_model(obj) abstractmethod

Verify the given value is a binding model.

Parameters:

Name Type Description Default
obj Any

The input model instance

required

Raises:

Type Description
XmlContextError

if not supported

Source code in xsdata/formats/dataclass/compat.py
50
51
52
53
54
55
56
57
58
59
@abc.abstractmethod
def verify_model(self, obj: Any):
    """Verify the given value is a binding model.

    Args:
        obj: The input model instance

    Raises:
        XmlContextError: if not supported
    """

get_fields(obj) abstractmethod

Return the models fields in the correct mro ordering.

Source code in xsdata/formats/dataclass/compat.py
61
62
63
@abc.abstractmethod
def get_fields(self, obj: Any) -> Iterator[FieldInfo]:
    """Return the models fields in the correct mro ordering."""

default_value(field, default=None) abstractmethod

Return the default value or factory of the given model field.

Source code in xsdata/formats/dataclass/compat.py
65
66
67
@abc.abstractmethod
def default_value(self, field: FieldInfo, default: Optional[Any] = None) -> Any:
    """Return the default value or factory of the given model field."""

default_choice_value(choice) abstractmethod

Return the default value or factory of the given model field choice.

Source code in xsdata/formats/dataclass/compat.py
69
70
71
@abc.abstractmethod
def default_choice_value(self, choice: Dict) -> Any:
    """Return the default value or factory of the given model field choice."""

score_object(obj)

Score a binding model instance by its field values types.

Weights
  1. None: 0
  2. str: 1
  3. *: 1.5

Parameters:

Name Type Description Default
obj Any

The input object

required

Returns:

Type Description
float

The float score value.

Source code in xsdata/formats/dataclass/compat.py
 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
def score_object(self, obj: Any) -> float:
    """Score a binding model instance by its field values types.

    Weights:
        1. None: 0
        2. str: 1
        3. *: 1.5

    Args:
        obj: The input object

    Returns:
        The float score value.
    """
    if not obj:
        return -1.0

    def score(value: Any) -> float:
        if isinstance(value, str):
            return 1.0

        if value is not None:
            return 1.5

        return 0.0

    if self.is_model(obj):
        return sum(
            score(getattr(obj, var.name, None)) for var in self.get_fields(obj)
        )

    return score(obj)

ClassTypes

A class types registry.

Attributes:

Name Type Description
types Dict[str, ClassType]

A name-instance map of the registered class types

Source code in xsdata/formats/dataclass/compat.py
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
class ClassTypes:
    """A class types registry.

    Attributes:
        types: A name-instance map of the registered class types
    """

    __slots__ = "types"

    def __init__(self):
        self.types: Dict[str, ClassType] = {}

    def register(self, name: str, fmt: ClassType, **_: Any):
        """Register a class type instance by name.

        Args:
            name: The name of the class type
            fmt: The class type instance
            **_: No idea :(
        """
        self.types[name] = fmt

    def get_type(self, name: str) -> ClassType:
        """Get a class type instance by name.

        Args:
            name: The class type name

        Returns:
            The class type instance

        Raises:
            KeyError: If the name is not registered.
        """
        return self.types[name]

register(name, fmt, **_)

Register a class type instance by name.

Parameters:

Name Type Description Default
name str

The name of the class type

required
fmt ClassType

The class type instance

required
**_ Any

No idea :(

{}
Source code in xsdata/formats/dataclass/compat.py
119
120
121
122
123
124
125
126
127
def register(self, name: str, fmt: ClassType, **_: Any):
    """Register a class type instance by name.

    Args:
        name: The name of the class type
        fmt: The class type instance
        **_: No idea :(
    """
    self.types[name] = fmt

get_type(name)

Get a class type instance by name.

Parameters:

Name Type Description Default
name str

The class type name

required

Returns:

Type Description
ClassType

The class type instance

Raises:

Type Description
KeyError

If the name is not registered.

Source code in xsdata/formats/dataclass/compat.py
129
130
131
132
133
134
135
136
137
138
139
140
141
def get_type(self, name: str) -> ClassType:
    """Get a class type instance by name.

    Args:
        name: The class type name

    Returns:
        The class type instance

    Raises:
        KeyError: If the name is not registered.
    """
    return self.types[name]

Dataclasses

Bases: ClassType

The dataclasses class type.

Source code in xsdata/formats/dataclass/compat.py
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
class Dataclasses(ClassType):
    """The dataclasses class type."""

    __slots__ = ()

    @property
    def any_element(self) -> Type:
        """Return the generic any element class."""
        return AnyElement

    @property
    def derived_element(self) -> Type:
        """Return the generic derived element class."""
        return DerivedElement

    def is_model(self, obj: Any) -> bool:
        """Return whether the obj is a dataclass model."""
        return is_dataclass(obj)

    def verify_model(self, obj: Any):
        """Validate whether the obj is a dataclass model.

        Args:
            obj: The input object to validate.

        Raises:
            XmlContextError: If it's not a dataclass model.
        """
        if not self.is_model(obj):
            raise XmlContextError(f"Type '{obj}' is not a dataclass.")

    def get_fields(self, obj: Any) -> Iterator[FieldInfo]:
        """Return a dataclass fields iterator."""
        yield from fields(obj)

    def default_value(self, field: FieldInfo, default: Optional[Any] = None) -> Any:
        """Return the default value or factory of the given model field."""
        if field.default_factory is not MISSING:
            return field.default_factory

        if field.default is not MISSING:
            return field.default

        return default

    def default_choice_value(self, choice: Dict) -> Any:
        """Return the default value or factory of the given model field choice."""
        factory = choice.get("default_factory")
        if callable(factory):
            return factory

        return choice.get("default")

any_element: Type property

Return the generic any element class.

derived_element: Type property

Return the generic derived element class.

is_model(obj)

Return whether the obj is a dataclass model.

Source code in xsdata/formats/dataclass/compat.py
159
160
161
def is_model(self, obj: Any) -> bool:
    """Return whether the obj is a dataclass model."""
    return is_dataclass(obj)

verify_model(obj)

Validate whether the obj is a dataclass model.

Parameters:

Name Type Description Default
obj Any

The input object to validate.

required

Raises:

Type Description
XmlContextError

If it's not a dataclass model.

Source code in xsdata/formats/dataclass/compat.py
163
164
165
166
167
168
169
170
171
172
173
def verify_model(self, obj: Any):
    """Validate whether the obj is a dataclass model.

    Args:
        obj: The input object to validate.

    Raises:
        XmlContextError: If it's not a dataclass model.
    """
    if not self.is_model(obj):
        raise XmlContextError(f"Type '{obj}' is not a dataclass.")

get_fields(obj)

Return a dataclass fields iterator.

Source code in xsdata/formats/dataclass/compat.py
175
176
177
def get_fields(self, obj: Any) -> Iterator[FieldInfo]:
    """Return a dataclass fields iterator."""
    yield from fields(obj)

default_value(field, default=None)

Return the default value or factory of the given model field.

Source code in xsdata/formats/dataclass/compat.py
179
180
181
182
183
184
185
186
187
def default_value(self, field: FieldInfo, default: Optional[Any] = None) -> Any:
    """Return the default value or factory of the given model field."""
    if field.default_factory is not MISSING:
        return field.default_factory

    if field.default is not MISSING:
        return field.default

    return default

default_choice_value(choice)

Return the default value or factory of the given model field choice.

Source code in xsdata/formats/dataclass/compat.py
189
190
191
192
193
194
195
def default_choice_value(self, choice: Dict) -> Any:
    """Return the default value or factory of the given model field choice."""
    factory = choice.get("default_factory")
    if callable(factory):
        return factory

    return choice.get("default")