Skip to content

pyright rejects @rx.event(...) stacked above another @rx.event, although the repeated decorator is supported at runtime #7847

Open

Description

@masenf

Problem

Since #7807, stacking @rx.event decorators is supported at runtime: a repeated decorator is merged into one handler (options of the outer decorator win), which keeps apps like reflex-examples overkey working. The type stubs do not follow: the EventDecorator protocol that rx.event(...) returns only accepts a plain function Callable[[BASE_STATE, Unpack[P]], Any]. Applied to the EventCallback that the inner @rx.event produces, pyright reports an argument-type error on the decorator line. The unit tests for #7807 carry # pyright: ignore for this reason.

Repro

import reflex as rx


class S(rx.State):
    count: int = 0

    @rx.event(throttle=300)   # pyright: error (argument of type EventCallback[int] not assignable to Callable[[BASE_STATE, ...], Any])
    @rx.event(background=True)
    async def tick(self, step: int):
        async with self:
            self.count += step

uv run pyright on a file containing this (pyright 1.1.41x). The bare form @rx.event above @rx.event(...) goes through the func overload of rx.event; check it too.

Expected vs actual

  • Expected: no pyright error; S.tick is typed EventCallback[int], like a single decorator.
  • Actual: pyright error on the outer decorator.

Fix direction

  • Code: EventDecorator.__call__ and the EventNamespace.__new__ overloads in packages/reflex-base/src/reflex_base/event/__init__.py.
  • Add an overload of EventDecorator.__call__ that accepts EventCallback[Unpack[P]] and returns EventCallback[Unpack[P]]; if the bare func overload of rx.event has the same gap, add the matching overload there.
  • Mind the pyright-vs-Python-version issue fixed in Type bare @rx.event handlers under pyright before Python 3.14 #7810: verify with pyright --pythonversion 3.12 as well as 3.14, and with mypy.
  • Remove the # pyright: ignore comments from the repeated-decorator tests in tests/units/test_event.py once they pass, and add a typing check in the typing test suite if one exists for event handlers.

Not a regression (stacking crashed at import before #7807).

Activity

  1. added
    bugSomething isn't working
    release-trainIssues found during agentic /prerelease-testing fanout, not necessarily validated bugs.
    on Nov 11, 2026
  2. linear-code commented on Nov 11, 2026

    @linear-code
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingrelease-trainIssues found during agentic /prerelease-testing fanout, not necessarily validated bugs.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions