From d45ce18453dbf0285d877b82ebd4213be24f0f17 Mon Sep 17 00:00:00 2001 From: galuszkm Date: Thu, 2 Jul 2026 02:54:59 +0200 Subject: [PATCH] fix(admin): render boolean fields under wtforms 3.2 - shim missing validation_attrs on sqladmin BooleanInputWidget --- src/strands_compose_chat/admin/__init__.py | 11 ++++++++- src/strands_compose_chat/admin/compat.py | 27 ++++++++++++++++++++++ uv.lock | 8 +++---- 3 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 src/strands_compose_chat/admin/compat.py diff --git a/src/strands_compose_chat/admin/__init__.py b/src/strands_compose_chat/admin/__init__.py index d104944..5cc85f7 100644 --- a/src/strands_compose_chat/admin/__init__.py +++ b/src/strands_compose_chat/admin/__init__.py @@ -1 +1,10 @@ -"""Admin panel: sqladmin views and authentication backend.""" +"""Admin panel: sqladmin views and authentication backend. + +Importing this package applies the sqladmin/wtforms compatibility shim (see +``compat``) so boolean form fields render under wtforms 3.2 before any admin +view is constructed. +""" + +from .compat import apply_wtforms_compat + +apply_wtforms_compat() diff --git a/src/strands_compose_chat/admin/compat.py b/src/strands_compose_chat/admin/compat.py new file mode 100644 index 0000000..1e9c52b --- /dev/null +++ b/src/strands_compose_chat/admin/compat.py @@ -0,0 +1,27 @@ +"""Compatibility shim for sqladmin widgets against supported wtforms versions. + +sqladmin's ``BooleanInputWidget`` subclasses wtforms' base ``Input`` widget +without declaring ``validation_attrs``. wtforms 3.1 defined that attribute on the +base ``Input`` class, so the widget inherited it; wtforms 3.2 moved +``validation_attrs`` onto each concrete widget subclass, leaving +``BooleanInputWidget`` without it. Rendering any boolean form field then raises +``AttributeError`` inside ``Input.__call__``. + +This shim gives the widget the checkbox validation attributes it should have had, +restoring boolean-field rendering under wtforms 3.2 without waiting on an sqladmin +release. It is a no-op on wtforms 3.1, where the attribute is already inherited. +""" + +from sqladmin.widgets import BooleanInputWidget +from wtforms.widgets import CheckboxInput + + +def apply_wtforms_compat() -> None: + """Ensure sqladmin's ``BooleanInputWidget`` declares ``validation_attrs``. + + Idempotent: only assigns when the attribute is missing, so it is safe to call + once during app construction and does nothing on wtforms versions that already + provide it via the base ``Input`` widget. + """ + if not hasattr(BooleanInputWidget, "validation_attrs"): + setattr(BooleanInputWidget, "validation_attrs", list(CheckboxInput.validation_attrs)) diff --git a/uv.lock b/uv.lock index 1d5d293..9f21e8b 100644 --- a/uv.lock +++ b/uv.lock @@ -2014,7 +2014,7 @@ wheels = [ [[package]] name = "strands-compose-chat" -version = "0.1.1" +version = "0.1.2" source = { editable = "." } dependencies = [ { name = "aiosqlite" }, @@ -2527,12 +2527,12 @@ wheels = [ [[package]] name = "wtforms" -version = "3.1.2" +version = "3.2.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markupsafe" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6a/c7/96d10183c3470f1836846f7b9527d6cb0b6c2226ebca40f36fa29f23de60/wtforms-3.1.2.tar.gz", hash = "sha256:f8d76180d7239c94c6322f7990ae1216dae3659b7aa1cee94b6318bdffb474b9", size = 134705, upload-time = "2024-01-06T07:52:41.075Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e9/91/ed9b517da898e3fb747566aa3c12a734bd64ea7449a0d25ec74ce8f8b8eb/wtforms-3.2.2.tar.gz", hash = "sha256:7b00c73f8670f35d4edb0293dcd81b980528bee72fd662b182aaba27ae570b93", size = 139583, upload-time = "2026-05-03T05:53:44.147Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/18/19/c3232f35e24dccfad372e9f341c4f3a1166ae7c66e4e1351a9467c921cc1/wtforms-3.1.2-py3-none-any.whl", hash = "sha256:bf831c042829c8cdbad74c27575098d541d039b1faa74c771545ecac916f2c07", size = 145961, upload-time = "2024-01-06T07:52:43.023Z" }, + { url = "https://files.pythonhosted.org/packages/18/76/bb225c8300f3a0ba28e01df51419c6c9574a297c43d71b29048e03b65deb/wtforms-3.2.2-py3-none-any.whl", hash = "sha256:72b90d5d921bd3119252069cf0301e9c13915f9e52792652bc91c5dda4b79e56", size = 158656, upload-time = "2026-05-03T05:53:46.072Z" }, ]