Allow state to be rendered multiple times (#4030)

* state render

* add test

* formatting

* changelog
This commit is contained in:
Abubakar Abid 2023-05-01 18:53:51 -04:00 committed by GitHub
parent 398115b39a
commit f1ea4f79af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 5 deletions

View File

@ -6,7 +6,8 @@
## Bug Fixes:
No changes to highlight.
- Fixes bug where rendering the same `gr.State` across different Interfaces/Blocks within
a larger Blocks would not work by [@abidlabs](https://github.com/abidlabs) in [PR 4030](https://github.com/gradio-app/gradio/pull/4030)
## Documentation Changes:

View File

@ -843,10 +843,13 @@ class Blocks(BlockContext):
raise DuplicateBlockError(
f"A block with id: {self._id} has already been rendered in the current Blocks."
)
if not set(Context.root_block.blocks).isdisjoint(self.blocks):
raise DuplicateBlockError(
"At least one block in this Blocks has already been rendered."
)
overlapping_ids = set(Context.root_block.blocks).intersection(self.blocks)
for id in overlapping_ids:
# State componenents are allowed to be reused between Blocks
if not isinstance(self.blocks[id], components.State):
raise DuplicateBlockError(
"At least one block in this Blocks has already been rendered."
)
Context.root_block.blocks.update(self.blocks)
Context.root_block.fns.extend(self.fns)

View File

@ -1036,6 +1036,24 @@ class TestRender:
io3 = io2.render()
assert io2 == io3
def test_no_error_if_state_rendered_multiple_times(self):
state = gr.State("")
gr.TabbedInterface(
[
gr.Interface(
lambda _, x: (x, "I don't know"),
inputs=[state, gr.Textbox()],
outputs=[state, gr.Textbox()],
),
gr.Interface(
lambda s: (s, f"User question: {s}"),
inputs=[state],
outputs=[state, gr.Textbox(interactive=False)],
),
],
["Ask question", "Show question"],
)
class TestCancel:
@pytest.mark.skipif(