Skip to content

# models

## `xsdata.codegen.models`

### `CodegenModel` `dataclass`

Base codegen model.

Source code in `xsdata/codegen/models.py`

    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49

    @dataclass
    class CodegenModel:
        """Base codegen model."""

        def clone(self: T, **kwargs: Any) -> T:
            """Return a deep cloned instance."""
            clone = copy.deepcopy(self)
            return replace(clone, **kwargs) if kwargs else clone

        def swap(self, source: "CodegenModel") -> None:
            """Swap the instance attributes from the source instance."""
            for f in fields(self):
                value = copy.deepcopy(getattr(source, f.name))
                setattr(self, f.name, value)

#### `clone(**kwargs)`

Return a deep cloned instance.

Source code in `xsdata/codegen/models.py`

    40
    41
    42
    43

    def clone(self: T, **kwargs: Any) -> T:
        """Return a deep cloned instance."""
        clone = copy.deepcopy(self)
        return replace(clone, **kwargs) if kwargs else clone

#### `swap(source)`

Swap the instance attributes from the source instance.

Source code in `xsdata/codegen/models.py`

    45
    46
    47
    48
    49

    def swap(self, source: "CodegenModel") -> None:
        """Swap the instance attributes from the source instance."""
        for f in fields(self):
            value = copy.deepcopy(getattr(source, f.name))
            setattr(self, f.name, value)

### `Restrictions` `dataclass`

Bases: `CodegenModel`

Class field validation restrictions.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`min_occurs` | `int | None` | The minimum number of occurrences | `None`
`max_occurs` | `int | None` | The maximum number of occurrences | `None`
`min_exclusive` | `str | None` | The lower exclusive bound for numeric values | `None`
`min_inclusive` | `str | None` | The lower inclusive bound for numeric values | `None`
`min_length` | `int | None` | The minimum length of characters or list items allowed | `None`
`max_exclusive` | `str | None` | The upper exclusive bound for numeric values | `None`
`max_inclusive` | `str | None` | The upper inclusive bound for numeric values | `None`
`max_length` | `int | None` | The max length of characters or list items allowed | `None`
`total_digits` | `int | None` | The exact number of digits allowed for numeric values | `None`
`fraction_digits` | `int | None` | The maximum number of decimal places allowed | `None`
`length` | `int | None` | The exact number of characters or list items allowed | `None`
`white_space` | `str | None` | Specifies how white space is handled | `None`
`pattern` | `str | None` | Defines the exact sequence of characters that are acceptable | `None`
`explicit_timezone` | `str | None` | Require or prohibit the time zone offset in date/time | `None`
`nillable` | `bool | None` | Specifies whether nil content is allowed | `None`
`sequence` | `int | None` | The sequence reference number of the attr | `None`
`tokens` | `bool | None` | Specifies whether the value needs tokenization | `None`
`format` | `str | None` | The output format used for byte and datetime types | `None`
`choice` | `int | None` | The choice reference number of the attr | `None`
`group` | `int | None` | The group reference number of the attr | `None`
`process_contents` | `str | None` | Specifies the content processed mode: strict, lax, skip | `None`
`path` | `list[tuple[str, int, int, int]]` | The coded attr path in the source document | `list()`

