Skip to content

fix: annotate .tagify() return types per htmltools Tagified contract#311

Open
schloerke wants to merge 5 commits into
mainfrom
schloerke/htmltools-105-tagified-types
Open

fix: annotate .tagify() return types per htmltools Tagified contract#311
schloerke wants to merge 5 commits into
mainfrom
schloerke/htmltools-105-tagified-types

Conversation

@schloerke
Copy link
Copy Markdown
Contributor

@schloerke schloerke commented May 15, 2026

Summary

The upcoming htmltools release (posit-dev/py-htmltools#106 implementing #105) tightens the Tagifiable.tagify() Protocol return type from a bare TagList | Tag | MetadataNode | str | HTML to the new Tagified union. Tagified is the only tagified-shape alias exported by htmltools — downstream .tagify() implementations should annotate -> Tagified exclusively.

Annotate the three custom .tagify() methods in chatlas/_content.py with -> Tagified. Since htmltools is an optional runtime dep, the import lives behind TYPE_CHECKING (the existing from __future__ import annotations defers annotation evaluation).

For the ContentToolRequest.tagify() method 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 (the leaf-string arm of the union).

Test plan

  • uv run --with-editable <path>/py-htmltools pyright → 0 errors
  • Runtime behavior unchanged: .tagify() on a TagList containing only HTML / head_content is structurally idempotent

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`.
schloerke added 3 commits May 18, 2026 10:06
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).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant