python-slack-sdk icon indicating copy to clipboard operation
python-slack-sdk copied to clipboard

`RichTextElement.elements` items are never promoted to a proper Python object type

Open kezabelle opened this issue 1 year ago • 1 comments

Using the rich text editor widget with the following content: Screenshot 2024-03-05 at 11 39 10 gets you an unordered list, which upon a view_submission event gets posted into the state values as:

JSON representation of state value
{
  "type": "rich_text",
  "elements": [
    {
      "type": "rich_text_list",
      "style": "bullet",
      "indent": 0,
      "elements": [
        {
          "type": "rich_text_section",
          "elements": [
            {
              "type": "text",
              "text": "a"
            }
          ]
        },
        {
          "type": "rich_text_section",
          "elements": [
            {
              "type": "text",
              "text": "b"
            }
          ]
        }
      ],
      "border": 0
    }
  ]
}

which can then be converted into an object like so:

>>> obj = Block.parse(example)
>>> type(obj)
slack_sdk.models.blocks.blocks.RichTextBlock
>>> len(obj.elements)
1
>>> type(obj.elements[0])
slack_sdk.models.blocks.block_elements.RichTextListElement

which is all well and good... But the child elements of the encountered RichTextElement subclass are not converted to the equivalent Python class, and always remain as a dict, effectively looking like the parsing "gave up" at a certain depth (which isn't strictly true):

>>> type(obj.elements[0].elements[0])
dict
>>> obj.elements[0].elements[0]
{'type': 'rich_text_section', 'elements': [{'type': 'text', 'text': 'a'}]}

As far as I can tell, this is because the RichTextListElement, RichTextPreformattedElement, RichTextQuoteElement and RichTextSectionElement never themselves do any parsing, as all of them are defined using:

self.elements = elements

instead of something like:

self.elements = BlockElement.parse_all(elements)

The latter of which would at least make it so that:

>>> type(obj.elements[0].elements[0])
slack_sdk.models.blocks.block_elements.RichTextSectionElement 

That still leaves some child elements unpromoted, because there's nothing which converts {'type': 'text', 'text': 'a'} to a RichTextElementParts.Text etc, but that feels like a somewhat separate issue.

Category

  • [x] slack_sdk.models (UI component builders)

kezabelle avatar Mar 05 '24 11:03 kezabelle

Hi @kezabelle, thanks for reporting this! We will resolve the issue in the next release.

seratch avatar Mar 06 '24 01:03 seratch

Hello, @seratch I would like to work on this issue.

I believe I can submit a PR within a few days.

I have made changes to the RichTextListElement, RichTextPreformattedElement, RichTextQuoteElement and RichTextSectionElement classes in the slack_sdk/models/blocks/blocks.py file, and I am planning to update the tests in the tests/slack_sdk/models/test_blocks.py file next. Please let me know if there is anything else I need to consider before proceeding. Thank you.

k1e1n04 avatar May 01 '24 16:05 k1e1n04

Thank you. If you meant block_elements.py, that should be good to go. Having unit test addition would be also appreciated.

seratch avatar May 02 '24 02:05 seratch

@seratch It was block_elements.py, not blocks.py 🙏 I have created a PR, please check it when you have time.

k1e1n04 avatar May 02 '24 16:05 k1e1n04