Spaces:
Sleeping
Sleeping
| """ | |
| Minimal reproduction of gr.HTML subclass bug with gr.Examples caching. | |
| Bug: When subclassing gr.HTML and using the custom component as an output | |
| in gr.Examples with cache_examples=True, Gradio throws: | |
| AttributeError: 'CustomHTMLComponent' object has no attribute 'info' | |
| The error occurs in gradio/components/base.py line 252 in get_config(): | |
| if self.info: | |
| This happens during example caching when Gradio tries to serialize the | |
| component's config. | |
| Environment: Gradio 6.x (tested with latest) | |
| To reproduce: | |
| 1. Run this app: python app.py | |
| 2. Click on any example | |
| 3. Observe the error in the terminal | |
| Workaround: Use gr.HTML directly via factory function instead of subclassing, | |
| and don't include the custom component in Examples outputs. | |
| """ | |
| import gradio as gr | |
| # Custom component that subclasses gr.HTML - THIS CAUSES THE BUG | |
| class CustomSlider(gr.HTML): | |
| """A simple custom slider component using gr.HTML templates.""" | |
| def __init__(self, value=50, **kwargs): | |
| html_template = """ | |
| <div style="padding: 20px; background: #f0f0f0; border-radius: 8px;"> | |
| <h3>Custom Slider: {{value}}</h3> | |
| <input type="range" min="0" max="100" value="{{value}}" | |
| style="width: 100%;" id="custom-slider"> | |
| </div> | |
| """ | |
| js_on_load = """ | |
| (() => { | |
| const slider = element.querySelector('#custom-slider'); | |
| slider.addEventListener('input', (e) => { | |
| props.value = parseInt(e.target.value); | |
| }); | |
| slider.addEventListener('change', (e) => { | |
| trigger('change', parseInt(e.target.value)); | |
| }); | |
| })(); | |
| """ | |
| super().__init__( | |
| value=value, | |
| html_template=html_template, | |
| js_on_load=js_on_load, | |
| **kwargs | |
| ) | |
| # Even adding api_info() doesn't fix the 'info' attribute error | |
| def api_info(self): | |
| return {"type": "integer", "minimum": 0, "maximum": 100} | |
| def process(text_input, slider_value): | |
| """Simple processing function that returns text and updates the custom slider.""" | |
| result_text = f"Processed: {text_input} with value {slider_value}" | |
| new_slider_value = slider_value # Return the same value to update custom component | |
| return result_text, new_slider_value | |
| with gr.Blocks() as demo: | |
| gr.Markdown(""" | |
| ## Bug Reproduction: gr.HTML Subclass with Examples Caching | |
| Click any example below to trigger the error: | |
| ``` | |
| AttributeError: 'CustomSlider' object has no attribute 'info' | |
| ``` | |
| """) | |
| with gr.Row(): | |
| with gr.Column(): | |
| text_input = gr.Textbox(label="Text Input", value="Hello") | |
| slider_input = gr.Slider(label="Slider", minimum=0, maximum=100, value=50) | |
| btn = gr.Button("Process") | |
| with gr.Column(): | |
| text_output = gr.Textbox(label="Output") | |
| # Custom component that causes the bug when used in Examples outputs | |
| custom_slider = CustomSlider(value=50, label="Custom Slider Output") | |
| btn.click( | |
| fn=process, | |
| inputs=[text_input, slider_input], | |
| outputs=[text_output, custom_slider] | |
| ) | |
| # THIS CAUSES THE BUG - including custom gr.HTML subclass in outputs with caching | |
| gr.Examples( | |
| examples=[ | |
| ["Example 1", 25], | |
| ["Example 2", 50], | |
| ["Example 3", 75], | |
| ], | |
| inputs=[text_input, slider_input], | |
| outputs=[text_output, custom_slider], # Bug: custom_slider causes AttributeError | |
| fn=process, | |
| cache_examples=True, # Bug only occurs with caching enabled | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch() |