pydantic-xml
pydantic-xml copied to clipboard
Submodels instantiated as XmlEntityInfo instead of XmlModelMeta
Hi I'm migrating a library from pydantic_xml 0.6 to the most recent version. I see that the subclasses are instantiated with different logic compared to the older version. Indeed running this script with different pydantic_xml version return different results. here the code:
from typing import List, Optional
from pydantic_xml import BaseXmlModel, element, attr
import pkg_resources
ver = pkg_resources.get_distribution("pydantic-xml").version
class Product(BaseXmlModel):
launched: Optional[int] = attr(default=None)
class Company(BaseXmlModel):
products: List[Product] = element(tag='products')
company_name: str = element(tag='company_name')
print(type(Company))
print(type(Product))
if ver == '0.6.0': #adaptation according to new api
print(type(getattr(Company.__fields__['products'], 'type_')))
print(type(getattr(Company.__fields__['company_name'], 'type_')))
else:
print(type(Company.model_fields['products']))
print(type(Company.model_fields['company_name']))
output with version 0.6.0
<class 'pydantic_xml.model.XmlModelMeta'>
<class 'pydantic_xml.model.XmlModelMeta'>
<class 'pydantic_xml.model.XmlModelMeta'># the subclass for products is an XmlModelMeta, therefore is not a standard subfield
<class 'type'>
output with version 2.10.0
<class 'pydantic_xml.model.XmlModelMeta'>
<class 'pydantic_xml.model.XmlModelMeta'>
<class 'pydantic_xml.model.XmlEntityInfo'># the submodel is not navigable anymore because is instantiated as XmlEntityInfo
<class 'pydantic_xml.model.XmlEntityInfo'>
Could this issue be a bug? How can I distinguish between a basic type that has no inner fields and a submodel that includes fields?
@RiccardoNizzolo Hi,
That is breaking change in pydantic
itself, not pydantic-xml
. Starting from pydantic 2.0 it is not possible to get the field type from __fields__
map anymore.
If you want to analyze fields by yourself, you should analyze pydantic core schema:
>>> pprint(Company.__pydantic_core_schema__)
{'cls': <class '__main__.Company'>,
'config': {'title': 'Company'},
'custom_init': False,
'metadata': {...},
'ref': '__main__.Company:140461506687856',
'root_model': False,
'schema': {'computed_fields': [],
'fields': {'company_name': {'metadata': ...,
'schema': {'type': 'str'},
'type': 'model-field'},
'products': {'metadata': ...,
'schema': {'items_schema': {'cls': <class '__main__.Product'>,
'config': {'title': 'Product'},
'custom_init': False,
'metadata': ...,
'ref': '__main__.Product:140461504455808',
'root_model': False,
'schema': ...,
'type': 'model'},
'type': 'list'},
'type': 'model-field'}},
'model_name': 'Company',
'type': 'model-fields'},
'type': 'model'}
as you can see schema->fields->company_name->schema->type
is str, schema->fields->products->schema->items_schema->type
is model.
You can find more information here.