From 00d919e0614868a976513a7abafbaac341dab494 Mon Sep 17 00:00:00 2001 From: Kazuhiro Sera Date: Mon, 28 Oct 2024 09:16:49 +0900 Subject: [PATCH 1/2] Enable rich_text_section element to have an empty 'elements' property --- slack_sdk/models/basic_objects.py | 14 ++++++++++++++ tests/slack_sdk/models/test_blocks.py | 18 ++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/slack_sdk/models/basic_objects.py b/slack_sdk/models/basic_objects.py index 232ec21ea..b5fef8ceb 100644 --- a/slack_sdk/models/basic_objects.py +++ b/slack_sdk/models/basic_objects.py @@ -12,6 +12,11 @@ def __str__(self): return f"" +# Usually, Block Kit components do not allow an empty array for a property value, +# but there are some exceptions (as of October 2024, only rich_text_section's elements property). +EMPTY_ALLOWED_TYPE_AND_PROPERTY_LIST = [{"type": "rich_text_section", "property": "elements"}] + + class JsonObject(BaseObject, metaclass=ABCMeta): """The base class for JSON serializable class objects""" @@ -51,6 +56,15 @@ def is_not_empty(self, key: str) -> bool: value = getattr(self, key, None) if value is None: return False + + # Usually, Block Kit components do not allow an empty array for a property value, + # but there are some exceptions (as of October 2024, only rich_text_section's elements property). + # The following code deals with this exception: + type_value = getattr(self, "type", None) + for empty_allowed in EMPTY_ALLOWED_TYPE_AND_PROPERTY_LIST: + if type_value == empty_allowed["type"] and key == empty_allowed["property"]: + return True + has_len = getattr(value, "__len__", None) is not None if has_len: # skipcq: PYL-R1705 return len(value) > 0 diff --git a/tests/slack_sdk/models/test_blocks.py b/tests/slack_sdk/models/test_blocks.py index 65f0bafd6..df34a452a 100644 --- a/tests/slack_sdk/models/test_blocks.py +++ b/tests/slack_sdk/models/test_blocks.py @@ -1143,3 +1143,21 @@ def test_elements_are_parsed(self): self.assertIsInstance(block.elements[3], RichTextListElement) self.assertIsInstance(block.elements[3].elements[0], RichTextSectionElement) self.assertIsInstance(block.elements[3].elements[0].elements[0], RichTextElementParts.Text) + + def test_parsing_empty_block_elements(self): + empty_element_block = { + "block_id": "my-block", + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [], + }, + ], + } + block = RichTextBlock(**empty_element_block) + self.assertIsInstance(block.elements[0], RichTextSectionElement) + self.assertIsNotNone(block.elements[0].elements) + + block_dict = block.to_dict() + self.assertIsNotNone(block_dict["elements"][0].get("elements")) From e6548d363d221c17af8444c227bee92b2570df13 Mon Sep 17 00:00:00 2001 From: Kazuhiro Sera Date: Mon, 28 Oct 2024 12:28:23 +0900 Subject: [PATCH 2/2] Add more patterns --- slack_sdk/models/basic_objects.py | 15 +++++++++------ tests/slack_sdk/models/test_blocks.py | 14 ++++++++++---- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/slack_sdk/models/basic_objects.py b/slack_sdk/models/basic_objects.py index b5fef8ceb..bd9ffe58e 100644 --- a/slack_sdk/models/basic_objects.py +++ b/slack_sdk/models/basic_objects.py @@ -12,9 +12,13 @@ def __str__(self): return f"" -# Usually, Block Kit components do not allow an empty array for a property value, -# but there are some exceptions (as of October 2024, only rich_text_section's elements property). -EMPTY_ALLOWED_TYPE_AND_PROPERTY_LIST = [{"type": "rich_text_section", "property": "elements"}] +# Usually, Block Kit components do not allow an empty array for a property value, but there are some exceptions. +EMPTY_ALLOWED_TYPE_AND_PROPERTY_LIST = [ + {"type": "rich_text_section", "property": "elements"}, + {"type": "rich_text_list", "property": "elements"}, + {"type": "rich_text_preformatted", "property": "elements"}, + {"type": "rich_text_quote", "property": "elements"}, +] class JsonObject(BaseObject, metaclass=ABCMeta): @@ -57,9 +61,8 @@ def is_not_empty(self, key: str) -> bool: if value is None: return False - # Usually, Block Kit components do not allow an empty array for a property value, - # but there are some exceptions (as of October 2024, only rich_text_section's elements property). - # The following code deals with this exception: + # Usually, Block Kit components do not allow an empty array for a property value, but there are some exceptions. + # The following code deals with these exceptions: type_value = getattr(self, "type", None) for empty_allowed in EMPTY_ALLOWED_TYPE_AND_PROPERTY_LIST: if type_value == empty_allowed["type"] and key == empty_allowed["property"]: diff --git a/tests/slack_sdk/models/test_blocks.py b/tests/slack_sdk/models/test_blocks.py index df34a452a..940669b00 100644 --- a/tests/slack_sdk/models/test_blocks.py +++ b/tests/slack_sdk/models/test_blocks.py @@ -1149,15 +1149,21 @@ def test_parsing_empty_block_elements(self): "block_id": "my-block", "type": "rich_text", "elements": [ - { - "type": "rich_text_section", - "elements": [], - }, + {"type": "rich_text_section", "elements": []}, + {"type": "rich_text_list", "style": "bullet", "elements": []}, + {"type": "rich_text_preformatted", "elements": []}, + {"type": "rich_text_quote", "elements": []}, ], } block = RichTextBlock(**empty_element_block) self.assertIsInstance(block.elements[0], RichTextSectionElement) self.assertIsNotNone(block.elements[0].elements) + self.assertIsNotNone(block.elements[1].elements) + self.assertIsNotNone(block.elements[2].elements) + self.assertIsNotNone(block.elements[3].elements) block_dict = block.to_dict() self.assertIsNotNone(block_dict["elements"][0].get("elements")) + self.assertIsNotNone(block_dict["elements"][1].get("elements")) + self.assertIsNotNone(block_dict["elements"][2].get("elements")) + self.assertIsNotNone(block_dict["elements"][3].get("elements"))