alexa-skills-kit-sdk-for-python icon indicating copy to clipboard operation
alexa-skills-kit-sdk-for-python copied to clipboard

Type Checking Issues in Deserialize and Serialize Methods

Open Rob-S opened this issue 6 months ago • 0 comments
trafficstars

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.

Rob-S avatar May 14 '25 18:05 Rob-S