Skip to content

feat: TagList.tagify() raises TypeError on un-tagified content#112

Merged
schloerke merged 1 commit into
mainfrom
schloerke/manual-checks-no-type-asserts
May 15, 2026
Merged

feat: TagList.tagify() raises TypeError on un-tagified content#112
schloerke merged 1 commit into
mainfrom
schloerke/manual-checks-no-type-asserts

Conversation

@schloerke
Copy link
Copy Markdown
Collaborator

Summary

Adds runtime guards (only) from #106, with zero changes to type signatures:

  • TagList.tagify() now checks the post-recursion list for any remaining bare Tagifiable (excluding Tag / TagList, which are themselves Tagifiable but already-tagified shapes) and raises TypeError naming the offending class and slot index. This surfaces a broken .tagify() implementation at its source rather than later at render time.
  • TagList.get_html_string()'s render-time RuntimeError (kept as the fallback when the tree is mutated after .tagify()) now also names the offending class and hints at the likely cause.
  • New tests/test_tagify.py covering both guards plus idempotence of .tagify().

Explicitly excluded from #106:

  • All Tagified / TagifiedNode / TagifiedTag / TagifiedTagList type aliases.
  • Tag / TagList becoming Generic[ChildT].
  • All cast(...) calls and # pyright: ignore[...] comments.
  • Tagifiable.tagify() / Tag.tagify() return-type changes.
  • typing_extensions>=4.7.0 floor bump.
  • _jsx.py / _util.py type-assertion-driven changes.
  • tests/test_types.py static-type assertions.

Test plan

  • uv run pytest — 82 passed
  • uv run pyright htmltools tests — 0 errors, 0 warnings
  • uv run ruff check / ruff format --check — clean

When a child Tagifiable.tagify() returns a TagList whose own children
include another un-tagified Tagifiable, the broken recursion previously
surfaced as a confusing render-time RuntimeError far from the offending
implementation. TagList.tagify() now checks the post-recursion list for
any remaining bare Tagifiable (Tag and TagList excluded, since they are
themselves Tagifiable but already-tagified shapes) and raises TypeError
naming the offending class and slot index.

The render-time RuntimeError in TagList.get_html_string() — kept as the
fallback when the tree is mutated after .tagify() — now also names the
un-tagified class and points at the likely cause.

No public types or signatures change; the guards are purely runtime.
@schloerke
Copy link
Copy Markdown
Collaborator Author

Merging this as it's good behavior to have while we worry about true the typing vars in #106

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