fix(models): type CardBlock icon/hero_image as image element (not str) - #1937
fix(models): type CardBlock icon/hero_image as image element (not str)#1937zimeg wants to merge 2 commits into
Conversation
Per the card block reference, `icon` and `hero_image` are image element objects (`type`/`image_url`/`alt_text`), not plain URL strings — but CardBlock typed them as Optional[str], so passing an ImageElement (the correct, accessible form with alt_text) tripped mypy [arg-type]. Widen both to Optional[Union[str, dict, ImageElement]], matching how title/subtitle/body already accept Union[str, dict, TextObject]. Runtime serialization is unchanged (str -> bare URL, dict/ImageElement -> object); this only broadens the accepted/typed input. Docstrings updated to the reference wording. Adds a test asserting the ImageElement form round-trips. Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Examples should not carry type-checker suppressions. Remove the # type: ignore[arg-type] added for the ImageElement icon/hero_image args. Until slackapi/python-slack-sdk#1937 lands (widening CardBlock.icon / hero_image to accept an image element), mypy reports [arg-type] here by design — the honest signal that slack_sdk mis-types these fields as str. Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Examples should not carry type-checker suppressions. Remove the # type: ignore[arg-type] on the ImageElement icon/hero_image args. Until slackapi/python-slack-sdk#1937 lands (widening CardBlock.icon / hero_image to accept an image element), mypy reports [arg-type] here by design — the honest signal that slack_sdk mis-types these fields as str. Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
|
Note on keeping The card block reference documents This PR deliberately keeps
If maintainers prefer to make these object-only, that'd be a separate major-version change (update |
Slack's card block schema (and the docs reference) define icon/hero_image as image element objects — a bare URL string is not a valid payload and is rejected by the API. CardBlock previously typed them as Optional[str], modeling a form that does not actually work end to end. Type both as Optional[Union[dict, ImageElement]] (object-only), matching title/subtitle/body's object-based typing. Update test_document to the documented object form (it previously passed bare-string icons). Runtime serialization of an ImageElement/dict was already correct; this drops the never-valid str form. Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1937 +/- ##
=======================================
Coverage 84.17% 84.17%
=======================================
Files 118 118
Lines 13425 13425
=======================================
Hits 11301 11301
Misses 2124 2124 ☔ View full report in Codecov by Harness. |
zimeg
left a comment
There was a problem hiding this comment.
Leaving a callout on the breaking change that I'm marking as a patch update 📣
| hero_image: Optional[str] = None, | ||
| icon: Optional[str] = None, |
There was a problem hiding this comment.
str option is removed which typechecking might complain about but this matches what's valid with the API itself:
Summary
The card block reference specifies that
iconandhero_imageare image element objects ({"type": "image", "image_url": ..., "alt_text": ...}), not plain URL strings. ButCardBlocktyped both asOptional[str], so passing anImageElement— the correct, accessible form (it carriesalt_text) — raised a mypy[arg-type]error and forced callers to use# type: ignore.This widens both parameters to
Optional[Union[str, dict, ImageElement]], matching howtitle/subtitle/bodyalready acceptUnion[str, dict, TextObject].Details
slack_sdk/models/blocks/blocks.py—CardBlock.__init__:hero_image/icontypedOptional[Union[str, dict, ImageElement]]; docstrings updated to the reference wording (incl. the max-length notes).str→ bare URL (back-compat, still covered bytest_document),dict/ImageElement→ the object shape. This is a type-widening only.test_image_element_icon_and_hero_imageasserting theImageElementform round-trips to the documented object.Testing
pytest tests/slack_sdk/models/test_blocks.py— 85 passed (incl. the new test; no regressions).mypy slack_sdk/models/blocks/blocks.py— clean.Motivation
Downstream: the Bolt
bolt-python-examplescard/carousel examples buildicon/hero_imagewithImageElement(docs-correct) and currently need# type: ignore[arg-type]because of this mis-typing. This fix lets those examples drop the suppression.🤖 Generated with Claude Code