# Released under the MIT License. See LICENSE for details.#"""Functionality for sending and responding to messages.Supports static typing for message types and possible return types."""from__future__importannotationsfromtypingimportTYPE_CHECKING,AnnotatedfromdataclassesimportdataclassfromenumimportEnumfromefro.dataclassioimportioprepped,IOAttrsifTYPE_CHECKING:passclassUnregisteredMessageIDError(Exception):"""A message or response id is not covered by our protocol."""classMessage:"""Base class for messages."""
[docs]@classmethoddefget_response_types(cls)->list[type[Response]|None]:"""Return all Response types this Message can return when sent. The default implementation specifies a None return type. """return[None]
classResponse:"""Base class for responses to messages."""classSysResponse:"""Base class for system-responses to messages. These are only sent/handled by the messaging system itself; users of the api never see them. """
[docs]defset_local_exception(self,exc:Exception)->None:"""Attach a local exception to facilitate better logging/handling. Be aware that this data does not get serialized and only exists on the local object. """setattr(self,'_sr_local_exception',exc)
[docs]defget_local_exception(self)->Exception|None:"""Fetch a local attached exception."""value=getattr(self,'_sr_local_exception',None)assertisinstance(value,Exception|None)returnvalue
# Some standard response types:@ioprepped@dataclassclassErrorSysResponse(SysResponse):"""SysResponse saying some error has occurred for the send. This generally results in an Exception being raised for the caller. """
[docs]classErrorType(Enum):"""Type of error that occurred while sending a message."""REMOTE=0REMOTE_CLEAN=1LOCAL=2COMMUNICATION=3REMOTE_COMMUNICATION=4
error_message:Annotated[str,IOAttrs('m')]error_type:Annotated[ErrorType,IOAttrs('e')]=ErrorType.REMOTE@ioprepped@dataclassclassEmptySysResponse(SysResponse):"""The response equivalent of None."""# TODO: could allow handlers to deal in raw values for these# types similar to how we allow None in place of EmptySysResponse.# Though not sure if they are widely used enough to warrant the# extra code complexity.@ioprepped@dataclassclassBoolResponse(Response):"""A simple bool value response."""value:Annotated[bool,IOAttrs('v')]@ioprepped@dataclassclassStringResponse(Response):"""A simple string value response."""value:Annotated[str,IOAttrs('v')]