Source code in `xsdata/codegen/models.py`

     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
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216

    @dataclass
    class Restrictions(CodegenModel):
        """Class field validation restrictions.

        Args:
            min_occurs: The minimum number of occurrences
            max_occurs: The maximum number of occurrences
            min_exclusive: The lower exclusive bound for numeric values
            min_inclusive: The lower inclusive bound for numeric values
            min_length: The minimum length of characters or list items allowed
            max_exclusive: The upper exclusive bound for numeric values
            max_inclusive: The upper inclusive bound for numeric values
            max_length: The max length of characters or list items allowed
            total_digits:  The exact number of digits allowed for numeric values
            fraction_digits: The maximum number of decimal places allowed
            length: The exact number of characters or list items allowed
            white_space: Specifies how white space is handled
            pattern: Defines the exact sequence of characters that are acceptable
            explicit_timezone: Require or prohibit the time zone offset in date/time
            nillable: Specifies whether nil content is allowed
            sequence: The sequence reference number of the attr
            tokens: Specifies whether the value needs tokenization
            format: The output format used for byte and datetime types
            choice: The choice reference number of the attr
            group: The group reference number of the attr
            process_contents: Specifies the content processed mode: strict, lax, skip
            path: The coded attr path in the source document
        """

        min_occurs: int | None = field(default=None)
        max_occurs: int | None = field(default=None)
        min_exclusive: str | None = field(default=None)
        min_inclusive: str | None = field(default=None)
        min_length: int | None = field(default=None)
        max_exclusive: str | None = field(default=None)
        max_inclusive: str | None = field(default=None)
        max_length: int | None = field(default=None)
        total_digits: int | None = field(default=None)
        fraction_digits: int | None = field(default=None)
        length: int | None = field(default=None)
        white_space: str | None = field(default=None)
        pattern: str | None = field(default=None)
        explicit_timezone: str | None = field(default=None)
        nillable: bool | None = field(default=None)
        sequence: int | None = field(default=None, compare=False)
        tokens: bool | None = field(default=None)
        format: str | None = field(default=None)
        choice: int | None = field(default=None, compare=False)
        group: int | None = field(default=None)
        process_contents: str | None = field(default=None)
        path: list[tuple[str, int, int, int]] = field(default_factory=list)

        @property
        def is_list(self) -> bool:
            """Return whether the max occurs larger than one."""
            return self.max_occurs is not None and self.max_occurs > 1

        @property
        def is_optional(self) -> bool:
            """Return whether the min occurs is zero."""
            return self.min_occurs == 0

        @property
        def is_prohibited(self) -> bool:
            """Return whether the max occurs is zero."""
            return self.max_occurs == 0

        def merge(self, source: "Restrictions") -> None:
            """Update properties from another instance.

            Args:
                source: The source instance to merge properties from
            """
            keys = (
                "min_exclusive",
                "min_inclusive",
                "min_length",
                "max_exclusive",
                "max_inclusive",
                "max_length",
                "total_digits",
                "fraction_digits",
                "length",
                "white_space",
                "pattern",
                "explicit_timezone",
                "process_contents",
            )

            for key in keys:
                value = getattr(source, key)
                if value is not None:
                    setattr(self, key, value)

            self.path = source.path + self.path
            self.sequence = self.sequence or source.sequence
            self.choice = self.choice or source.choice
            self.tokens = self.tokens or source.tokens
            self.format = self.format or source.format
            self.group = self.group or source.group

            if self.min_occurs is None and source.min_occurs is not None:
                self.min_occurs = source.min_occurs

            if self.max_occurs is None and source.max_occurs is not None:
                self.max_occurs = source.max_occurs

        def asdict(self, types: list[type] | None = None) -> dict:
            """Return the initialized only properties as a dictionary.

            Skip None or implied values, and optionally use the
            attribute types to convert relevant options.

            Args:
                types: An optional list of attr python types

            Returns:
                A key-value of map of the attr restrictions for generation.
            """
            result = {}
            sorted_types = converter.sort_types(types) if types else []

            if self.is_list:
                if self.min_occurs is not None and self.min_occurs > 0:
                    result["min_occurs"] = self.min_occurs
                if self.max_occurs is not None and self.max_occurs < sys.maxsize:
                    result["max_occurs"] = self.max_occurs
            elif (
                self.min_occurs == self.max_occurs == 1
                and not self.nillable
                and not self.tokens
            ):
                result["required"] = True

            for key, value in asdict(self).items():
                if value is None or key in (
                    "choice",
                    "group",
                    "min_occurs",
                    "max_occurs",
                    "path",
                ):
                    continue

                if key == "process_contents" and value != "skip":
                    continue

                if key.endswith("clusive") and types:
                    value = converter.deserialize(value, sorted_types)

                result[key] = value

            return result

        @classmethod
        def from_element(cls, element: ElementBase) -> "Restrictions":
            """Static constructor from a xsd model.

            Args:
                element: A element base instance.

            Returns:
                The new restrictions instance
            """
            return cls(**element.get_restrictions())

#### `is_list` `property`

Return whether the max occurs larger than one.

#### `is_optional` `property`

Return whether the min occurs is zero.

#### `is_prohibited` `property`

Return whether the max occurs is zero.

#### `merge(source)`

Update properties from another instance.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`source` | `Restrictions` | The source instance to merge properties from | required

Source code in `xsdata/codegen/models.py`

    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

    def merge(self, source: "Restrictions") -> None:
        """Update properties from another instance.

        Args:
            source: The source instance to merge properties from
        """
        keys = (
            "min_exclusive",
            "min_inclusive",
            "min_length",
            "max_exclusive",
            "max_inclusive",
            "max_length",
            "total_digits",
            "fraction_digits",
            "length",
            "white_space",
            "pattern",
            "explicit_timezone",
            "process_contents",
        )

        for key in keys:
            value = getattr(source, key)
            if value is not None:
                setattr(self, key, value)

        self.path = source.path + self.path
        self.sequence = self.sequence or source.sequence
        self.choice = self.choice or source.choice
        self.tokens = self.tokens or source.tokens
        self.format = self.format or source.format
        self.group = self.group or source.group

        if self.min_occurs is None and source.min_occurs is not None:
            self.min_occurs = source.min_occurs

        if self.max_occurs is None and source.max_occurs is not None:
            self.max_occurs = source.max_occurs

#### `asdict(types=None)`

Return the initialized only properties as a dictionary.

Skip None or implied values, and optionally use the attribute types to convert relevant options.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`types` | `list[type] | None` | An optional list of attr python types | `None`

Returns:

Type | Description
--- | ---
`dict` | A key-value of map of the attr restrictions for generation.

