Skip to content
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

TypeError message is missleading for untyped lists #4576

Open
cglukas opened this issue Dec 29, 2024 · 2 comments
Open

TypeError message is missleading for untyped lists #4576

cglukas opened this issue Dec 29, 2024 · 2 comments
Labels
error message Improve error message

Comments

@cglukas
Copy link

cglukas commented Dec 29, 2024

Describe the bug
I ran into a TypeError that complained that I missed some type annotations in my render function. After some investigation, it turned out that the attribute of my state var was not correctly typed. In this case, I would expect an error message that points to a more reasonable place than the correctly typed render function.

To Reproduce
This simple example here should be able to produce this misleading TypeError:

from dataclasses import dataclass
import reflex as rx


@dataclass
class SimpleDataclass:
    Name: str


class MyState(rx.State):
    # Adding 'list[SimpleDataClass]' as type annotation fixes the issue.
    # It would be good to point to this line instead of the render function.
    untyped_list = [SimpleDataclass("")]


# I see no issue with the typing of this render function:
def render_fun(item: SimpleDataclass):
    return rx.badge(item.Name)


def index() -> rx.Component:
    return rx.container(rx.foreach(MyState.untyped_list, render_fun))


app = rx.App()
app.add_page(index)

The traceback should look something like this:

Traceback (most recent call last):
  File "HOME\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "HOME\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "...\.venv\lib\site-packages\reflex\__main__.py", line 6, in <module>
    cli()
  File "...\.venv\lib\site-packages\typer\main.py", line 340, in __call__
    raise e
  File "...\.venv\lib\site-packages\typer\main.py", line 323, in __call__
    return get_command(self)(*args, **kwargs)
  File "...\.venv\lib\site-packages\click\core.py", line 1157, in __call__
    return self.main(*args, **kwargs)
  File "...\.venv\lib\site-packages\typer\core.py", line 743, in main
    return _main(
  File "...\.venv\lib\site-packages\typer\core.py", line 198, in _main
    rv = self.invoke(ctx)
  File "...\.venv\lib\site-packages\click\core.py", line 1688, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "...\.venv\lib\site-packages\click\core.py", line 1434, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "...\.venv\lib\site-packages\click\core.py", line 783, in invoke
    return __callback(*args, **kwargs)
  File "...\.venv\lib\site-packages\typer\main.py", line 698, in wrapper
    return callback(**use_params)
  File "...\.venv\lib\site-packages\reflex\reflex.py", line 286, in run
    _run(env, frontend, backend, frontend_port, backend_port, backend_host, loglevel)
  File "...\.venv\lib\site-packages\reflex\reflex.py", line 187, in _run
    prerequisites.get_compiled_app()
  File "...\.venv\lib\site-packages\reflex\utils\prerequisites.py", line 327, in get_compiled_app
    app._compile(export=export)
  File "...\.venv\lib\site-packages\reflex\app.py", line 857, in _compile
    self._compile_page(route)
  File "...\.venv\lib\site-packages\reflex\app.py", line 550, in _compile_page
    component, enable_state = compiler.compile_unevaluated_page(
  File "...\.venv\lib\site-packages\reflex\compiler\compiler.py", line 563, in compile_unevaluated_page
    component = component if isinstance(component, Component) else component()
  File "...\SFZ_Kommunikation\SFZ_Kommunikation.py", line 22, in index
    rx.foreach(MyState.untyped_list, render_fun)
  File "...\.venv\lib\site-packages\reflex\components\core\foreach.py", line 75, in create
    component.children = [component._render().render_component()]
  File "...\.venv\lib\site-packages\reflex\components\tags\iter_tag.py", line 126, in render_component
    component = self.render_fn(arg)
  File "...\SFZ_Kommunikation\SFZ_Kommunikation.py", line 18, in render_fun
    return rx.badge(item.Name)
  File "...\.venv\lib\site-packages\reflex\vars\base.py", line 1059, in __getattr__
    raise TypeError(
TypeError: You must provide an annotation for the state var `item`. Annotation cannot be `typing.Any`.

Expected behavior
IMHO the error should point to the origin of the issue. Instead of "You must provide an annotation for the state var item. Annotation cannot be typing.Any." It should use the right variable name "untyped_list". IMO the error message is currently wrong because the "item" variable is correctly annotated.

Specifics (please complete the following information):

  • Python Version: 3.10.0
  • Reflex Version: 0.6.6.post3
  • OS: Windows 10
  • Browser (Optional): None, this issue happens during frontend compilation.

Anyway, I think this issue is just a small convenience feature for other devs. Would be great to get it fixed for future versions. Maybe it's a low-hanging fruit... IDK.
I'm really enjoying the reflex framework. It's quite nice to use 👍. Hope this report can add some value to this project😀

Copy link

linear bot commented Dec 29, 2024

@adhami3310
Copy link
Member

The issue is that the render function provides a fake variable with the same name as the function argument. It doesn't actually use the variable you provided. It might be possible to instead raise UntypedVarError and make the foreach function catch such error and raise it again with the correct variable name. An additional check can be had that it was the var with the same name (otherwise, a separate UntypedVarError could be wrongly assumed to be because of the foreach first argument).

@adhami3310 adhami3310 added the error message Improve error message label Jan 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
error message Improve error message
Projects
None yet
Development

No branches or pull requests

2 participants