diff --git a/.changeset/funny-dodos-sip.md b/.changeset/funny-dodos-sip.md new file mode 100644 index 000000000000..86297236b397 --- /dev/null +++ b/.changeset/funny-dodos-sip.md @@ -0,0 +1,5 @@ +--- +"gradio": minor +--- + +feat:V4: Fix constructor_args diff --git a/gradio/blocks.py b/gradio/blocks.py index 471036eae122..455608a9f4ed 100644 --- a/gradio/blocks.py +++ b/gradio/blocks.py @@ -113,7 +113,7 @@ def __init__( self._skip_init_processing = _skip_init_processing self.parent: BlockContext | None = None self.is_rendered: bool = False - self.constructor_args: dict + self._constructor_args: dict self.state_session_capacity = 10000 if render: @@ -123,6 +123,16 @@ def __init__( def skip_api(self): return False + @property + def constructor_args(self) -> dict[str, Any]: + """Get the arguments passed to the component's initializer. + + Only set classes whose metaclass is ComponentMeta + """ + # the _constructor_args list is appended based on the mro of the class + # so the first entry is for the bottom of the hierarchy + return self._constructor_args[0] if self._constructor_args else {} + @property def events( self, diff --git a/gradio/component_meta.py b/gradio/component_meta.py index a2a2fc7d2426..377a474aa9d3 100644 --- a/gradio/component_meta.py +++ b/gradio/component_meta.py @@ -139,12 +139,14 @@ def updateable(fn): def wrapper(*args, **kwargs): fn_args = inspect.getfullargspec(fn).args self = args[0] + if not hasattr(self, "_constructor_args"): + self._constructor_args = [] for i, arg in enumerate(args): if i == 0 or i >= len(fn_args): # skip self, *args continue arg_name = fn_args[i] kwargs[arg_name] = arg - self.constructor_args = kwargs + self._constructor_args.append(kwargs) if in_event_listener(): return None else: diff --git a/gradio/events.py b/gradio/events.py index aeacd319e03d..f2d27efff161 100644 --- a/gradio/events.py +++ b/gradio/events.py @@ -287,7 +287,7 @@ def inner(*args, **kwargs): if Context.root_block is None: raise AttributeError( - "Cannot call {self.event_name} outside of a gradio.Blocks context." + f"Cannot call {_event_name} outside of a gradio.Blocks context." ) dep, dep_index = Context.root_block.set_event_trigger( diff --git a/test/test_components.py b/test/test_components.py index b10871bd14bb..40bbf78376aa 100644 --- a/test/test_components.py +++ b/test/test_components.py @@ -2649,3 +2649,11 @@ def test_component_class_ids(): # Make sure that the ids are unique assert len({button_id, textbox_id, json_id, microphone_id, audio_id}) == 5 + + +def test_constructor_args(): + assert gr.Textbox(max_lines=314).constructor_args == {"max_lines": 314} + assert gr.LoginButton(icon="F00.svg", value="Log in please").constructor_args == { + "icon": "F00.svg", + "value": "Log in please", + }