Source code in `xsdata/codegen/models.py`

    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
    199
    200
    201
    202
    203
    204

    def asdict(self, types: list[type] | None = None) -> dict:
        """Return the initialized only properties as a dictionary.

        Skip None or implied values, and optionally use the
        attribute types to convert relevant options.

        Args:
            types: An optional list of attr python types

        Returns:
            A key-value of map of the attr restrictions for generation.
        """
        result = {}
        sorted_types = converter.sort_types(types) if types else []

        if self.is_list:
            if self.min_occurs is not None and self.min_occurs > 0:
                result["min_occurs"] = self.min_occurs
            if self.max_occurs is not None and self.max_occurs < sys.maxsize:
                result["max_occurs"] = self.max_occurs
        elif (
            self.min_occurs == self.max_occurs == 1
            and not self.nillable
            and not self.tokens
        ):
            result["required"] = True

        for key, value in asdict(self).items():
            if value is None or key in (
                "choice",
                "group",
                "min_occurs",
                "max_occurs",
                "path",
            ):
                continue

            if key == "process_contents" and value != "skip":
                continue

            if key.endswith("clusive") and types:
                value = converter.deserialize(value, sorted_types)

            result[key] = value

        return result

#### `from_element(element)` `classmethod`

Static constructor from a xsd model.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`element` | `ElementBase` | A element base instance. | required

Returns:

Type | Description
--- | ---
`Restrictions` | The new restrictions instance

Source code in `xsdata/codegen/models.py`

    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216

    @classmethod
    def from_element(cls, element: ElementBase) -> "Restrictions":
        """Static constructor from a xsd model.

        Args:
            element: A element base instance.

        Returns:
            The new restrictions instance
        """
        return cls(**element.get_restrictions())

### `AttrType` `dataclass`

Bases: `CodegenModel`

Class field typing information.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`qname` | `str` | The namespace qualified name | required
`alias` | `str | None` | The type alias | `None`
`reference` | `int` | The type reference number | `0`
`native` | `bool` | Specifies if it's python native type | `False`
`forward` | `bool` | Specifies if it's a forward reference | `False`
`circular` | `bool` | Specifies if it's a circular reference | `False`
`substituted` | `bool` | Specifies if it has been processed for substitution groups | `False`

Source code in `xsdata/codegen/models.py`

    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265

    @dataclass(unsafe_hash=True)
    class AttrType(CodegenModel):
        """Class field typing information.

        Args:
            qname: The namespace qualified name
            alias: The type alias
            reference: The type reference number
            native: Specifies if it's python native type
            forward: Specifies if it's a forward reference
            circular: Specifies if it's a circular reference
            substituted: Specifies if it has been processed for substitution groups
        """

        qname: str
        alias: str | None = field(default=None, compare=False)
        reference: int = field(default=0, compare=False)
        native: bool = field(default=False)
        forward: bool = field(default=False)
        circular: bool = field(default=False)
        substituted: bool = field(default=False, compare=False)

        @property
        def datatype(self) -> DataType | None:
            """Return the datatype instance if native, none otherwise."""
            return DataType.from_qname(self.qname) if self.native else None

        @property
        def name(self) -> str:
            """Shortcut for qname local name."""
            return namespaces.local_name(self.qname)

        def is_dependency(self, allow_circular: bool) -> bool:
            """Return whether this type is a dependency.

            The type must a reference to a user type, not a forward
            reference and not a circular unless if it's allowed.

            Args:
                allow_circular: Allow circular references as dependencies

            Returns:
                The bool result/
            """
            return not (
                self.forward or self.native or (not allow_circular and self.circular)
            )

#### `datatype` `property`

Return the datatype instance if native, none otherwise.

#### `name` `property`

Shortcut for qname local name.

#### `is_dependency(allow_circular)`

Return whether this type is a dependency.

The type must a reference to a user type, not a forward reference and not a circular unless if it's allowed.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`allow_circular` | `bool` | Allow circular references as dependencies | required

Returns:

Type | Description
--- | ---
`bool` | The bool result/

Source code in `xsdata/codegen/models.py`

    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265

    def is_dependency(self, allow_circular: bool) -> bool:
        """Return whether this type is a dependency.

        The type must a reference to a user type, not a forward
        reference and not a circular unless if it's allowed.

        Args:
            allow_circular: Allow circular references as dependencies

        Returns:
            The bool result/
        """
        return not (
            self.forward or self.native or (not allow_circular and self.circular)
        )

### `Attr` `dataclass`

Bases: `CodegenModel`

Class field model representation.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`tag` | `str` | The xml tag that produced this attr | required
`name` | `str` | The final attr name | required
`local_name` | `str` | The original attr name | `''`
`wrapper` | `str | None` | The wrapper element name | `None`
`index` | `int` | The index position of this attr in the class | `int()`
`default` | `str | None` | The default value | `None`
`fixed` | `bool` | Specifies if the default value is fixed | `False`
`mixed` | `bool` | Specifies if the attr supports mixed content | `False`
`types` | `list[AttrType]` | The attr types list | `list()`
`choices` | `list[Attr]` | The attr choice list | `list()`
`namespace` | `str | None` | The attr namespace | `None`
`help` | `str | None` | The attr help text | `None`
`restrictions` | `Restrictions` | The attr restrictions instance | `Restrictions()`
`parent` | `str | None` | The parent class qualified name of the attr | `None`
`substitution` | `str | None` | The substitution group this attr belongs to | `None`

