alexa-skills-kit-sdk-for-python
alexa-skills-kit-sdk-for-python copied to clipboard
Type Checking Issues in Deserialize and Serialize Methods
This is a minor issue, affecting only type checking, such as when using MyPy.
To store application objects in attributes (managed by AttributesManager), the objects do not need to be fully serialized to a string, just converted from application-specific attributes to potentially serializable built-in types (str, bytes, int, float, bool, list, tuple, dict). Therefore, the DefaultSerializer has methods which use the Python object representation of JSON in place of the fully-serialized string.
Type hints for __deserialize on lines 172 - 173 declare payload as Optional[str] (# type: (Optional[str], Union[T, str]) -> Any) (likely copy-and-pasted from the deserialize method).
https://github.com/alexa/alexa-skills-kit-sdk-for-python/blob/7e13ca69b240985584dff6ec633a27598a154ca1/ask-sdk-core/ask_sdk_core/serialize.py#L173
However, the payload is the value returned by json.loads, which is the Python object representation of a JSON string. This results in (from MyPy):
@error: Argument 1 to "__deserialize" of "DefaultSerializer" has incompatible type "..."; expected "str | None" [arg-type].
The type hint should be something like:
# type: (Optional[str | bytes | int | float | bool | list[Any] | tuple[Any, ...] | dict[str, Any]], type) -> Any)
or, the new way:
def __deserialize(self, payload: str | bytes | int | float | bool | list[Any] | tuple[Any, ...] | dict[str, Any] | None, obj_type: type) -> Any
Likewise, the replacement of the #type(str) return value of the serialize method with the Python object representation of JSON results in (from MyPy):
@error: Incompatible return value type (got "dict[str, Any] | list[Any] | tuple[Any, ...] | str | int | float | bytes | None", expected "str") [return-value]
That is, it violates the Liskov Substitution Principle: @Return types in subclass methods should either match or be subtypes of return types in superclass methods.
A solution to that might be to use a __serialize method, similar to the use of __deserialize.