From a6d40e64899991d303885825af9b8dcd37b160a5 Mon Sep 17 00:00:00 2001 From: Dmitry Pershin Date: Fri, 23 Jun 2023 20:08:26 +0500 Subject: [PATCH] from_xml, from_xml_tree methods typing fixed. --- pydantic_xml/model.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/pydantic_xml/model.py b/pydantic_xml/model.py index d76a025..07557b3 100644 --- a/pydantic_xml/model.py +++ b/pydantic_xml/model.py @@ -1,5 +1,6 @@ import functools as ft -from typing import Any, Callable, ClassVar, Dict, Optional, Tuple, Type, Union +import typing +from typing import Any, Callable, ClassVar, Dict, Optional, Tuple, Type, TypeVar, Union import pydantic as pd import pydantic.fields @@ -203,6 +204,9 @@ def _merge_configs(mcls, bases: Tuple[type], namespace: Dict[str, Any]) -> None: setattr(self_config, 'xml_encoders', xml_encoders) +ModelT = TypeVar('ModelT', bound='BaseXmlModel') + + class BaseXmlModel(pd.BaseModel, metaclass=XmlModelMeta): """ Base pydantic-xml model. @@ -268,7 +272,7 @@ def update_forward_refs(cls, **kwargs: Any) -> None: cls.__xml_serializer__.resolve_forward_refs() @classmethod - def from_xml_tree(cls, root: etree.Element) -> Optional['BaseXmlModel']: + def from_xml_tree(cls: Type[ModelT], root: etree.Element) -> ModelT: """ Deserializes an xml element tree to an object of `cls` type. @@ -279,7 +283,7 @@ def from_xml_tree(cls, root: etree.Element) -> Optional['BaseXmlModel']: assert cls.__xml_serializer__ is not None, f"model {cls.__name__} is partially initialized" if root.tag == cls.__xml_serializer__.element_name: - obj = cls.__xml_serializer__.deserialize(XmlElement.from_native(root)) + obj = typing.cast(ModelT, cls.__xml_serializer__.deserialize(XmlElement.from_native(root))) return obj else: raise errors.ParsingError( @@ -287,7 +291,7 @@ def from_xml_tree(cls, root: etree.Element) -> Optional['BaseXmlModel']: ) @classmethod - def from_xml(cls, source: Union[str, bytes]) -> Optional['BaseXmlModel']: + def from_xml(cls: Type[ModelT], source: Union[str, bytes]) -> ModelT: """ Deserializes an xml string to an object of `cls` type. @@ -339,6 +343,9 @@ def to_xml( return etree.tostring(self.to_xml_tree(encoder=encoder, skip_empty=skip_empty), **kwargs) +GenericModelT = TypeVar('GenericModelT', bound='BaseGenericXmlModel') + + class BaseGenericXmlModel(BaseXmlModel, pd.generics.GenericModel): """ Base pydantic-xml generic model. @@ -364,7 +371,7 @@ def __init_serializer__(cls) -> None: super().__init_serializer__() @classmethod - def from_xml_tree(cls, root: etree.Element) -> Optional['BaseXmlModel']: + def from_xml_tree(cls: Type[GenericModelT], root: etree.Element) -> GenericModelT: """ Deserializes an xml element tree to an object of `cls` type.