Source code in `xsdata/codegen/models.py`

    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454

    @dataclass
    class Attr(CodegenModel):
        """Class field model representation.

        Args:
            tag: The xml tag that produced this attr
            name: The final attr name
            local_name: The original attr name
            wrapper: The wrapper element name
            index: The index position of this attr in the class
            default: The default value
            fixed: Specifies if the default value is fixed
            mixed: Specifies if the attr supports mixed content
            types: The attr types list
            choices: The attr choice list
            namespace: The attr namespace
            help: The attr help text
            restrictions: The attr restrictions instance
            parent: The parent class qualified name of the attr
            substitution: The substitution group this attr belongs to
        """

        tag: str
        name: str = field(compare=False)
        local_name: str = field(default="")
        wrapper: str | None = field(default=None)
        index: int = field(compare=False, default_factory=int)
        default: str | None = field(default=None, compare=False)
        fixed: bool = field(default=False, compare=False)
        mixed: bool = field(default=False, compare=False)
        types: list[AttrType] = field(default_factory=list, compare=False)
        choices: list["Attr"] = field(default_factory=list, compare=False)
        namespace: str | None = field(default=None)
        help: str | None = field(default=None, compare=False)
        restrictions: Restrictions = field(default_factory=Restrictions, compare=False)
        parent: str | None = field(default=None, compare=False)
        substitution: str | None = field(default=None, compare=False)

        def __post_init__(self):
            """Post init processing."""
            if not self.local_name:
                self.local_name = self.name

            if text.alnum(self.name) == "":
                self.name = "_".join(unicodedata.name(char) for char in self.name)

        @property
        def key(self) -> str:
            """Generate a key for this attr.

            Concatenate the tag/namespace/local_name.
            This key is used to find duplicates, it's not
            supposed to be unique.

            Returns:
                The unique key for this attr.

            """
            return f"{self.tag}.{self.namespace}.{self.local_name}"

        @property
        def qname(self) -> str:
            """Return the fully qualified name of the attr."""
            return namespaces.build_qname(self.namespace, self.local_name)

        @property
        def is_attribute(self) -> bool:
            """Return whether this attr represents a xml attribute node."""
            return self.tag in (Tag.ATTRIBUTE, Tag.ANY_ATTRIBUTE)

        @property
        def is_element(self) -> bool:
            """Return whether this attr represents a xml element."""
            return self.tag == Tag.ELEMENT

        @property
        def is_enumeration(self) -> bool:
            """Return whether this attr an enumeration member."""
            return self.tag == Tag.ENUMERATION

        @property
        def is_dict(self) -> bool:
            """Return whether this attr is derived from xs:anyAttribute."""
            return self.tag == Tag.ANY_ATTRIBUTE

        @property
        def is_factory(self) -> bool:
            """Return whether this attribute is a list of items or a mapping."""
            return self.is_list or self.is_dict or self.is_tokens

        @property
        def is_forward_ref(self) -> bool:
            """Return whether any attr types is a forward or circular reference."""
            return any(tp.circular or tp.forward for tp in self.types)

        @property
        def is_circular_ref(self) -> bool:
            """Return whether any attr types is a circular reference."""
            return any(tp.circular for tp in self.types)

        @property
        def is_group(self) -> bool:
            """Return whether this attr is a reference to a group class."""
            return self.tag in (Tag.ATTRIBUTE_GROUP, Tag.GROUP)

        @property
        def is_list(self) -> bool:
            """Return whether this attr requires a list of values."""
            return self.restrictions.is_list

        @property
        def is_prohibited(self) -> bool:
            """Return whether this attr is prohibited."""
            return self.restrictions.is_prohibited

        @property
        def is_nameless(self) -> bool:
            """Return whether this attr is a real xml node."""
            return self.tag not in (Tag.ATTRIBUTE, Tag.ELEMENT)

        @property
        def is_nillable(self) -> bool:
            """Return whether this attr supports nil values."""
            return self.restrictions.nillable is True

        @property
        def is_optional(self) -> bool:
            """Return whether this attr is not required."""
            return self.restrictions.is_optional

        @property
        def is_suffix(self) -> bool:
            """Return whether this attr is supposed to be generated last."""
            return self.index == sys.maxsize

        @property
        def is_xsi_type(self) -> bool:
            """Return whether this attr represents a xsi:type attribute."""
            return self.namespace == Namespace.XSI.uri and self.name == "type"

        @property
        def is_tokens(self) -> bool:
            """Return whether this attr supports token values."""
            return self.restrictions.tokens is True

        @property
        def is_wildcard(self) -> bool:
            """Return whether this attr supports any content."""
            return self.tag in (Tag.ANY_ATTRIBUTE, Tag.ANY)

        @property
        def is_any_type(self) -> bool:
            """Return whether this attr types support any content."""
            return any(tp is object for tp in self.get_native_types())

        @property
        def native_types(self) -> list[type]:
            """Return a list of all the builtin data types."""
            return list(set(self.get_native_types()))

        @property
        def user_types(self) -> Iterator[AttrType]:
            """Yield an iterator of all the user defined types."""
            for tp in self.types:
                if not tp.native:
                    yield tp

        @property
        def slug(self) -> str:
            """Return the slugified name of the attr."""
            return text.alnum(self.name)

        @property
        def xml_type(self) -> str | None:
            """Return the xml type this attribute is mapped to."""
            return xml_type_map.get(self.tag)

        def get_native_types(self) -> Iterator[type]:
            """Yield an iterator of all the native attr types."""
            for tp in self.types:
                datatype = tp.datatype
                if datatype:
                    yield datatype.type

        def can_be_restricted(self) -> bool:
            """Return whether this attr can be restricted."""
            return self.xml_type not in (Tag.ATTRIBUTE, None)

#### `key` `property`

Generate a key for this attr.

Concatenate the tag/namespace/local_name. This key is used to find duplicates, it's not supposed to be unique.

Returns:

Type | Description
--- | ---
`str` | The unique key for this attr.

#### `qname` `property`

Return the fully qualified name of the attr.

#### `is_attribute` `property`

Return whether this attr represents a xml attribute node.

#### `is_element` `property`

Return whether this attr represents a xml element.

#### `is_enumeration` `property`

Return whether this attr an enumeration member.

#### `is_dict` `property`

Return whether this attr is derived from xs:anyAttribute.

#### `is_factory` `property`

Return whether this attribute is a list of items or a mapping.

#### `is_forward_ref` `property`

Return whether any attr types is a forward or circular reference.

#### `is_circular_ref` `property`

Return whether any attr types is a circular reference.

#### `is_group` `property`

Return whether this attr is a reference to a group class.

#### `is_list` `property`

Return whether this attr requires a list of values.

#### `is_prohibited` `property`

Return whether this attr is prohibited.

#### `is_nameless` `property`

Return whether this attr is a real xml node.

#### `is_nillable` `property`

Return whether this attr supports nil values.

#### `is_optional` `property`

Return whether this attr is not required.

#### `is_suffix` `property`

Return whether this attr is supposed to be generated last.

#### `is_xsi_type` `property`

Return whether this attr represents a xsi:type attribute.

#### `is_tokens` `property`

Return whether this attr supports token values.

#### `is_wildcard` `property`

Return whether this attr supports any content.

#### `is_any_type` `property`

Return whether this attr types support any content.

#### `native_types` `property`

Return a list of all the builtin data types.

#### `user_types` `property`

Yield an iterator of all the user defined types.

#### `slug` `property`

Return the slugified name of the attr.

#### `xml_type` `property`

Return the xml type this attribute is mapped to.

#### `__post_init__()`

Post init processing.

Source code in `xsdata/codegen/models.py`

    306
    307
    308
    309
    310
    311
    312

    def __post_init__(self):
        """Post init processing."""
        if not self.local_name:
            self.local_name = self.name

        if text.alnum(self.name) == "":
            self.name = "_".join(unicodedata.name(char) for char in self.name)

#### `get_native_types()`

Yield an iterator of all the native attr types.

Source code in `xsdata/codegen/models.py`

    445
    446
    447
    448
    449
    450

    def get_native_types(self) -> Iterator[type]:
        """Yield an iterator of all the native attr types."""
        for tp in self.types:
            datatype = tp.datatype
            if datatype:
                yield datatype.type

#### `can_be_restricted()`

Return whether this attr can be restricted.

Source code in `xsdata/codegen/models.py`

    452
    453
    454

    def can_be_restricted(self) -> bool:
        """Return whether this attr can be restricted."""
        return self.xml_type not in (Tag.ATTRIBUTE, None)

### `Extension` `dataclass`

Bases: `CodegenModel`

Base class model representation.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`tag` | `str` | The xml tag that produced this extension | required
`type` | `AttrType` | The extension type | required
`restrictions` | `Restrictions` | The extension restrictions instance | required

Source code in `xsdata/codegen/models.py`

    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469

    @dataclass(unsafe_hash=True)
    class Extension(CodegenModel):
        """Base class model representation.

        Args:
            tag: The xml tag that produced this extension
            type: The extension type
            restrictions: The extension restrictions instance
        """

        tag: str
        type: AttrType
        restrictions: Restrictions = field(hash=False)

### `Status`

Bases: `IntEnum`

Class process status enumeration.

Source code in `xsdata/codegen/models.py`

    472
    473
    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    484
    485
    486
    487

    class Status(IntEnum):
        """Class process status enumeration."""

        RAW = 0
        UNGROUPING = 10
        UNGROUPED = 11
        FLATTENING = 20
        FLATTENED = 21
        SANITIZING = 30
        SANITIZED = 31
        RESOLVING = 40
        RESOLVED = 41
        CLEANING = 50
        CLEANED = 51
        FINALIZING = 60
        FINALIZED = 61

### `Class` `dataclass`

Bases: `CodegenModel`

Class model representation.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`qname` | `str` | The namespace qualified name | required
`tag` | `str` | The xml tag that produced this class | required
`location` | `str` | The schema/document location uri | required
`mixed` | `bool` | Specifies whether this class supports mixed content | `False`
`abstract` | `bool` | Specifies whether this is an abstract class | `False`
`nillable` | `bool` | Specifies whether this class supports nil content | `False`
`local_type` | `bool` | Specifies if this class was an inner type at some point | `False`
`status` | `Status` | The processing status of the class | `RAW`
`container` | `str | None` | The xml container of the class, schema, override, redefine | `None`
`package` | `str | None` | The designated package of the class | `None`
`module` | `str | None` | The designated module of the class | `None`
`namespace` | `str | None` | The class namespace | `None`
`help` | `str | None` | The help text | `None`
`meta_name` | `str | None` | The xml element name of the class | `None`
`default` | `Any` | The default value | `None`
`fixed` | `bool` | Specifies whether the default value is fixed | `False`
`substitutions` | `list[str]` | The list of all the substitution groups this class belongs to | `list()`
`extensions` | `list[Extension]` | The list of all the extension instances | `list()`
`attrs` | `list[Attr]` | The list of all the attr instances | `list()`
`inner` | `list[Class]` | The list of all the inner class instances | `list()`
`ns_map` | `dict` | The namespace prefix-URI map | `dict()`
`parent` | `Optional[Class]` | The parent outer class | `None`

