diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e80daaa8c..cbbc3b2c43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,8 +50,9 @@ inference time of 80 seconds). ## Bug Fixes: * Fixes issue where plotly animations, interactivity, titles, legends, were not working properly. [@dawoodkhan82](https://github.com/dawoodkhan82) in [PR 2486](https://github.com/gradio-app/gradio/pull/2486) -* Prevent requests to the `/api` endpoint from skipping the queue if the queue is enabled for that event - by [@freddyaboulton](https://github.com/freddyaboulton) in [PR 2493](https://github.com/gradio-app/gradio/pull/2493) +* Prevent requests to the `/api` endpoint from skipping the queue if the queue is enabled for that event by [@freddyaboulton](https://github.com/freddyaboulton) in [PR 2493](https://github.com/gradio-app/gradio/pull/2493) +* Fixes a bug with `cancels` in event triggers so that it works properly if multiple +Blocks are rendered by [@abidlabs](https://github.com/abidlabs) in [PR 2530](https://github.com/gradio-app/gradio/pull/2530) ## Documentation Changes: * Added an example interactive dashboard to the "Tabular & Plots" section of the Demos page by [@freddyaboulton](https://github.com/freddyaboulton) in [PR 2508](https://github.com/gradio-app/gradio/pull/2508) diff --git a/gradio/blocks.py b/gradio/blocks.py index c0f814a186..ffb53ce26a 100644 --- a/gradio/blocks.py +++ b/gradio/blocks.py @@ -621,6 +621,7 @@ class Blocks(BlockContext): Context.root_block.blocks.update(self.blocks) Context.root_block.fns.extend(self.fns) + dependency_offset = len(Context.root_block.dependencies) for dependency in self.dependencies: api_name = dependency["api_name"] if api_name is not None: @@ -635,6 +636,9 @@ class Blocks(BlockContext): ) ) dependency["api_name"] = api_name_ + dependency["cancels"] = [ + c + dependency_offset for c in dependency["cancels"] + ] Context.root_block.dependencies.append(dependency) Context.root_block.temp_dirs = Context.root_block.temp_dirs | self.temp_dirs diff --git a/test/test_blocks.py b/test/test_blocks.py index a4073c849b..93888f244a 100644 --- a/test/test_blocks.py +++ b/test/test_blocks.py @@ -760,6 +760,40 @@ class TestCancel: captured = capsys.readouterr() assert "HELLO FROM LONG JOB" not in captured.out + @pytest.mark.skipif( + sys.version_info < (3, 8), + reason="Tasks dont have names in 3.7", + ) + @pytest.mark.asyncio + async def test_cancel_function_with_multiple_blocks(self, capsys): + async def long_job(): + await asyncio.sleep(10) + print("HELLO FROM LONG JOB") + + with gr.Blocks() as demo1: + textbox = gr.Textbox() + button1 = gr.Button(value="Start") + button1.click(lambda x: x, textbox, textbox) + with gr.Blocks() as demo2: + button2 = gr.Button(value="Start") + click = button2.click(long_job, None, None) + cancel = gr.Button(value="Cancel") + cancel.click(None, None, None, cancels=[click]) + + with gr.Blocks() as demo: + with gr.Tab("Demo 1"): + demo1.render() + with gr.Tab("Demo 2"): + demo2.render() + + cancel_fun = demo.fns[-1].fn + + task = asyncio.create_task(long_job()) + task.set_name("foo_0") + await asyncio.gather(task, cancel_fun("foo"), return_exceptions=True) + captured = capsys.readouterr() + assert "HELLO FROM LONG JOB" not in captured.out + def test_raise_exception_if_cancelling_an_event_thats_not_queued(self): def iteration(a): yield a