-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Closed
Labels
bugSomething isn't workingSomething isn't working
Description
Initial Checks
- I confirm that I'm using the latest version of Pydantic AI
- I confirm that I searched for my issue in https://github.com/pydantic/pydantic-ai/issues before opening this issue
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 workingSomething isn't working