Source code in `xsdata/codegen/models.py`

    490
    491
    492
    493
    494
    495
    496
    497
    498
    499
    500
    501
    502
    503
    504
    505
    506
    507
    508
    509
    510
    511
    512
    513
    514
    515
    516
    517
    518
    519
    520
    521
    522
    523
    524
    525
    526
    527
    528
    529
    530
    531
    532
    533
    534
    535
    536
    537
    538
    539
    540
    541
    542
    543
    544
    545
    546
    547
    548
    549
    550
    551
    552
    553
    554
    555
    556
    557
    558
    559
    560
    561
    562
    563
    564
    565
    566
    567
    568
    569
    570
    571
    572
    573
    574
    575
    576
    577
    578
    579
    580
    581
    582
    583
    584
    585
    586
    587
    588
    589
    590
    591
    592
    593
    594
    595
    596
    597
    598
    599
    600
    601
    602
    603
    604
    605
    606
    607
    608
    609
    610
    611
    612
    613
    614
    615
    616
    617
    618
    619
    620
    621
    622
    623
    624
    625
    626
    627
    628
    629
    630
    631
    632
    633
    634
    635
    636
    637
    638
    639
    640
    641
    642
    643
    644
    645
    646
    647
    648
    649
    650
    651
    652
    653
    654
    655
    656
    657
    658
    659
    660
    661
    662
    663
    664
    665
    666
    667
    668
    669
    670
    671
    672
    673
    674
    675
    676
    677
    678
    679
    680
    681
    682
    683
    684
    685
    686
    687
    688
    689
    690
    691
    692
    693
    694
    695
    696
    697
    698
    699
    700
    701
    702
    703
    704
    705
    706
    707
    708
    709
    710
    711
    712
    713
    714
    715
    716
    717
    718
    719
    720
    721
    722
    723
    724

    @dataclass
    class Class(CodegenModel):
        """Class model representation.

        Args:
            qname: The namespace qualified name
            tag: The xml tag that produced this class
            location: The schema/document location uri
            mixed: Specifies whether this class supports mixed content
            abstract: Specifies whether this is an abstract class
            nillable: Specifies whether this class supports nil content
            local_type: Specifies if this class was an inner type at some point
            status: The processing status of the class
            container: The xml container of the class, schema, override, redefine
            package: The designated package of the class
            module: The designated module of the class
            namespace: The class namespace
            help: The help text
            meta_name: The xml element name of the class
            default: The default value
            fixed: Specifies whether the default value is fixed
            substitutions: The list of all the substitution groups this class belongs to
            extensions: The list of all the extension instances
            attrs: The list of all the attr instances
            inner: The list of all the inner class instances
            ns_map: The namespace prefix-URI map
            parent: The parent outer class
        """

        qname: str
        tag: str
        location: str = field(compare=False)
        mixed: bool = field(default=False)
        abstract: bool = field(default=False)
        nillable: bool = field(default=False)
        local_type: bool = field(default=False)
        status: Status = field(default=Status.RAW)
        container: str | None = field(default=None)
        package: str | None = field(default=None)
        module: str | None = field(default=None)
        namespace: str | None = field(default=None)
        help: str | None = field(default=None)
        meta_name: str | None = field(default=None)
        default: Any = field(default=None, compare=False)
        fixed: bool = field(default=False, compare=False)
        substitutions: list[str] = field(default_factory=list)
        extensions: list[Extension] = field(default_factory=list)
        attrs: list[Attr] = field(default_factory=list)
        inner: list["Class"] = field(default_factory=list)
        ns_map: dict = field(default_factory=dict)
        parent: Optional["Class"] = field(default=None, compare=False)

        @property
        def name(self) -> str:
            """Shortcut for the class local name."""
            return namespaces.local_name(self.qname)

        @property
        def slug(self) -> str:
            """Return a slugified version of the class name."""
            return text.alnum(self.name)

        @property
        def ref(self) -> int:
            """Return this id reference of this instance."""
            return id(self)

        @property
        def target_namespace(self) -> str | None:
            """Return the class target namespace."""
            return namespaces.target_uri(self.qname)

        @property
        def has_suffix_attr(self) -> bool:
            """Return whether it includes a suffix attr."""
            return any(attr.is_suffix for attr in self.attrs)

        @property
        def has_help_attr(self) -> bool:
            """Return whether at least one of attrs has help content."""
            return any(attr.help and attr.help.strip() for attr in self.attrs)

        @property
        def is_element(self) -> bool:
            """Return whether this class represents a xml element."""
            return self.tag == Tag.ELEMENT

        @property
        def is_enumeration(self) -> bool:
            """Return whether all attrs are enumeration members."""
            return len(self.attrs) > 0 and all(attr.is_enumeration for attr in self.attrs)

        @property
        def is_complex_type(self) -> bool:
            """Return whether this class represents a root/global class.

            Global classes are the only classes that get generated by default.
            """
            return self.tag in GLOBAL_TYPES

        @property
        def is_group(self) -> bool:
            """Return whether this class is derived from a xs:group/attributeGroup."""
            return self.tag in (Tag.ATTRIBUTE_GROUP, Tag.GROUP)

        @property
        def is_nillable(self) -> bool:
            """Return whether this class represents a nillable xml element."""
            return self.nillable or any(x.restrictions.nillable for x in self.extensions)

        @property
        def is_mixed(self) -> bool:
            """Return whether this class supports mixed content."""
            return self.mixed or any(x.mixed for x in self.attrs)

        @property
        def is_restricted(self) -> bool:
            """Return whether this class includes any restriction extensions."""
            return any(
                True for extension in self.extensions if extension.tag == Tag.RESTRICTION
            )

        @property
        def is_service(self) -> bool:
            """Return whether this instance is derived from a wsdl:operation."""
            return self.tag == Tag.BINDING_OPERATION

        @property
        def references(self) -> Iterator[int]:
            """Yield all class object reference numbers."""
            for tp in self.types():
                if tp.reference:
                    yield tp.reference

        @property
        def target_module(self) -> str:
            """Return the designated full module path.

            Raises:
                CodeGenerationError: if the target was not designated
                    a package and module.
            """
            if self.package and self.module:
                return f"{self.package}.{self.module}"

            if self.module:
                return self.module

            raise CodegenError(
                "Type has not been assigned to a module yet!", type=self.qname
            )

        def dependencies(self, allow_circular: bool = False) -> Iterator[str]:
            """Yields all class dependencies.

            Omit circular and forward references by default.

            Collect:
                * base classes
                * attribute types
                * attribute choice types
                * recursively go through the inner classes
                * Ignore inner class references
                * Ignore native types.

            Args:
                allow_circular: Allow circular references
            """
            for tp in set(self.types()):
                if tp.is_dependency(allow_circular=allow_circular):
                    yield tp.qname

        def types(self) -> Iterator[AttrType]:
            """Yields all class types."""
            for _, tp in self.types_with_parents():
                yield tp

        def types_with_parents(self) -> Iterator[tuple[CodegenModel, AttrType]]:
            """Yields all class types with their parent codegen instance."""
            for ext in self.extensions:
                yield ext, ext.type

            for attr in self.attrs:
                for tp in attr.types:
                    yield attr, tp

                for choice in attr.choices:
                    for tp in choice.types:
                        yield choice, tp

            for inner in self.inner:
                yield from inner.types_with_parents()

        def children(self) -> Iterator[CodegenModel]:
            """Yield all codegen children."""
            for attr in self.attrs:
                yield attr
                yield attr.restrictions

                yield from attr.types

                for choice in attr.choices:
                    yield choice
                    yield choice.restrictions

                    yield from choice.types

            for ext in self.extensions:
                yield ext
                yield ext.type
                yield ext.restrictions

            for inner in self.inner:
                yield from inner.children()

        def has_forward_ref(self) -> bool:
            """Return whether this class has any forward references."""
            for attr in self.attrs:
                if attr.is_forward_ref:
                    return True

                if any(choice for choice in attr.choices if choice.is_forward_ref):
                    return True

            return any(inner.has_forward_ref() for inner in self.inner)

        def parent_names(self) -> list[str]:
            """Return the outer class names."""
            result = []
            target = self.parent
            while target is not None:
                result.append(target.name)
                target = target.parent

            return list(reversed(result))

#### `name` `property`

Shortcut for the class local name.

#### `slug` `property`

Return a slugified version of the class name.

#### `ref` `property`

Return this id reference of this instance.

#### `target_namespace` `property`

Return the class target namespace.

#### `has_suffix_attr` `property`

Return whether it includes a suffix attr.

#### `has_help_attr` `property`

Return whether at least one of attrs has help content.

#### `is_element` `property`

Return whether this class represents a xml element.

#### `is_enumeration` `property`

Return whether all attrs are enumeration members.

#### `is_complex_type` `property`

Return whether this class represents a root/global class.

