gradio-app / gradio

Build and share delightful machine learning apps, all in Python. 🌟 Star to support our work!
http://www.gradio.app
Apache License 2.0
33.39k stars 2.52k forks source link

Choice updates to dropdowns are forgotten when component is re-renderred with a key #9364

Open QuantumTM opened 1 month ago

QuantumTM commented 1 month ago

Describe the bug

Observed Issue

Dropdown components 'forget' any updated choices they may have received when re-renderred (using gr.render) even though they are key'd. This causes the options to no longer be populated/selectable, and the value to also be drop (see below for caveats)

Additional Notes/Testing

The value of the effected dropdown is visually lost, but updating the dropdown to have the choices it had before the re-render appears to restore the value to what it was previously. Tweaking the reproduction script to output the dropdown value (via button click) show the value is still set, and adding allow_custom_value=True to the dropdown avoids the visual lose of the selected value. Notable, no warning is raised when allow_custom_value=False even thought the selected value is not in the choices (not sure if it would be expected in this case).

related issues

There's no directly related issues, but this issue might share the same root cause as https://github.com/gradio-app/gradio/issues/9207 though I think the effect of this is different enough to warrant its own issue.

Have you searched existing issues? 🔎

Reproduction

import gradio as gr

dropdown_letter = ['a', 'w']
dropdown_cont = {'a': ['b', 'c', 'd', 'e'], 'w': ['x', 'y', 'z']}

def main():
    with gr.Blocks() as demo:
        items = gr.State(0)

        with gr.Column():
            def add_item(items_value):
                return items_value + 1

            button = gr.Button('Add item')
            button.click(add_item, inputs=[items], outputs=[items])

            @gr.render(items)
            def _(item_count):
                for i in range(item_count):
                    with gr.Row():
                        d_letter = gr.Dropdown(choices=dropdown_letter, label='Type', key=f'letter_{i}')
                        d_cont = gr.Dropdown(label='Value', interactive=True, key=f'cont_{i}')

                        def dd_change(d_letter_value):
                            if not d_letter_value:
                                return None
                            return gr.Dropdown(choices=dropdown_cont[d_letter_value], key=f'cont_{i}')

                        d_letter.change(
                            dd_change,
                            inputs=[d_letter],
                            outputs=[d_cont]
                        )

    demo.launch()

if __name__ == '__main__':
    main()

Screenshot

No response

Logs

No response

System Info

Gradio Environment Information:
------------------------------
Operating System: Linux
gradio version: 4.44.0
gradio_client version: 1.3.0

------------------------------------------------
gradio dependencies in your environment:

aiofiles: 23.2.1
anyio: 4.4.0
fastapi: 0.114.2
ffmpy: 0.4.0
gradio-client==1.3.0 is not installed.
httpx: 0.27.2
huggingface-hub: 0.24.7
importlib-resources: 6.4.5
jinja2: 3.1.4
markupsafe: 2.1.5
matplotlib: 3.9.2
numpy: 2.1.1
orjson: 3.10.7
packaging: 24.1
pandas: 2.2.2
pillow: 10.4.0
pydantic: 2.9.1
pydub: 0.25.1
python-multipart: 0.0.9
pyyaml: 6.0.2
ruff: 0.6.5
semantic-version: 2.10.0
tomlkit==0.12.0 is not installed.
typer: 0.12.5
typing-extensions: 4.12.2
urllib3: 2.2.3
uvicorn: 0.30.6
authlib; extra == 'oauth' is not installed.
itsdangerous; extra == 'oauth' is not installed.

gradio_client dependencies in your environment:

fsspec: 2024.9.0
httpx: 0.27.2
huggingface-hub: 0.24.7
packaging: 24.1
typing-extensions: 4.12.2
websockets: 12.0

Severity

Blocking usage of gradio

(edit: formatting)

justintemps commented 4 weeks ago

Having the same issue.