dapper91 / pydantic-xml

python xml for humans
https://pydantic-xml.readthedocs.io
The Unlicense
141 stars 14 forks source link

type dict raises pydantic_xml.errors.ModelError: type any is not supported #198

Closed koeppe-at-pdtec closed 6 days ago

koeppe-at-pdtec commented 1 week ago

First of all thanks for providing this piece of software.

I like to compute a field after serialization from other fields:

It fails to use the type dict, but runs at least for the serialisation from xml. Is this intentional or am I on the wrong path?

here is a minimum example:

import json

from pydantic import StringConstraints, computed_field
from pydantic_xml import BaseXmlModel
from typing_extensions import Annotated

value = '<Data>{"abc":123}</Data>'

class Data(BaseXmlModel, tag="Data"):
    value: Annotated[str, StringConstraints(strip_whitespace=True)]

    @computed_field
    @property
    # def value_dict(self) -> str:  # runs with correct warning
    def value_dict(self) -> dict:  # fails
        return json.loads(self.value)

data = Data.from_xml(value)
print(data.model_dump())
dapper91 commented 1 week ago

@koeppe-at-pdtec Hi,

The problem is that dict type is dict[Any, Any] under the hood, which is not supported by the pydantic-xml. Try to define key and value types of the dict like this:

import json

from pydantic import StringConstraints, computed_field
from pydantic_xml import BaseXmlModel
from typing_extensions import Annotated

value = '<Data>{"abc":123}</Data>'

class Data(BaseXmlModel, tag="Data"):
    value: Annotated[str, StringConstraints(strip_whitespace=True)]

    @computed_field
    @property
    def value_dict(self) -> dict[str, int]:
        return json.loads(self.value)

data = Data.from_xml(value)
print(data.model_dump())
koeppe-at-pdtec commented 1 week ago

Thanks for quick response. This totally makes sense. Works perfectly.