Global classes are the only classes that get generated by default.

#### `is_group` `property`

Return whether this class is derived from a xs:group/attributeGroup.

#### `is_nillable` `property`

Return whether this class represents a nillable xml element.

#### `is_mixed` `property`

Return whether this class supports mixed content.

#### `is_restricted` `property`

Return whether this class includes any restriction extensions.

#### `is_service` `property`

Return whether this instance is derived from a wsdl:operation.

#### `references` `property`

Yield all class object reference numbers.

#### `target_module` `property`

Return the designated full module path.

Raises:

Type | Description
--- | ---
`CodeGenerationError` | if the target was not designated a package and module.

#### `dependencies(allow_circular=False)`

Yields all class dependencies.

Omit circular and forward references by default.

Collect

- base classes
- attribute types
- attribute choice types
- recursively go through the inner classes
- Ignore inner class references
- Ignore native types.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`allow_circular` | `bool` | Allow circular references | `False`

Source code in `xsdata/codegen/models.py`

    642
    643
    644
    645
    646
    647
    648
    649
    650
    651
    652
    653
    654
    655
    656
    657
    658
    659
    660

    def dependencies(self, allow_circular: bool = False) -> Iterator[str]:
        """Yields all class dependencies.

        Omit circular and forward references by default.

        Collect:
            * base classes
            * attribute types
            * attribute choice types
            * recursively go through the inner classes
            * Ignore inner class references
            * Ignore native types.

        Args:
            allow_circular: Allow circular references
        """
        for tp in set(self.types()):
            if tp.is_dependency(allow_circular=allow_circular):
                yield tp.qname

#### `types()`

Yields all class types.

Source code in `xsdata/codegen/models.py`

    662
    663
    664
    665

    def types(self) -> Iterator[AttrType]:
        """Yields all class types."""
        for _, tp in self.types_with_parents():
            yield tp

#### `types_with_parents()`

Yields all class types with their parent codegen instance.

Source code in `xsdata/codegen/models.py`

    667
    668
    669
    670
    671
    672
    673
    674
    675
    676
    677
    678
    679
    680
    681

    def types_with_parents(self) -> Iterator[tuple[CodegenModel, AttrType]]:
        """Yields all class types with their parent codegen instance."""
        for ext in self.extensions:
            yield ext, ext.type

        for attr in self.attrs:
            for tp in attr.types:
                yield attr, tp

            for choice in attr.choices:
                for tp in choice.types:
                    yield choice, tp

        for inner in self.inner:
            yield from inner.types_with_parents()

#### `children()`

Yield all codegen children.

Source code in `xsdata/codegen/models.py`

    683
    684
    685
    686
    687
    688
    689
    690
    691
    692
    693
    694
    695
    696
    697
    698
    699
    700
    701
    702
    703

    def children(self) -> Iterator[CodegenModel]:
        """Yield all codegen children."""
        for attr in self.attrs:
            yield attr
            yield attr.restrictions

            yield from attr.types

            for choice in attr.choices:
                yield choice
                yield choice.restrictions

                yield from choice.types

        for ext in self.extensions:
            yield ext
            yield ext.type
            yield ext.restrictions

        for inner in self.inner:
            yield from inner.children()

#### `has_forward_ref()`

Return whether this class has any forward references.

Source code in `xsdata/codegen/models.py`

    705
    706
    707
    708
    709
    710
    711
    712
    713
    714

    def has_forward_ref(self) -> bool:
        """Return whether this class has any forward references."""
        for attr in self.attrs:
            if attr.is_forward_ref:
                return True

            if any(choice for choice in attr.choices if choice.is_forward_ref):
                return True

        return any(inner.has_forward_ref() for inner in self.inner)

#### `parent_names()`

Return the outer class names.

Source code in `xsdata/codegen/models.py`

    716
    717
    718
    719
    720
    721
    722
    723
    724

    def parent_names(self) -> list[str]:
        """Return the outer class names."""
        result = []
        target = self.parent
        while target is not None:
            result.append(target.name)
            target = target.parent

        return list(reversed(result))

### `Import` `dataclass`

Python import statement model representation.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`qname` | `str` | The qualified name of the imported class | required
`source` | `str` | The absolute module path | required
`alias` | `str | None` | Specifies an alias to avoid naming conflicts | `None`

Source code in `xsdata/codegen/models.py`

    727
    728
    729
    730
    731
    732
    733
    734
    735
    736
    737
    738
    739
    740
    741
    742
    743
    744
    745
    746
    747
    748
    749

    @dataclass
    class Import:
        """Python import statement model representation.

        Args:
            qname: The qualified name of the imported class
            source: The absolute module path
            alias: Specifies an alias to avoid naming conflicts
        """

        qname: str
        source: str
        alias: str | None = field(default=None)

        @property
        def name(self) -> str:
            """Return the name of the imported class."""
            return namespaces.local_name(self.qname)

        @property
        def slug(self) -> str:
            """Return a slugified version of the imported class name."""
            return text.alnum(self.name)

#### `name` `property`

Return the name of the imported class.

#### `slug` `property`

Return a slugified version of the imported class name.