Skip to content

enum.Enum is an unsupported type for XML formatting in (format_as_xml) #3058

@RootLUG

Description

@RootLUG

Initial Checks

Description

Hello,
when trying to serialize the pydantic/dataclass model to xml via format_as_xml function, an error is thrown if the model contains a field of type enum.Enum. This data type is common in dataclasses for better control over the field values. It is also already supported all the other places such as outputs so there is a reasonable expectationt that the format_as_xml should support serializing native enum values as well. This fails for both pydantic BaseModel and dataclasses decorators

self = _ToXml(data=MyDataclass(attr=<SampleEnum.XYZ: 'ABC'>), item_tag='item', none_str='null', include_field_info=False, _fields_info={}, _included_fields=set(), _element_names={'': 'MyDataclass'}, _is_info_extracted=True)
value = <SampleEnum.XYZ: 'ABC'>, path = 'attr', tag = 'attr'

    def _to_xml(self, value: Any, path: str, tag: str | None = None) -> ElementTree.Element:
        element = self._create_element(self.item_tag if tag is None else tag, path)
        if value is None:
            element.text = self.none_str
        elif isinstance(value, str):
            element.text = value
        elif isinstance(value, bytes | bytearray):
            element.text = value.decode(errors='ignore')
        elif isinstance(value, bool | int | float):
            element.text = str(value)
        elif isinstance(value, date):
            element.text = value.isoformat()
        elif isinstance(value, Mapping):
            if tag is None and path in self._element_names:
                element.tag = self._element_names[path]
            self._mapping_to_xml(element, value, path)  # pyright: ignore[reportUnknownArgumentType]
        elif is_dataclass(value) and not isinstance(value, type):
            self._init_structure_info()
            if tag is None:
                element.tag = value.__class__.__name__
            self._mapping_to_xml(element, asdict(value), path)
        elif isinstance(value, BaseModel):
            self._init_structure_info()
            if tag is None:
                element.tag = value.__class__.__name__
            # by dumping the model we loose all metadata in nested data structures,
            # but we have collected it when called _init_structure_info
            self._mapping_to_xml(element, value.model_dump(), path)
        elif isinstance(value, Iterable):
            for n, item in enumerate(value):  # pyright: ignore[reportUnknownVariableType,reportUnknownArgumentType]
                element.append(self._to_xml(value=item, path=f'{path}.[{n}]' if path else f'[{n}]'))
        else:
>           raise TypeError(f'Unsupported type for XML formatting: {type(value)}')
E           TypeError: Unsupported type for XML formatting: <enum 'SampleEnum'>

.venv\Lib\site-packages\pydantic_ai\format_prompt.py:128: TypeError

Example Code

import enum

import pytest
from pydantic import dataclasses, BaseModel
from pydantic_ai import format_as_xml


class SampleEnum(enum.Enum):
    XYZ = "ABC"


class MyDataclass(BaseModel):
    attr: SampleEnum


@pytest.mark.xfail
def test_xml_enum():
    obj = MyDataclass(attr=SampleEnum.XYZ)
    output = format_as_xml(obj)  # Fails here
    assert isinstance(output, str)

Python, Pydantic AI & LLM client version

pydantic-ai==1.0.12

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions