feat(event): accept any sequence of events where a list of them is accepted

Merged
BE
2d ago
+277-35

An event prop accepted a list literal of events, but not a list variable:

events: list[EventSpec] = [rx.redirect("/x"), rx.console_log("y")]
rx.button(on_click=events)  # rejected by pyright and ty

EventType spelled its list form list[...] of every kind of event, and lists are
invariant, so a list[EventSpec] or a list[EventCallback[()]] is not one of those.
At runtime the same holds for tuples: EventChain.create, format_queue_events,
Event.from_event_type and fix_events only took a list, while call_event_fn
already took a tuple from a lambda and _check_valid_yield already let a handler
return a tuple (return a, b), which from_event_type then rejected as an
unexpected event type.

EventType now spells it Sequence[...], which is covariant, and those places
take any sequence other than a string through is_non_string_sequence, a TypeIs
helper in reflex_base.utils.types, so the runtime accepts exactly what the type
does. A Var is not a Sequence, so nothing that was a single event becomes a
sequence. A page's on_load (App._commit_page) reads the value the same way, so
on_load=(a, b) registers both events instead of one tuple. The internal demo and
intro forms check their on_submit against Sequence directly, since their
declared reflex floor predates the helper, and reject a string up front.

from_event_type runs for every event a handler returns, so it checks the single
event kinds before the Sequence ABC, as _check_valid_yield does: a single
Event, EventSpec or callable costs what it did with the list check.

tests/type_checking/event.py passes a list[EventSpec] variable and a tuple of
handlers to an EventType[()] parameter; it fails under pyright and ty before this
change. Unit tests cover a tuple in each of the runtime places, the full unit suite
and pyright pass.