-
Notifications
You must be signed in to change notification settings - Fork 853
Description
The type contract for StaticSelectElement specifies:
options: Optional[Sequence[Union[dict, slack_sdk.models.blocks.basic_components.Option]]] = None
which is how I've encountered the problem, but the issue itself seems to be generic based on how to_dict_compatible is implemented.
Given the following:
In [1]: from slack_sdk.models.blocks import StaticSelectElement, Option
In [2]: from typing import Sequence
In [3]: Option(value="x", text="x").to_dict()
Out[3]: {'text': {'emoji': True, 'text': 'x', 'type': 'plain_text'}, 'value': 'x'}
In [4]: StaticSelectElement(options=[Option(value="x", text="x")]).to_dict()
Out[5]:
{'options': [{'text': {'emoji': True, 'text': 'x', 'type': 'plain_text'},
'value': 'x'}],
'type': 'static_select'}
In [6]: isinstance([], Sequence)
Out[6]: True
which is all well and good.
However, simply changing using a tuple as the sequence, leads to:
In [7]: StaticSelectElement(options=(
...: Option(value="x", text="x"),
...: )
...: ).to_dict()
Out[7]: {'options': (<slack_sdk.Option>,), 'type': 'static_select'}
In [14]: isinstance((), Sequence)
Out[14]: True
which conceptually may make some sense (it's still a tuple of options after all), but doesn't given the docstring of JsonObject.to_dict which says:
Extract this object as a JSON-compatible, Slack-API-valid dictionary
and you'll ultimately end up with an error like so if you do try and serialize it down to JSON:
TypeError: Object of type Option is not JSON serializable
Environment details, though I don't think it matters for this case, because it's still the same on main right now:
slack-sdk==3.15.2
Python 3.10.2
ProductName: macOS
ProductVersion: 12.2.1
The issue itself is "simply" a strict isinstance check like so: if isinstance(value, list): where it doesn't actually consider all sequence types. I'd posit that changing it to if isinstance(value, typing.Sequence): might be all that's needed, and would cover mutable/immutable and builtin/custom object types that meet the expected contract.