Skip to content

Compiling raises a TypeError when using rx.foreach. #5157

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
murdak opened this issue Apr 21, 2025 · 3 comments · Fixed by #5161
Closed

Compiling raises a TypeError when using rx.foreach. #5157

murdak opened this issue Apr 21, 2025 · 3 comments · Fixed by #5161
Assignees

Comments

@murdak
Copy link

murdak commented Apr 21, 2025

Describe the bug
Compiling raises a TypeError when using rx.foreach with list of tuples.

Error: TypeError: Invalid var passed for prop Avatar.src, expected type <class 'str'>, got value category.at(1) of type typing.Union[int, str].

Compiling succeeds only when removing first element (or replacing with string type)
(or when rx.avatar is removed or replaced with rx.text)

To Reproduce

  1. Execute - reflex run
  2. Compile error is raised.
  • Code/Link to Repo:
def render_category(category):
    id = category[0]
    thumbnail = category[1]
    label = category[2]
    description = category[3]

    return rx.card(
                rx.link(
                    rx.flex(
                        rx.avatar(src=thumbnail),
                        #rx.text(thumbnail),
                        rx.box(
                            rx.text.strong(label, size="4"),
                            rx.text(
                                description
                            ),
                        ),
                        spacing="2",
                    ),
                    on_click=State.select_category(id),
                ),
                as_child=True,
            )

categorys = [
        (0, "/fries.webp", "label1", "desc1"),
        (1, "/fries.webp", "label2", "desc2"),
        (2, "/fries.webp", "label3", "desc3"),
    ]

@rx.page(route="/")
def index() -> rx.Component:
    return rx.container(
        rx.vstack(
            rx.foreach(categorys, render_category),

Expected behavior
Compile succeeds, application runs and data is displayed.

Screenshots
n/a

Specifics (please complete the following information):

  • Python Version: 3.11
  • Reflex Version: 7.7
  • OS: Linux
  • Browser (Optional): firefox

Additional context
n/a

Copy link

linear bot commented Apr 21, 2025

@masenf
Copy link
Collaborator

masenf commented Apr 21, 2025

@adhami3310 is there a reason we treat the tuple like a list instead of calling figure_out_type on each element?

diff --git a/reflex/vars/base.py b/reflex/vars/base.py
index 708548f0..689a75f4 100644
--- a/reflex/vars/base.py
+++ b/reflex/vars/base.py
@@ -1750,7 +1750,7 @@ def figure_out_type(value: Any) -> types.GenericType:
     if isinstance(value, set):
         return set[unionize(*(figure_out_type(v) for v in value))]
     if isinstance(value, tuple):
-        return tuple[unionize(*(figure_out_type(v) for v in value)), ...]
+        return tuple[*(figure_out_type(v) for v in value)]
     if isinstance(value, Mapping):
         if not value:
             return Mapping[NoReturn, NoReturn]

@adhami3310
Copy link
Member

is there a reason we treat the tuple like a list instead of calling figure_out_type on each element?

there are some reasons, one of them is trying to simplify the typing, it's a tradeoff where in this case doing the above makes more sense

we could do that maybe on small tuples? maybe the first few values of a tuple are like that then everything else is unionized?

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 a pull request may close this issue.

3 participants