Skip to content

Commit

Permalink
Remove deprecation warning from gr.update and clean up associated c…
Browse files Browse the repository at this point in the history
…ode (#5890)

* update

* add changeset

* remove

* add changeset

* test

* update

* changes

* revert

* fix tests

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
  • Loading branch information
abidlabs and gradio-pr-bot committed Oct 16, 2023
1 parent f0e76a0 commit c4ba832
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 93 deletions.
5 changes: 5 additions & 0 deletions .changeset/tall-tables-sing.md
@@ -0,0 +1,5 @@
---
"gradio": patch
---

fix:Remove deprecation warning from `gr.update` and clean up associated code
14 changes: 1 addition & 13 deletions gradio/blocks.py
Expand Up @@ -225,14 +225,6 @@ def get_config(self):
def update(**kwargs) -> dict:
return {}

@classmethod
def get_specific_update(cls, generic_update: dict[str, Any]) -> dict:
generic_update = generic_update.copy()
del generic_update["__type__"]
specific_update = cls.update(**generic_update)
specific_update = utils.delete_none(specific_update, skip_value=True)
return specific_update


class BlockContext(Block):
def __init__(
Expand Down Expand Up @@ -344,16 +336,13 @@ def __repr__(self):
def postprocess_update_dict(block: Block, update_dict: dict, postprocess: bool = True):
"""
Converts a dictionary of updates into a format that can be sent to the frontend.
E.g. {"__type__": "generic_update", "value": "2", "interactive": False}
E.g. {"__type__": "update", "value": "2", "interactive": False}
Into -> {"__type__": "update", "value": 2.0, "mode": "static"}
Parameters:
block: The Block that is being updated with this update dictionary.
update_dict: The original update dictionary
postprocess: Whether to postprocess the "value" key of the update dictionary.
"""
if update_dict.get("__type__", "") == "generic_update":
update_dict = block.get_specific_update(update_dict)
if update_dict.get("value") is components._Keywords.NO_VALUE:
update_dict.pop("value")
interactive = update_dict.pop("interactive", None)
Expand Down Expand Up @@ -1445,7 +1434,6 @@ def postprocess_data(
args["_skip_init_processing"] = not block_fn.postprocess
state[output_id] = self.blocks[output_id].__class__(**args)

assert isinstance(prediction_value, dict)
prediction_value = postprocess_update_dict(
block=state[output_id],
update_dict=prediction_value,
Expand Down
51 changes: 19 additions & 32 deletions gradio/helpers.py
Expand Up @@ -788,53 +788,40 @@ def special_args(
return inputs or [], progress_index, event_data_index


def update(**kwargs) -> dict:
def update(
elem_id: str | None = None,
elem_classes: list[str] | str | None = None,
visible: bool | None = None,
**kwargs,
) -> dict:
"""
DEPRECATED. Updates component properties. When a function passed into a Gradio Interface or a Blocks events returns a typical value, it updates the value of the output component. But it is also possible to update the properties of an output component (such as the number of lines of a `Textbox` or the visibility of an `Image`) by returning the component's `update()` function, which takes as parameters any of the constructor parameters for that component.
This is a shorthand for using the update method on a component.
For example, rather than using gr.Number.update(...) you can just use gr.update(...).
Note that your editor's autocompletion will suggest proper parameters
if you use the update method on the component.
Demos: blocks_essay, blocks_update, blocks_essay_update
Updates a component's properties. When a function passed into a Gradio Interface or a Blocks events returns a value, it typically updates the value of the output component. But it is also possible to update the *properties* of an output component (such as the number of lines of a `Textbox` or the visibility of an `Row`) by returning a component and passing in the parameters to update in the constructor of the component. Alternatively, you can return `gr.update(...)` with any arbitrary parameters to update. (This is useful as a shorthand or if the same function can be called with different components to update.)
Parameters:
kwargs: Key-word arguments used to update the component's properties.
elem_id: Use this to update the id of the component in the HTML DOM
elem_classes: Use this to update the classes of the component in the HTML DOM
visible: Use this to update the visibility of the component
kwargs: Any other keyword arguments to update the component's properties.
Example:
# Blocks Example
import gradio as gr
with gr.Blocks() as demo:
radio = gr.Radio([1, 2, 4], label="Set the value of the number")
number = gr.Number(value=2, interactive=True)
radio.change(fn=lambda value: gr.update(value=value), inputs=radio, outputs=number)
demo.launch()
# Interface example
import gradio as gr
def change_textbox(choice):
if choice == "short":
return gr.Textbox.update(lines=2, visible=True)
elif choice == "long":
return gr.Textbox.update(lines=8, visible=True)
else:
return gr.Textbox.update(visible=False)
gr.Interface(
change_textbox,
gr.Radio(
["short", "long", "none"], label="What kind of essay would you like to write?"
),
gr.Textbox(lines=2),
live=True,
).launch()
"""
warnings.warn(
"Using the update method is deprecated. Simply return a new object instead, e.g. `return gr.Textbox(...)` instead of `return gr.update(...)"
)
kwargs["__type__"] = "generic_update"
kwargs["__type__"] = "update"
if elem_id is not None:
kwargs["elem_id"] = elem_id
if elem_classes is not None:
kwargs["elem_classes"] = elem_classes
if visible is not None:
kwargs["visible"] = visible
return kwargs


def skip() -> dict:
return {"__type__": "generic_update"}
return {"__type__": "update"}


@document()
Expand Down
49 changes: 1 addition & 48 deletions test/test_blocks.py
Expand Up @@ -1176,54 +1176,7 @@ def batch_fn(x, y):
await demo.process_api(0, [["A", "B", "C"], ["D", "E"]], state=None)


class TestSpecificUpdate:
def test_without_update(self):
with pytest.raises(KeyError):
gr.Textbox.get_specific_update({"lines": 4})

def test_with_update(self):
specific_update = gr.Textbox.get_specific_update(
{"lines": 4, "__type__": "update", "interactive": False}
)
assert specific_update == {
"lines": 4,
"value": gr.components._Keywords.NO_VALUE,
"interactive": False,
"__type__": "update",
}

specific_update = gr.Textbox.get_specific_update(
{"lines": 4, "__type__": "update", "interactive": True}
)
assert specific_update == {
"lines": 4,
"value": gr.components._Keywords.NO_VALUE,
"interactive": True,
"__type__": "update",
}

def test_with_generic_update(self):
specific_update = gr.Video.get_specific_update(
{
"visible": True,
"value": "test.mp4",
"__type__": "generic_update",
"interactive": True,
"container": None,
"height": None,
"min_width": None,
"scale": None,
"width": None,
"show_share_button": None,
}
)
assert specific_update == {
"visible": True,
"value": "test.mp4",
"interactive": True,
"__type__": "update",
}

class TestUpdate:
@pytest.mark.asyncio
async def test_accordion_update(self):
with gr.Blocks() as demo:
Expand Down

0 comments on commit c4ba832

Please sign in to comment.