From be697506b097b028b3dfb4cd081209fcada4d748 Mon Sep 17 00:00:00 2001 From: Thomas Matecki Date: Mon, 14 Sep 2026 17:23:42 -0400 Subject: [PATCH 1/2] Fixup Type Annotations --- src/datastar_py/attributes.py | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/datastar_py/attributes.py b/src/datastar_py/attributes.py index 6950792..13d3179 100644 --- a/src/datastar_py/attributes.py +++ b/src/datastar_py/attributes.py @@ -131,7 +131,7 @@ def signals( val = _js_object(signals) if expressions_ else json.dumps(signals) return SignalsAttr(value=val, alias=self._alias) - def computed(self, computed_dict: Mapping | None = None, /, **computed: str) -> BaseAttr: + def computed(self, computed_dict: Mapping[str, str] | None = None, /, **computed: str) -> BaseAttr: """Create signals that are computed based on an expression.""" computed = {**(computed_dict or {}), **computed} first, *rest = ( @@ -150,7 +150,7 @@ def ignore(self) -> IgnoreAttr: """Tell Datastar to ignore data-* attributes on the element.""" return IgnoreAttr(alias=self._alias) - def attr(self, attr_dict: Mapping | None = None, /, **attrs: str) -> BaseAttr: + def attr(self, attr_dict: Mapping[str, str] | None = None, /, **attrs: str) -> BaseAttr: """Set the value of any HTML attributes to expressions, and keep them in sync.""" attrs = {**(attr_dict or {}), **attrs} return BaseAttr("attr", value=_js_object(attrs), alias=self._alias) @@ -159,7 +159,7 @@ def bind(self, signal_name: str) -> BaseAttr: """Set up two-way data binding between a signal and an element's value.""" return BindAttr(value=signal_name, alias=self._alias) - def class_(self, class_dict: Mapping | None = None, /, **classes: str) -> BaseAttr: + def class_(self, class_dict: Mapping[str, str] | None = None, /, **classes: str) -> BaseAttr: """Add or removes classes to or from an element based on expressions.""" classes = {**(class_dict or {}), **classes} return BaseAttr("class", value=_js_object(classes), alias=self._alias) @@ -214,7 +214,7 @@ def show(self, expression: str) -> BaseAttr: """Show or hides an element based on whether an expression evaluates to true or false.""" return BaseAttr("show", value=expression, alias=self._alias) - def style(self, style_dict: Mapping | None = None, /, **styles: str) -> BaseAttr: + def style(self, style_dict: Mapping[str, str] | None = None, /, **styles: str) -> BaseAttr: """Set the value of inline CSS styles on an element based on an expression, and keeps them in sync.""" styles = {**(style_dict or {}), **styles} return BaseAttr("style", value=_js_object(styles), alias=self._alias) @@ -261,7 +261,7 @@ def query_string(self) -> QueryStringAttr: return QueryStringAttr(alias=self._alias) -class BaseAttr(Mapping): +class BaseAttr(Mapping[str, str | Literal[True]]): _attr: str def __init__( @@ -346,6 +346,8 @@ def __str__(self) -> str: class TimingMod: + _mods: dict[str, list[str]] + def debounce( self: Self, wait: int | str, @@ -392,6 +394,9 @@ def throttle( class DelayMod: + + _mods: dict[str, list[str]] + def delay( self: Self, wait: int | str, @@ -405,6 +410,10 @@ def delay( class ViewtransitionMod: + + + _mods: dict[str, list[str]] + @property def viewtransition(self: Self) -> Self: """Wrap the expression in document.startViewTransition().""" @@ -719,8 +728,8 @@ def _escape(s: str) -> str: ) -def _filter_dict(include: str | None = None, exclude: str | None = None) -> dict: - filter_dict = {} +def _filter_dict(include: str | None = None, exclude: str | None = None) -> dict[str, str | None]: + filter_dict: dict[str, str| None] = {} if include: filter_dict["include"] = include if exclude: @@ -728,7 +737,9 @@ def _filter_dict(include: str | None = None, exclude: str | None = None) -> dict return filter_dict -def _js_object(obj: dict) -> str: +JSObjectDict: TypeAlias = Mapping[str, "str | SignalValue | JSObjectDict"] + +def _js_object(obj: JSObjectDict) -> str: """Create a JS object where the values are expressions rather than strings.""" return ( "{" From f13a0f6a4ac43a0779f8ca9e14962fd3c0b359d6 Mon Sep 17 00:00:00 2001 From: Thomas Matecki Date: Tue, 22 Sep 2026 10:58:09 -0400 Subject: [PATCH 2/2] _filter_dict values won't be --- src/datastar_py/attributes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/datastar_py/attributes.py b/src/datastar_py/attributes.py index 13d3179..abd2196 100644 --- a/src/datastar_py/attributes.py +++ b/src/datastar_py/attributes.py @@ -728,8 +728,8 @@ def _escape(s: str) -> str: ) -def _filter_dict(include: str | None = None, exclude: str | None = None) -> dict[str, str | None]: - filter_dict: dict[str, str| None] = {} +def _filter_dict(include: str | None = None, exclude: str | None = None) -> dict[str, str]: + filter_dict: dict[str, str] = {} if include: filter_dict["include"] = include if exclude: