fix: align custom .tagify() annotations with htmltools Tagified contract#226
Draft
schloerke wants to merge 5 commits into
Draft
fix: align custom .tagify() annotations with htmltools Tagified contract#226schloerke 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`). Custom .tagify() implementations whose return is wider than `Tagified` no longer satisfy the protocol in strict-mode type checkers. * `_chat_bookmark.py`: change `def tagify(self) -> TagChild: return ""` to `-> Tagified`. The previous `TagChild` annotation was wider than the protocol return type (TagChild includes float/None/Sequence/etc.). * `_chat_normalize_chatlas.py`: annotate both `def tagify(self):` methods as `-> Tagified` and call `.tagify()` on the returned `Tag(…)` so the value is properly tagified (matches the recursive invariant the protocol now expresses).
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` type alias is only available in htmltools >= 0.7.0 (posit-dev/py-htmltools#105). Importing it at module load time breaks `from htmltools import Tagified` against the currently-released htmltools 0.6.x. Move the import under `if TYPE_CHECKING:`. The existing `from __future__ import annotations` defers all annotations to lazy strings, so the name only needs to resolve at type-check time, not at runtime. This makes the branch importable today and type-checks under both the released htmltools and the upcoming one.
The `Tagified` alias used by this PR is only available in htmltools >= 0.7.0 (posit-dev/py-htmltools#105). Until that release lands, 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.
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 toTagified.Tagifiedis a tighter union than the previous bareTagList | Tag | MetadataNode | str | HTML: it excludes the un-resolvedTagifiablearm and is the only tagified-shape alias exported by htmltools — downstream.tagify()implementations should annotate-> Tagifiedexclusively. Custom.tagify()implementations whose return is wider thanTagifiedno longer satisfy the protocol in strict-mode type checkers.Changes:
_chat_bookmark.py: changedef tagify(self) -> TagChild: return ""to-> Tagified. The previousTagChildannotation was wider than the protocol return type (TagChildincludesfloat/None/Sequence/etc.)._chat_normalize_chatlas.py: annotate bothdef tagify(self):methods as-> Tagifiedand call.tagify()on the returnedTag(…)so the value is properly tagified (matches the recursive invariant the protocol now expresses).Pyright (basic mode, as configured) is already clean with the released htmltools; these changes make the code also correct under the upcoming protocol tightening.
Test plan
uv run --with-editable <path>/py-htmltools pyright→ 0 errors.tagify()on a leaf-onlyTagis a no-op at runtime