Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ No changes to highlight.
* Gradio now supports batched functions by [@abidlabs](https://github.com/abidlabs) in [PR 2218](https://github.com/gradio-app/gradio/pull/2218)
* Add `upload` event for `Video`, `Audio`, `Image`, and `File` components [@dawoodkhan82](https://github.com/dawoodkhan82) in [PR 2448](https://github.com/gradio-app/gradio/pull/2456)
* Changes websocket path for Spaces as it is no longer necessary to have a different URL for websocket connections on Spaces by [@abidlabs](https://github.com/abidlabs) in [PR 2528](https://github.com/gradio-app/gradio/pull/2528)
* Clearer error message when events are defined outside of a Blocks scope, or if you
try to use `Series` or `Parallel` with `Blocks` by [@abidlabs](https://github.com/abidlabs) in [PR 2543](https://github.com/gradio-app/gradio/pull/2543)


## Contributors Shoutout:
No changes to highlight.
Expand Down
5 changes: 5 additions & 0 deletions gradio/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import time
import warnings
import webbrowser
from tkinter import N
from types import ModuleType
from typing import (
TYPE_CHECKING,
Expand Down Expand Up @@ -162,6 +163,10 @@ def set_event_trigger(
inputs = [inputs]
if not isinstance(outputs, list):
outputs = [outputs]
if Context.root_block is None:
raise AttributeError(
f"{event_name}() and other events can only be called within a Blocks context."
)
Context.root_block.fns.append(BlockFunction(fn, preprocess, postprocess))
if api_name is not None:
api_name_ = utils.append_unique_suffix(
Expand Down
5 changes: 5 additions & 0 deletions gradio/mix.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ def __init__(self, *interfaces: gradio.Interface, **options):
outputs: List[IOComponent] = []

for interface in interfaces:
if not (isinstance(interface, gradio.Interface)):
raise TypeError("Parallel requires all inputs to be of type Interface.")
outputs.extend(interface.output_components)

async def parallel_fn(*args):
Expand Down Expand Up @@ -108,6 +110,9 @@ async def connected_fn(*data):
return data[0]
return data

for interface in interfaces:
if not (isinstance(interface, gradio.Interface)):
raise TypeError("Series requires all inputs to be of type Interface.")
connected_fn.__name__ = " => ".join([io.__name__ for io in interfaces])

kwargs = {
Expand Down
16 changes: 16 additions & 0 deletions test/test_events.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import pytest

import gradio as gr


class TestEventErrors:
def test_event_defined_invalid_scope(self):
with gr.Blocks() as demo:
textbox = gr.Textbox()
textbox.blur(lambda x: x + x, textbox, textbox)

with pytest.raises(AttributeError):
demo.load(lambda: "hello", None, textbox)

with pytest.raises(AttributeError):
textbox.change(lambda x: x + x, textbox, textbox)