reflex icon indicating copy to clipboard operation
reflex copied to clipboard

The error appears when the lambda is inside the event chain

Open heumsi opened this issue 3 years ago β€’ 2 comments

Describe the bug A clear and concise description of what the bug is.

I got following error.

AttributeError: 'function' object has no attribute 'fn'
Details
─────────────────────────────── Starting Pynecone App ────────────────────────────────
Traceback (most recent call last):
  File "/Users/user/Desktop/heumsi/repos/hollys/.venv/bin/pc", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/Users/user/Desktop/heumsi/repos/hollys/.venv/lib/python3.11/site-packages/typer/main.py", line 214, in __call__
    return get_command(self)(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/Desktop/heumsi/repos/hollys/.venv/lib/python3.11/site-packages/click/core.py", line 1130, in __call__
    return self.main(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/Desktop/heumsi/repos/hollys/.venv/lib/python3.11/site-packages/click/core.py", line 1055, in main
    rv = self.invoke(ctx)
         ^^^^^^^^^^^^^^^^
  File "/Users/user/Desktop/heumsi/repos/hollys/.venv/lib/python3.11/site-packages/click/core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/Desktop/heumsi/repos/hollys/.venv/lib/python3.11/site-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/Desktop/heumsi/repos/hollys/.venv/lib/python3.11/site-packages/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/Desktop/heumsi/repos/hollys/.venv/lib/python3.11/site-packages/typer/main.py", line 532, in wrapper
    return callback(**use_params)  # type: ignore
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/Desktop/heumsi/repos/hollys/.venv/lib/python3.11/site-packages/pynecone/pc.py", line 78, in run
    app = utils.get_app()
          ^^^^^^^^^^^^^^^
  File "/Users/user/Desktop/heumsi/repos/hollys/.venv/lib/python3.11/site-packages/pynecone/utils.py", line 365, in get_app
    app = __import__(module, fromlist=(constants.APP_VAR,))
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/Desktop/heumsi/repos/hollys/hollys/hollys.py", line 15, in <module>
    app.add_page(query.index, path="/")
  File "/Users/user/Desktop/heumsi/repos/hollys/.venv/lib/python3.11/site-packages/pynecone/app.py", line 193, in add_page
    component = component if isinstance(component, Component) else component()
                                                                   ^^^^^^^^^^^
  File "/Users/user/Desktop/heumsi/repos/hollys/hollys/page/query/__init__.py", line 150, in index
    return page(content())
                ^^^^^^^^^
  File "/Users/user/Desktop/heumsi/repos/hollys/hollys/page/query/__init__.py", line 85, in content
    pc.foreach(
  File "/Users/user/Desktop/heumsi/repos/hollys/.venv/lib/python3.11/site-packages/pynecone/components/layout/foreach.py", line 40, in create
    children=[IterTag.render_component(render_fn, arg=arg)],
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/Desktop/heumsi/repos/hollys/.venv/lib/python3.11/site-packages/pynecone/components/tags/iter_tag.py", line 70, in render_component
    component = render_fn(arg)
                ^^^^^^^^^^^^^^
  File "/Users/user/Desktop/heumsi/repos/hollys/hollys/page/query/__init__.py", line 98, in <lambda>
    pc.icon(
  File "/Users/user/Desktop/heumsi/repos/hollys/.venv/lib/python3.11/site-packages/pynecone/components/component.py", line 300, in create
    return cls(children=children, **props)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/Desktop/heumsi/repos/hollys/.venv/lib/python3.11/site-packages/pynecone/components/component.py", line 127, in __init__
    kwargs["event_triggers"][key] = self._create_event_chain(key, value)
                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/Desktop/heumsi/repos/hollys/.venv/lib/python3.11/site-packages/pynecone/components/component.py", line 173, in _create_event_chain
    events = [utils.call_event_handler(v, arg) for v in value]
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/Desktop/heumsi/repos/hollys/.venv/lib/python3.11/site-packages/pynecone/components/component.py", line 173, in <listcomp>
    events = [utils.call_event_handler(v, arg) for v in value]
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/Desktop/heumsi/repos/hollys/.venv/lib/python3.11/site-packages/pynecone/utils.py", line 1081, in call_event_handler
    args = inspect.getfullargspec(event_handler.fn).args
                                  ^^^^^^^^^^^^^^^^
AttributeError: 'function' object has no attribute 'fn'

To Reproduce Steps to reproduce the behavior:

  • Code/Link to Repo:
class QueryState(BaseState):
    label: str
    labels: List[str] = []
    nodes: List[str] = api.get_nodes()

    def add_label(self) -> None:
        if not self.label:
            return
        self.labels += [self.label]

    def remove_label(self, label: str) -> None:
        self.labels = [_label for _label in self.labels if _label != label]

    def reset_label(self) -> None:
        self.label = ""

    def reset_labels(self) -> None:
        self.labels = []

    def reset(self):
        return [self.reset_labels(), self.refresh_nodes()]

    def refresh_nodes(self) -> None:
        self.nodes = api.get_nodes(self.labels)

pc.box(
    pc.foreach(
        QueryState.labels,
        lambda label: pc.hstack(
            pc.box(
                pc.text(label),
                width="fit-content",
                margin="0.5rem",
                margin_right="0rem",
                padding="0.5rem",
                display="inline-block",
                bg=style.get_color("gray", 50),
                font_size="sm",
            ),
            pc.icon(
                tag="CloseIcon",
                margin="0",
                pading="0",
                color=style.get_color("gray", 300),
                font_size="0.5rem",
                _hover={
                    "color": "#000000",
                    "cursor": "pointer",
                },
                on_click=[
                    lambda: QueryState.remove_label(label),
                    QueryState.refresh_node,
                ],
            ),
        ),
    ),
    min_height="50px",
    padding="1rem",
)

Expected behavior A clear and concise description of what you expected to happen.

Even if click_on contains a lambda inside the chain of event triggers, there should be no errors.

on_click=[
    lambda: QueryState.remove_label(label),
    QueryState.refresh_node,
]

is this intended? Am I misunderstanding how to use it?

Are there any other possible ways now to use the above?

Screenshots If applicable, add screenshots to help explain your problem.

** Specifics (please complete the following information):**

  • Python Version: 3.11.0
  • Pynecone Version: 0.1.13
  • OS: Mac OS Monetrey 12.6
  • Browser (Optional): Chrome 109.0.5414.87 arm 64

Additional context Add any other context about the problem here.

heumsi avatar Jan 23 '23 06:01 heumsi

Might be related to #317

The error is the same as when using partial in event chain so it's probably the same problem.

Lendemor avatar Jan 23 '23 10:01 Lendemor

Might be related to #317

The error is the same as when using partial in event chain so it's probably the same problem.

Yeah I think we need to add support for this, will prioritize even chain issues

Alek99 avatar Jan 24 '23 02:01 Alek99