fix: annotate .tagify() return types per htmltools Tagified contract#311
Open
schloerke wants to merge 5 commits into
Open
fix: annotate .tagify() return types per htmltools Tagified contract#311schloerke wants to merge 5 commits into
schloerke wants to merge 5 commits into
Conversation
The upcoming htmltools release (posit-dev/py-htmltools#105) tightens the `Tagifiable.tagify()` Protocol return type from a bare `TagList | Tag | MetadataNode | str | HTML` to the new `Tagified` union (`TagifiedTag | TagifiedTagList | TagLeaf`). Annotate the three custom `.tagify()` methods in `chatlas/_content.py` with `-> Tagified` (string-import via TYPE_CHECKING since htmltools is an optional runtime dep). For the `ContentToolRequest` `tagify` that returns a `TagList`, append `.tagify()` so the value is properly tagified (matches the recursive invariant the protocol now expresses). The two methods that return `HTML(...)` directly are already in `Tagified` via the `_TagLeaf` arm.
schloerke
added a commit
to posit-dev/py-htmltools
that referenced
this pull request
May 15, 2026
…ype changes * py-shiny@schloerke/htmltools-105-tagified-types — posit-dev/py-shiny#2244 * shinychat@schloerke/htmltools-105-tagified-types — posit-dev/shinychat#226 * chatlas@schloerke/htmltools-105-tagified-types — posit-dev/chatlas#311 * brand-yml@schloerke/htmltools-105-tagified-types — posit-dev/brand-yml#115 When each downstream PR merges, flip its `ref` back to `main` (or remove the explicit ref). The matrix is restructured to use `include:` so each entry can carry its own `ref`.
The `Tagified` alias used by this PR is only available in htmltools >= 0.7.0 (posit-dev/py-htmltools#105). Pin htmltools to the PR branch via `[tool.uv.sources]` so CI installs the version that exports `Tagified` and pyright is happy. **Remove this override before merging** once htmltools 0.7.0 is on PyPI.
The PR introduces `Tagified`, only available in htmltools 0.7.0+ (posit-dev/py-htmltools#105). Bump the declared minimum so consumers who skip the PR-branch pin still resolve a compatible version.
htmltools 0.7.0 dropped Python 3.9, and uv resolves dependencies for the full supported-Python range. Without this marker the 3.9 resolution split fails even when running tests on 3.10+.
The schloerke/tagify-tag-class-issue branch was deleted after posit-dev/py-htmltools#106 merged. Point at main so CI resolves again while we wait for the htmltools 0.7.0 PyPI release. The [tool.uv.sources] block will be dropped entirely once 0.7.0 ships (see posit-dev/py-htmltools#113).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The upcoming htmltools release (posit-dev/py-htmltools#106 implementing #105) tightens the
Tagifiable.tagify()Protocol return type from a bareTagList | Tag | MetadataNode | str | HTMLto the newTagifiedunion.Tagifiedis the only tagified-shape alias exported by htmltools — downstream.tagify()implementations should annotate-> Tagifiedexclusively.Annotate the three custom
.tagify()methods inchatlas/_content.pywith-> Tagified. Sincehtmltoolsis an optional runtime dep, the import lives behindTYPE_CHECKING(the existingfrom __future__ import annotationsdefers annotation evaluation).For the
ContentToolRequest.tagify()method that returns aTagList, append.tagify()so the value is properly tagified (matches the recursive invariant the protocol now expresses). The two methods that returnHTML(...)directly are already inTagified(the leaf-string arm of the union).Test plan
uv run --with-editable <path>/py-htmltools pyright→ 0 errors.tagify()on aTagListcontaining onlyHTML/head_contentis structurally idempotent