posit-dev / posit-dev/py-shiny

When `@event(ignore_none=True, ignore_init=True)` is used, should the initial `None` count as an initial value?

Open
#67 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
1.8k
Forks
135
Avg merge
2d 18h
Merged PRs (30d)
21

Description

When @event() is used with both ignore_none=True (the default) and ignore_init=True (not default), a starting None value due to an unpopulated input can count as the initial value. This can happen when an input is part of dynamic UI.

This example app illustrates how static and dynamic UI behaves differently.

from shiny import *

app_ui = ui.page_fluid(
    ui.input_text("static_txt", "Static text input", "starting value"),
    ui.tags.p("@event()"),
    ui.output_text_verbatim("static_txt_value", placeholder=True),
    ui.tags.p("@event(ignore_init=True)"),
    ui.output_text_verbatim("static_txt_noinit_value", placeholder=True),
    ui.tags.hr(),
    ui.output_ui("dyn_ui"),
    ui.tags.p("@event()"),
    ui.output_text_verbatim("dyn_txt_value", placeholder=True),
    ui.tags.p("@event(ignore_init=True)"),
    ui.output_text_verbatim("dyn_txt_noinit_value", placeholder=True),
)


def server(input: Inputs, output: Outputs, session: Session):
    @output()
    @render_text()
    @event(input.static_txt)
    def static_txt_value():
        return str(input.static_txt())

    @output()
    @render_text()
    @event(input.static_txt, ignore_init=True)
    def static_txt_noinit_value():
        return str(input.static_txt())

    @output()
    @render_text()
    @event(input.dyn_txt)
    def dyn_txt_value():
        return str(input.dyn_txt())

    @output()
    @render_text()
    @event(input.dyn_txt, ignore_init=True)
    def dyn_txt_noinit_value():
        return str(input.dyn_txt())

    # UI component for dynamic text input
    @output()
    @render_ui()
    def dyn_ui():
        return ui.input_text("dyn_txt", "Dynamic input text", "starting value")


app = App(app_ui, server, debug=True)

In the screenshot below, with @event(ignore_init=True), the static case shows nothing, but the dynamic case shows starting value. This is because, for the dynamic UI case, when unpopulated, input.dyn_txt() returns None, and that counts as an initial value.

image

This difference seems strange to me, especially if we specify types for input values, with something roughly like:

input.dyn_txt: reactiveValue[str]

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the supplied static and dynamic UI example with Python Shiny and the @event(ignore_none=True, ignore_init=True) combination. Trace the event handling behavior for an unpopulated dynamic input and compare it with the static case; done means the initial None is handled consistently with the intended ignore_init semantics and the behavior is covered by a regression test.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.