Union types#
To declare a field that can be of one type or anther typing.Union
is used.
It works for primitive types and models as well but not combined together.
Primitive types#
Union can be applied to text, attributes or elements. The type declaration order matters since the first type matched wins.
Model
class Message(BaseXmlModel, tag='Message'):
timestamp: Union[float, dt.datetime] = attr()
text: Optional[str]
class Messages(BaseXmlModel):
messages: List[Message]
Document
<Messages>
<Message timestamp="1674995230.295639">hello world</Message>
<Message timestamp="2023-01-29T17:30:38.762166"/>
</Messages>
{
"messages": [
{
"timestamp": 1674995230.295639,
"text": "hello world"
},
{
"timestamp": "2023-01-29T17:30:38.762166"
}
]
}
Model types#
Union can be applied to model types either. The type declaration order matters since the first model matched wins.
Model
class Event(BaseXmlModel):
timestamp: float = attr()
class KeyboardEvent(Event, tag='keyboard'):
type: str = attr()
key: str = element()
class MouseEvent(Event, tag='mouse'):
position: Dict[str, int] = element()
class Log(BaseXmlModel, tag='log'):
events: List[Union[KeyboardEvent, MouseEvent]]
Document
<log>
<mouse timestamp="1674999183.5486422">
<position x="234" y="345"/>
</mouse>
<keyboard timestamp="1674999184.227246"
type="KEYDOWN">
<key>CTRL</key>
</keyboard>
<keyboard timestamp="1674999185.6342669"
type="KEYDOWN">
<key>C</key>
</keyboard>
<mouse timestamp="1674999186.270716">
<position x="236" y="211"/>
</mouse>
</log>
{
"events": [
{
"timestamp": 1674999183.5486422,
"position": {"x": 234, "y": 345}
},
{
"timestamp": 1674999184.227246,
"type": "KEYDOWN",
"key": "CTRL"
},
{
"timestamp": 1674999185.6342669,
"type": "KEYDOWN",
"key": "C"
},
{
"timestamp": 1674999186.270716,
"position": {"x": 236, "y": 211}
}
]
}