diff --git a/.changeset/chubby-hairs-beam.md b/.changeset/chubby-hairs-beam.md new file mode 100644 index 0000000000..78e3986753 --- /dev/null +++ b/.changeset/chubby-hairs-beam.md @@ -0,0 +1,6 @@ +--- +"gradio": minor +"gradio_client": minor +--- + +feat:Drop python 3.8 and 3.9 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 7ec3127cc3..33a2c936d0 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -25,6 +25,7 @@ jobs: uses: "gradio-app/gradio/.github/actions/install-all-deps@main" with: always_install_pnpm: true + python_version: "3.10" skip_build: "false" - name: Build packages run: | diff --git a/.github/workflows/storybook-build.yml b/.github/workflows/storybook-build.yml index 31cf484b11..2319a12822 100644 --- a/.github/workflows/storybook-build.yml +++ b/.github/workflows/storybook-build.yml @@ -52,6 +52,7 @@ jobs: - name: install dependencies uses: "gradio-app/gradio/.github/actions/install-all-deps@main" with: + python_version: "3.10" always_install_pnpm: true skip_build: "true" - name: build client diff --git a/.github/workflows/test-functional-lite.yml b/.github/workflows/test-functional-lite.yml index f9b7d6d387..6731594ecd 100644 --- a/.github/workflows/test-functional-lite.yml +++ b/.github/workflows/test-functional-lite.yml @@ -49,6 +49,8 @@ jobs: always_install_pnpm: true build_lite: true skip_build: true + python_version: "3.10" + test: true - run: pnpm exec playwright install chromium firefox - name: Run Lite E2E tests run: | diff --git a/.github/workflows/test-functional.yml b/.github/workflows/test-functional.yml index 4812b5f3ab..3cd4a13f71 100644 --- a/.github/workflows/test-functional.yml +++ b/.github/workflows/test-functional.yml @@ -47,7 +47,9 @@ jobs: uses: "gradio-app/gradio/.github/actions/install-all-deps@main" with: always_install_pnpm: true - - name: install outbreak_forecast dependencies + python_version: "3.10" + test: true + - name: install dependencies for specific tests run: | . venv/bin/activate python -m pip install -r demo/outbreak_forecast/requirements.txt diff --git a/.github/workflows/website-build.yml b/.github/workflows/website-build.yml index d4a2cfa4b7..87594bcc04 100644 --- a/.github/workflows/website-build.yml +++ b/.github/workflows/website-build.yml @@ -56,6 +56,7 @@ jobs: with: always_install_pnpm: true skip_build: true + python_version: "3.10" - name: build client run: pnpm --filter @gradio/client build diff --git a/.github/workflows/website-docs-build.yml b/.github/workflows/website-docs-build.yml index 7552b77a52..69a43d30e2 100644 --- a/.github/workflows/website-docs-build.yml +++ b/.github/workflows/website-docs-build.yml @@ -51,7 +51,9 @@ jobs: - name: install dependencies uses: "gradio-app/gradio/.github/actions/install-all-deps@main" with: + python_version: "3.10" skip_build: true + test: true # generated when installing deps - name: upload website json artifacts diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 47d8976c17..28ea87702f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,7 +7,7 @@ More than 200 awesome developers have contributed to the `gradio` library, and w Prerequisites: -- [Python 3.8+](https://www.python.org/downloads/) +- [Python 3.10+](https://www.python.org/downloads/) - [Node.js v16.14+](https://nodejs.dev/en/download/package-manager/) (only needed if you are making changes to the frontend) - [pnpm 8.1+](https://pnpm.io/8.x/installation) (only needed if you are making changes to the frontend) diff --git a/client/python/gradio_client/cli/deploy_discord.py b/client/python/gradio_client/cli/deploy_discord.py index 9a828a32a0..e653007428 100644 --- a/client/python/gradio_client/cli/deploy_discord.py +++ b/client/python/gradio_client/cli/deploy_discord.py @@ -1,7 +1,6 @@ -from typing import List, Optional +from typing import Annotated, Optional from typer import Option -from typing_extensions import Annotated from gradio_client import Client @@ -17,7 +16,7 @@ def main( str, Option(help="Discord bot token. Get one on the discord website.") ] = None, api_names: Annotated[ - List[str], Option(help="Api names to turn into discord bots") + list[str], Option(help="Api names to turn into discord bots") ] = None, to_id: Annotated[ Optional[str], Option(help="Name of the space used to host the discord bot") diff --git a/client/python/gradio_client/client.py b/client/python/gradio_client/client.py index 2d7ce6c0a1..8cb81e327c 100644 --- a/client/python/gradio_client/client.py +++ b/client/python/gradio_client/client.py @@ -16,13 +16,14 @@ import urllib.parse import uuid import warnings +from collections.abc import Callable from concurrent.futures import Future from dataclasses import dataclass from datetime import datetime from functools import partial from pathlib import Path from threading import Lock -from typing import Any, Callable, Literal +from typing import Any, Literal import httpx import huggingface_hub @@ -1303,7 +1304,11 @@ def download_files(self, *data) -> tuple: def remove_skipped_components(self, *data) -> tuple: """""" - data = [d for d, oct in zip(data, self.output_component_types) if not oct.skip] + data = [ + d + for d, oct in zip(data, self.output_component_types, strict=False) + if not oct.skip + ] return tuple(data) def reduce_singleton_output(self, *data) -> Any: diff --git a/client/python/gradio_client/compatibility.py b/client/python/gradio_client/compatibility.py index ca5f323b74..8348cf0c19 100644 --- a/client/python/gradio_client/compatibility.py +++ b/client/python/gradio_client/compatibility.py @@ -172,7 +172,7 @@ def _upload( "orig_name": Path(f).name, "data": None, } - for f, o in zip(fs, output) + for f, o in zip(fs, output, strict=False) ] else: o = next(o for ix, o in enumerate(result) if indices[ix] == i) @@ -207,7 +207,7 @@ def insert_state(self, *data) -> tuple: def remove_skipped_components(self, *data) -> tuple: data = [ d - for d, oct in zip(data, self.output_component_types) + for d, oct in zip(data, self.output_component_types, strict=False) if oct not in utils.SKIP_COMPONENTS ] return tuple(data) @@ -235,13 +235,15 @@ def serialize(self, *data) -> tuple: files = [ f - for f, t in zip(data, self.input_component_types) + for f, t in zip(data, self.input_component_types, strict=False) if t in ["file", "uploadbutton"] ] uploaded_files = self._upload(files) data = list(data) self._add_uploaded_files_to_data(uploaded_files, data) - o = tuple([s.serialize(d) for s, d in zip(self.serializers, data)]) + o = tuple( + [s.serialize(d) for s, d in zip(self.serializers, data, strict=False)] + ) return o def deserialize(self, *data) -> tuple: @@ -257,7 +259,7 @@ def deserialize(self, *data) -> tuple: hf_token=self.client.hf_token, root_url=self.root_url, ) - for s, d in zip(self.deserializers, data) + for s, d in zip(self.deserializers, data, strict=False) ] ) return outputs diff --git a/client/python/gradio_client/documentation.py b/client/python/gradio_client/documentation.py index 741ad78abb..a3ab654930 100644 --- a/client/python/gradio_client/documentation.py +++ b/client/python/gradio_client/documentation.py @@ -6,8 +6,8 @@ import inspect import warnings from collections import defaultdict +from collections.abc import Callable from functools import lru_cache -from typing import Callable classes_to_document = defaultdict(list) classes_inherit_documentation = {} diff --git a/client/python/gradio_client/utils.py b/client/python/gradio_client/utils.py index 1e5cc88c4c..ce08e0de24 100644 --- a/client/python/gradio_client/utils.py +++ b/client/python/gradio_client/utils.py @@ -13,12 +13,13 @@ import tempfile import time import warnings +from collections.abc import Callable, Coroutine from dataclasses import dataclass, field from datetime import datetime from enum import Enum from pathlib import Path from threading import Lock -from typing import TYPE_CHECKING, Any, Callable, Coroutine, Literal, Optional, TypedDict +from typing import TYPE_CHECKING, Any, Literal, Optional, TypedDict import fsspec.asyn import httpx diff --git a/client/python/pyproject.toml b/client/python/pyproject.toml index 54778eb45e..c7dcf0846f 100644 --- a/client/python/pyproject.toml +++ b/client/python/pyproject.toml @@ -7,7 +7,7 @@ name = "gradio_client" dynamic = ["version", "dependencies", "readme"] description = "Python library for easily interacting with trained machine learning models" license = "Apache-2.0" -requires-python = ">=3.8" +requires-python = ">=3.10" authors = [ { name = "Abubakar Abid", email = "gradio-team@huggingface.co" }, { name = "Ali Abid", email = "gradio-team@huggingface.co" }, diff --git a/gradio/_simple_templates/simpledropdown.py b/gradio/_simple_templates/simpledropdown.py index c1d8ad1423..3fbe8cebd9 100644 --- a/gradio/_simple_templates/simpledropdown.py +++ b/gradio/_simple_templates/simpledropdown.py @@ -1,7 +1,8 @@ from __future__ import annotations import warnings -from typing import TYPE_CHECKING, Any, Callable, Sequence +from collections.abc import Callable, Sequence +from typing import TYPE_CHECKING, Any from gradio.components.base import Component, FormComponent from gradio.events import Events diff --git a/gradio/_simple_templates/simpleimage.py b/gradio/_simple_templates/simpleimage.py index 712b843f60..9e33732178 100644 --- a/gradio/_simple_templates/simpleimage.py +++ b/gradio/_simple_templates/simpleimage.py @@ -2,8 +2,9 @@ from __future__ import annotations +from collections.abc import Sequence from pathlib import Path -from typing import TYPE_CHECKING, Any, Sequence +from typing import TYPE_CHECKING, Any from gradio_client import handle_file from gradio_client.documentation import document diff --git a/gradio/_simple_templates/simpletextbox.py b/gradio/_simple_templates/simpletextbox.py index 12aa16acb5..fb0eb4209a 100644 --- a/gradio/_simple_templates/simpletextbox.py +++ b/gradio/_simple_templates/simpletextbox.py @@ -1,6 +1,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, Callable, Sequence +from collections.abc import Callable, Sequence +from typing import TYPE_CHECKING, Any from gradio.components.base import Component, FormComponent from gradio.events import Events diff --git a/gradio/blocks.py b/gradio/blocks.py index f9ce3b6dc2..864c27fbcd 100644 --- a/gradio/blocks.py +++ b/gradio/blocks.py @@ -15,16 +15,13 @@ import warnings import webbrowser from collections import defaultdict +from collections.abc import AsyncIterator, Callable, Sequence, Set from pathlib import Path from types import ModuleType from typing import ( TYPE_CHECKING, - AbstractSet, Any, - AsyncIterator, - Callable, Literal, - Sequence, cast, ) from urllib.parse import urlparse, urlunparse @@ -681,14 +678,14 @@ def set_event_trigger( Component | BlockContext | Sequence[Component | BlockContext] - | AbstractSet[Component | BlockContext] + | Set[Component | BlockContext] | None ), outputs: ( Component | BlockContext | Sequence[Component | BlockContext] - | AbstractSet[Component | BlockContext] + | Set[Component | BlockContext] | None ), preprocess: bool = True, @@ -754,7 +751,7 @@ def set_event_trigger( ) for target in targets ] - if isinstance(inputs, AbstractSet): + if isinstance(inputs, Set): inputs_as_dict = True inputs = sorted(inputs, key=lambda x: x._id) else: @@ -764,7 +761,7 @@ def set_event_trigger( elif not isinstance(inputs, Sequence): inputs = [inputs] - if isinstance(outputs, AbstractSet): + if isinstance(outputs, Set): outputs = sorted(outputs, key=lambda x: x._id) elif outputs is None: outputs = [] @@ -1215,7 +1212,7 @@ def iterate_over_children(children_list): raise ValueError( "This config is missing the 'dependencies' field and cannot be loaded." ) - for dependency, fn in zip(config["dependencies"], fns): + for dependency, fn in zip(config["dependencies"], fns, strict=False): # We used to add a "fake_event" to the config to cache examples # without removing it. This was causing bugs in calling gr.load # We fixed the issue by removing "fake_event" from the config in examples.py @@ -1521,7 +1518,9 @@ async def call_function( if iterator is None: # If not a generator function that has already run if block_fn.inputs_as_dict: - processed_input = [dict(zip(block_fn.inputs, processed_input))] + processed_input = [ + dict(zip(block_fn.inputs, processed_input, strict=False)) + ] processed_input, progress_index, _ = special_args( block_fn.fn, processed_input, request, event_data @@ -1928,11 +1927,11 @@ async def process_api( ) inputs = [ await self.preprocess_data(block_fn, list(i), state, explicit_call) - for i in zip(*inputs) + for i in zip(*inputs, strict=False) ] result = await self.call_function( block_fn, - list(zip(*inputs)), + list(zip(*inputs, strict=False)), None, request, event_id, @@ -1943,11 +1942,11 @@ async def process_api( preds = result["prediction"] data = [ await self.postprocess_data(block_fn, list(o), state) - for o in zip(*preds) + for o in zip(*preds, strict=False) ] if root_path is not None: data = processing_utils.add_root_url(data, root_path, None) # type: ignore - data = list(zip(*data)) + data = list(zip(*data, strict=False)) is_generating, iterator = None, None else: old_iterator = iterator @@ -1972,7 +1971,9 @@ async def process_api( if state: changed_state_ids = [ state_id - for hash_value, state_id in zip(hashed_values, state_ids_to_track) + for hash_value, state_id in zip( + hashed_values, state_ids_to_track, strict=False + ) if hash_value != utils.deep_hash(state[state_id]) ] diff --git a/gradio/chat_interface.py b/gradio/chat_interface.py index 38f4ab9aff..2ddceeca24 100644 --- a/gradio/chat_interface.py +++ b/gradio/chat_interface.py @@ -8,7 +8,8 @@ import functools import inspect import warnings -from typing import AsyncGenerator, Callable, Literal, Union, cast +from collections.abc import AsyncGenerator, Callable +from typing import Literal, Union, cast import anyio from gradio_client.documentation import document diff --git a/gradio/cli/commands/components/_docs_utils.py b/gradio/cli/commands/components/_docs_utils.py index 855e15eb07..9b61b76889 100644 --- a/gradio/cli/commands/components/_docs_utils.py +++ b/gradio/cli/commands/components/_docs_utils.py @@ -145,31 +145,14 @@ def get_type_arguments(type_hint) -> tuple: def get_container_name(arg): """Gets a human readable name for a type.""" - - # This is a bit of a hack to get the generic type for python 3.8 - typing_genericalias = getattr(typing, "_GenericAlias", None) - types_genericalias = getattr(types, "GenericAlias", None) - types_uniontype = getattr(types, "UnionType", None) - if types_genericalias is None: - raise ValueError( - """Unable to find GenericAlias type. This is likely because you are using an older version of python. Please upgrade to python 3.10 or higher.""" - ) - - generic_type_tuple = ( - (types_genericalias,) - if typing_genericalias is None - else (types_genericalias, typing_genericalias) - ) - if inspect.isclass(arg): return arg.__name__ - if isinstance(arg, (generic_type_tuple)): + if isinstance(arg, types.GenericAlias): return arg.__origin__.__name__ - elif types_uniontype and isinstance(arg, types_uniontype): + elif isinstance(arg, types.UnionType): return "Union" elif getattr(arg, "__origin__", None) is typing.Literal: return "Literal" - else: return str(arg) diff --git a/gradio/cli/commands/components/build.py b/gradio/cli/commands/components/build.py index 3c0bfed5e1..0cefe66824 100644 --- a/gradio/cli/commands/components/build.py +++ b/gradio/cli/commands/components/build.py @@ -4,12 +4,11 @@ import shutil import subprocess from pathlib import Path -from typing import Optional +from typing import Annotated, Optional import semantic_version import typer from tomlkit import dump, parse -from typing_extensions import Annotated import gradio from gradio.analytics import custom_component_analytics diff --git a/gradio/cli/commands/components/create.py b/gradio/cli/commands/components/create.py index 59453e9173..410c1ddde8 100644 --- a/gradio/cli/commands/components/create.py +++ b/gradio/cli/commands/components/create.py @@ -2,14 +2,13 @@ import shutil from pathlib import Path -from typing import Optional +from typing import Annotated, Optional import typer from rich import print from rich.panel import Panel from rich.prompt import Confirm, Prompt from tomlkit import dump, parse -from typing_extensions import Annotated from gradio.analytics import custom_component_analytics @@ -156,14 +155,14 @@ def _create( pyproject_toml["project"]["license"] = license_ # type: ignore requires_python = Prompt.ask( - "\n:snake: Please enter the [bold][magenta]allowed python[/][/] versions for your component. Leave blank for '>=3.8'" + "\n:snake: Please enter the [bold][magenta]allowed python[/][/] versions for your component. Leave blank for '>=3.10'" ) - requires_python = requires_python or ">=3.8" + requires_python = requires_python or ">=3.10" print( f":snake: Using requires-python of [bold][magenta]{requires_python}[/][/]" ) pyproject_toml["project"]["requires-python"] = ( # type: ignore - requires_python or ">=3.8" + requires_python or ">=3.10" ) print( diff --git a/gradio/cli/commands/components/dev.py b/gradio/cli/commands/components/dev.py index 0563618500..025c5ea320 100644 --- a/gradio/cli/commands/components/dev.py +++ b/gradio/cli/commands/components/dev.py @@ -3,11 +3,10 @@ import shutil import subprocess from pathlib import Path -from typing import Optional +from typing import Annotated, Optional import typer from rich import print -from typing_extensions import Annotated import gradio from gradio.analytics import custom_component_analytics diff --git a/gradio/cli/commands/components/docs.py b/gradio/cli/commands/components/docs.py index 62e0c068c1..145d9073ab 100644 --- a/gradio/cli/commands/components/docs.py +++ b/gradio/cli/commands/components/docs.py @@ -3,12 +3,11 @@ import importlib import re from pathlib import Path -from typing import Any, Optional +from typing import Annotated, Any, Optional import requests import tomlkit as toml from typer import Argument, Option -from typing_extensions import Annotated from gradio.analytics import custom_component_analytics from gradio.cli.commands.display import LivePanelDisplay @@ -201,5 +200,5 @@ def run_command( if type_mode == "simple": live.update( - "\n:orange_circle: [red]The docs were generated in simple mode. Updating python to a version greater than 3.9 will result in richer documentation.[/]" + "\n:orange_circle: [red]The docs were generated in simple mode. Updating python to a more recent version will result in richer documentation.[/]" ) diff --git a/gradio/cli/commands/components/install_component.py b/gradio/cli/commands/components/install_component.py index 08092e76d7..6dd0a90573 100644 --- a/gradio/cli/commands/components/install_component.py +++ b/gradio/cli/commands/components/install_component.py @@ -3,11 +3,10 @@ import shutil import subprocess from pathlib import Path -from typing import Optional +from typing import Annotated, Optional from rich.markup import escape from typer import Argument, Option -from typing_extensions import Annotated from gradio.cli.commands.display import LivePanelDisplay from gradio.utils import set_directory diff --git a/gradio/cli/commands/components/publish.py b/gradio/cli/commands/components/publish.py index ff2bdc8d71..2affbe4172 100644 --- a/gradio/cli/commands/components/publish.py +++ b/gradio/cli/commands/components/publish.py @@ -4,7 +4,7 @@ import shutil import tempfile from pathlib import Path -from typing import List, Optional +from typing import Annotated, Optional import semantic_version from huggingface_hub import HfApi @@ -14,7 +14,6 @@ from rich.prompt import Confirm, Prompt from tomlkit import parse from typer import Argument, Option -from typing_extensions import Annotated from gradio.analytics import custom_component_analytics @@ -37,7 +36,7 @@ def _get_version_from_file(dist_file: Path) -> Optional[str]: return match.group(1) -def _get_max_version(distribution_files: List[Path]) -> Optional[str]: +def _get_max_version(distribution_files: list[Path]) -> Optional[str]: versions = [] for p in distribution_files: version = _get_version_from_file(p) diff --git a/gradio/cli/commands/deploy_space.py b/gradio/cli/commands/deploy_space.py index ad082d5817..e3f19a26bd 100644 --- a/gradio/cli/commands/deploy_space.py +++ b/gradio/cli/commands/deploy_space.py @@ -2,12 +2,11 @@ import os import re -from typing import Optional +from typing import Annotated, Optional import huggingface_hub from rich import print from typer import Option -from typing_extensions import Annotated import gradio as gr diff --git a/gradio/cli/commands/reload.py b/gradio/cli/commands/reload.py index 2468c74d43..5df9995980 100644 --- a/gradio/cli/commands/reload.py +++ b/gradio/cli/commands/reload.py @@ -16,7 +16,7 @@ import sys import threading from pathlib import Path -from typing import List, Optional +from typing import Optional import typer from rich import print @@ -106,7 +106,7 @@ def _setup_config( def main( demo_path: Path, demo_name: str = "demo", - watch_dirs: Optional[List[str]] = None, + watch_dirs: Optional[list[str]] = None, encoding: str = "utf-8", ): # default execution pattern to start the server and watch changes diff --git a/gradio/components/annotated_image.py b/gradio/components/annotated_image.py index 0cd79082f0..111743605e 100644 --- a/gradio/components/annotated_image.py +++ b/gradio/components/annotated_image.py @@ -2,7 +2,8 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, List, Sequence +from collections.abc import Sequence +from typing import TYPE_CHECKING, Any import gradio_client.utils as client_utils import numpy as np @@ -28,7 +29,7 @@ class Annotation(GradioModel): class AnnotatedImageData(GradioModel): image: FileData - annotations: List[Annotation] + annotations: list[Annotation] @document() diff --git a/gradio/components/audio.py b/gradio/components/audio.py index 6b8abd327f..34f7f3986c 100644 --- a/gradio/components/audio.py +++ b/gradio/components/audio.py @@ -4,8 +4,9 @@ import dataclasses import io +from collections.abc import Callable, Sequence from pathlib import Path -from typing import TYPE_CHECKING, Any, Callable, Literal, Sequence +from typing import TYPE_CHECKING, Any, Literal import anyio import httpx diff --git a/gradio/components/bar_plot.py b/gradio/components/bar_plot.py index c38422c389..f2adef960d 100644 --- a/gradio/components/bar_plot.py +++ b/gradio/components/bar_plot.py @@ -3,7 +3,8 @@ from __future__ import annotations import warnings -from typing import TYPE_CHECKING, Any, Callable, Literal, Sequence +from collections.abc import Callable, Sequence +from typing import TYPE_CHECKING, Any, Literal from gradio_client.documentation import document diff --git a/gradio/components/base.py b/gradio/components/base.py index 12690b2ba1..7606ae85d2 100644 --- a/gradio/components/base.py +++ b/gradio/components/base.py @@ -10,9 +10,10 @@ import sys import warnings from abc import ABC, abstractmethod +from collections.abc import Callable, Sequence from enum import Enum from pathlib import Path -from typing import TYPE_CHECKING, Any, Callable, Sequence, Type +from typing import TYPE_CHECKING, Any import gradio_client.utils as client_utils @@ -172,7 +173,7 @@ def __init__( # This gets overridden when `select` is called self._selectable = False if not hasattr(self, "data_model"): - self.data_model: Type[GradioDataModel] | None = None + self.data_model: type[GradioDataModel] | None = None Block.__init__( self, diff --git a/gradio/components/button.py b/gradio/components/button.py index 1b42620018..e53901092a 100644 --- a/gradio/components/button.py +++ b/gradio/components/button.py @@ -2,7 +2,8 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, Callable, Literal, Sequence +from collections.abc import Callable, Sequence +from typing import TYPE_CHECKING, Any, Literal from gradio_client.documentation import document diff --git a/gradio/components/chatbot.py b/gradio/components/chatbot.py index 74caf6ae3d..ceaaa9f1fe 100644 --- a/gradio/components/chatbot.py +++ b/gradio/components/chatbot.py @@ -3,19 +3,14 @@ from __future__ import annotations import inspect +from collections.abc import Callable, Sequence from dataclasses import dataclass, field from pathlib import Path from typing import ( TYPE_CHECKING, Any, - Callable, - Dict, - List, Literal, Optional, - Sequence, - Tuple, - Type, TypedDict, Union, cast, @@ -66,13 +61,13 @@ class FileMessage(GradioModel): class ComponentMessage(GradioModel): component: str value: Any - constructor_args: Dict[str, Any] - props: Dict[str, Any] + constructor_args: dict[str, Any] + props: dict[str, Any] class ChatbotDataTuples(GradioRootModel): - root: List[ - Tuple[ + root: list[ + tuple[ Union[str, FileMessage, ComponentMessage, None], Union[str, FileMessage, ComponentMessage, None], ] @@ -97,10 +92,10 @@ class ChatMessage: class ChatbotDataMessages(GradioRootModel): - root: List[Message] + root: list[Message] -TupleFormat = List[List[Union[str, Tuple[str], Tuple[str, str], None]]] +TupleFormat = list[list[Union[str, tuple[str], tuple[str, str], None]]] if TYPE_CHECKING: from gradio.components import Timer @@ -485,7 +480,7 @@ def postprocess( an object of type ChatbotData """ data_model = cast( - Union[Type[ChatbotDataTuples], Type[ChatbotDataMessages]], self.data_model + Union[type[ChatbotDataTuples], type[ChatbotDataMessages]], self.data_model ) if value is None: return data_model(root=[]) diff --git a/gradio/components/checkbox.py b/gradio/components/checkbox.py index e4dc833ed3..ba3a5daf1c 100644 --- a/gradio/components/checkbox.py +++ b/gradio/components/checkbox.py @@ -2,7 +2,8 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, Callable, Sequence +from collections.abc import Callable, Sequence +from typing import TYPE_CHECKING, Any from gradio_client.documentation import document diff --git a/gradio/components/checkboxgroup.py b/gradio/components/checkboxgroup.py index 95cbdf2b68..c25839aa4d 100644 --- a/gradio/components/checkboxgroup.py +++ b/gradio/components/checkboxgroup.py @@ -2,7 +2,8 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, Callable, Literal, Sequence +from collections.abc import Callable, Sequence +from typing import TYPE_CHECKING, Any, Literal from gradio_client.documentation import document diff --git a/gradio/components/clear_button.py b/gradio/components/clear_button.py index f1617a74b9..f8ba9c4048 100644 --- a/gradio/components/clear_button.py +++ b/gradio/components/clear_button.py @@ -4,7 +4,8 @@ import copy import json -from typing import TYPE_CHECKING, Any, Literal, Sequence +from collections.abc import Sequence +from typing import TYPE_CHECKING, Any, Literal from gradio_client.documentation import document diff --git a/gradio/components/code.py b/gradio/components/code.py index 4393294613..80220f57f7 100644 --- a/gradio/components/code.py +++ b/gradio/components/code.py @@ -2,7 +2,8 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, Callable, Literal, Sequence +from collections.abc import Callable, Sequence +from typing import TYPE_CHECKING, Any, Literal from gradio_client.documentation import document @@ -159,10 +160,15 @@ def postprocess(self, value: str | None) -> None | str: Parameters: value: Expects a `str` of code. Returns: - Returns the code as a `str`. + Returns the code as a `str` stripped of leading and trailing whitespace. """ if value is None: return None + if isinstance(value, tuple): + raise ValueError( + "Code component does not support returning files as tuples anymore. " + "Please read the file contents and return as str instead." + ) return value.strip() def api_info(self) -> dict[str, Any]: diff --git a/gradio/components/color_picker.py b/gradio/components/color_picker.py index 163732ad31..0eee7c20c1 100644 --- a/gradio/components/color_picker.py +++ b/gradio/components/color_picker.py @@ -2,7 +2,8 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, Callable, Sequence +from collections.abc import Callable, Sequence +from typing import TYPE_CHECKING, Any from gradio_client.documentation import document diff --git a/gradio/components/dataframe.py b/gradio/components/dataframe.py index 4dd6f1a04b..e1380db7de 100644 --- a/gradio/components/dataframe.py +++ b/gradio/components/dataframe.py @@ -3,16 +3,12 @@ from __future__ import annotations import warnings +from collections.abc import Callable, Sequence from typing import ( TYPE_CHECKING, Any, - Callable, - Dict, - List, Literal, Optional, - Sequence, - Tuple, Union, ) @@ -46,9 +42,9 @@ def _import_polars(): class DataframeData(GradioModel): - headers: List[str] - data: Union[List[List[Any]], List[Tuple[Any, ...]]] - metadata: Optional[Dict[str, Optional[List[Any]]]] = None + headers: list[str] + data: Union[list[list[Any]], list[tuple[Any, ...]]] + metadata: Optional[dict[str, Optional[list[Any]]]] = None @document() diff --git a/gradio/components/dataset.py b/gradio/components/dataset.py index 468087aef2..9551c0052f 100644 --- a/gradio/components/dataset.py +++ b/gradio/components/dataset.py @@ -3,7 +3,8 @@ from __future__ import annotations import warnings -from typing import Any, Literal, Sequence +from collections.abc import Sequence +from typing import Any, Literal from gradio_client.documentation import document @@ -99,7 +100,7 @@ def __init__( self.samples: list[list] = [] for example in self.raw_samples: self.samples.append([]) - for component, ex in zip(self._components, example): + for component, ex in zip(self._components, example, strict=False): # If proxy_url is set, that means it is being loaded from an external Gradio app # which means that the example has already been processed. if self.proxy_url is None: diff --git a/gradio/components/download_button.py b/gradio/components/download_button.py index 15c5aec9ed..6c34718c09 100644 --- a/gradio/components/download_button.py +++ b/gradio/components/download_button.py @@ -3,8 +3,9 @@ from __future__ import annotations import tempfile +from collections.abc import Callable, Sequence from pathlib import Path -from typing import TYPE_CHECKING, Callable, Literal, Sequence +from typing import TYPE_CHECKING, Literal from gradio_client import handle_file from gradio_client.documentation import document diff --git a/gradio/components/dropdown.py b/gradio/components/dropdown.py index 5102e09374..1abe4ebbdf 100644 --- a/gradio/components/dropdown.py +++ b/gradio/components/dropdown.py @@ -3,7 +3,8 @@ from __future__ import annotations import warnings -from typing import TYPE_CHECKING, Any, Callable, Literal, Sequence +from collections.abc import Callable, Sequence +from typing import TYPE_CHECKING, Any, Literal from gradio_client.documentation import document diff --git a/gradio/components/duplicate_button.py b/gradio/components/duplicate_button.py index 90f01bc4c2..0094e57243 100644 --- a/gradio/components/duplicate_button.py +++ b/gradio/components/duplicate_button.py @@ -2,7 +2,8 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Literal, Sequence +from collections.abc import Sequence +from typing import TYPE_CHECKING, Literal from gradio_client.documentation import document diff --git a/gradio/components/file.py b/gradio/components/file.py index 4bc4503cd7..70dbcfd995 100644 --- a/gradio/components/file.py +++ b/gradio/components/file.py @@ -4,8 +4,9 @@ import tempfile import warnings +from collections.abc import Callable, Sequence from pathlib import Path -from typing import TYPE_CHECKING, Any, Callable, Literal, Sequence +from typing import TYPE_CHECKING, Any, Literal import gradio_client.utils as client_utils from gradio_client import handle_file diff --git a/gradio/components/file_explorer.py b/gradio/components/file_explorer.py index 7f9ca06313..8ad9e957f1 100644 --- a/gradio/components/file_explorer.py +++ b/gradio/components/file_explorer.py @@ -4,8 +4,9 @@ import fnmatch import os +from collections.abc import Callable, Sequence from pathlib import Path -from typing import TYPE_CHECKING, Any, Callable, List, Literal, Sequence +from typing import TYPE_CHECKING, Any, Literal from gradio_client.documentation import document @@ -20,7 +21,7 @@ class FileExplorerData(GradioRootModel): # The outer list is the list of files selected, and the inner list # is the path to the file as a list, split by the os.sep. - root: List[List[str]] + root: list[list[str]] @document() diff --git a/gradio/components/gallery.py b/gradio/components/gallery.py index 7a514ab988..4e2b00bcf2 100644 --- a/gradio/components/gallery.py +++ b/gradio/components/gallery.py @@ -2,17 +2,14 @@ from __future__ import annotations +from collections.abc import Callable, Sequence from concurrent.futures import ThreadPoolExecutor from pathlib import Path from typing import ( TYPE_CHECKING, Any, - Callable, - List, Literal, Optional, - Sequence, - Tuple, Union, ) from urllib.parse import urlparse @@ -32,7 +29,7 @@ from gradio.components import Timer GalleryImageType = Union[np.ndarray, PIL.Image.Image, Path, str] -CaptionedGalleryImageType = Tuple[GalleryImageType, str] +CaptionedGalleryImageType = tuple[GalleryImageType, str] class GalleryImage(GradioModel): @@ -41,7 +38,7 @@ class GalleryImage(GradioModel): class GalleryData(GradioRootModel): - root: List[GalleryImage] + root: list[GalleryImage] @document() @@ -78,7 +75,7 @@ def __init__( elem_classes: list[str] | str | None = None, render: bool = True, key: int | str | None = None, - columns: int | list[int] | Tuple[int, ...] | None = 2, + columns: int | list[int] | tuple[int, ...] | None = 2, rows: int | list[int] | None = None, height: int | float | str | None = None, allow_preview: bool = True, @@ -163,9 +160,9 @@ def __init__( def preprocess( self, payload: GalleryData | None ) -> ( - List[tuple[str, str | None]] - | List[tuple[PIL.Image.Image, str | None]] - | List[tuple[np.ndarray, str | None]] + list[tuple[str, str | None]] + | list[tuple[PIL.Image.Image, str | None]] + | list[tuple[np.ndarray, str | None]] | None ): """ diff --git a/gradio/components/highlighted_text.py b/gradio/components/highlighted_text.py index 58a2486eec..17200579d6 100644 --- a/gradio/components/highlighted_text.py +++ b/gradio/components/highlighted_text.py @@ -2,7 +2,8 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, Callable, List, Sequence, Union +from collections.abc import Callable, Sequence +from typing import TYPE_CHECKING, Any, Union from gradio_client.documentation import document @@ -20,7 +21,7 @@ class HighlightedToken(GradioModel): class HighlightedTextData(GradioRootModel): - root: List[HighlightedToken] + root: list[HighlightedToken] @document() diff --git a/gradio/components/html.py b/gradio/components/html.py index e3fd3c17cb..eac6a277b4 100644 --- a/gradio/components/html.py +++ b/gradio/components/html.py @@ -2,7 +2,8 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, Callable, Sequence +from collections.abc import Callable, Sequence +from typing import TYPE_CHECKING, Any from gradio_client.documentation import document diff --git a/gradio/components/image.py b/gradio/components/image.py index 67ff6f9466..b4f7713718 100644 --- a/gradio/components/image.py +++ b/gradio/components/image.py @@ -3,8 +3,9 @@ from __future__ import annotations import warnings +from collections.abc import Callable, Sequence from pathlib import Path -from typing import TYPE_CHECKING, Any, Callable, Literal, Sequence, cast +from typing import TYPE_CHECKING, Any, Literal, cast import numpy as np import PIL.Image diff --git a/gradio/components/image_editor.py b/gradio/components/image_editor.py index b59798760b..4fa0bf8272 100644 --- a/gradio/components/image_editor.py +++ b/gradio/components/image_editor.py @@ -4,17 +4,14 @@ import dataclasses import warnings +from collections.abc import Iterable, Sequence from io import BytesIO from pathlib import Path from typing import ( TYPE_CHECKING, Any, - Iterable, - List, Literal, Optional, - Sequence, - Tuple, Union, cast, ) @@ -50,14 +47,14 @@ class EditorExampleValue(TypedDict): class EditorData(GradioModel): background: Optional[FileData] = None - layers: List[FileData] = [] + layers: list[FileData] = [] composite: Optional[FileData] = None id: Optional[str] = None class EditorDataBlobs(GradioModel): background: Optional[bytes] - layers: List[Union[bytes, None]] + layers: list[Union[bytes, None]] composite: Optional[bytes] @@ -70,7 +67,7 @@ class BlobData(TypedDict): class AcceptBlobs(GradioModel): data: BlobData - files: List[Tuple[str, bytes]] + files: list[tuple[str, bytes]] @document() diff --git a/gradio/components/json_component.py b/gradio/components/json_component.py index 5f57f89d71..7a8754af7e 100644 --- a/gradio/components/json_component.py +++ b/gradio/components/json_component.py @@ -3,11 +3,10 @@ from __future__ import annotations import json +from collections.abc import Callable, Sequence from typing import ( TYPE_CHECKING, Any, - Callable, - Sequence, ) import orjson diff --git a/gradio/components/label.py b/gradio/components/label.py index fd623111d8..21fdbe68e4 100644 --- a/gradio/components/label.py +++ b/gradio/components/label.py @@ -4,8 +4,9 @@ import json import operator +from collections.abc import Callable, Sequence from pathlib import Path -from typing import TYPE_CHECKING, Any, Callable, List, Optional, Sequence, Union +from typing import TYPE_CHECKING, Any, Optional, Union from gradio_client.documentation import document @@ -24,7 +25,7 @@ class LabelConfidence(GradioModel): class LabelData(GradioModel): label: Optional[Union[str, int, float]] = None - confidences: Optional[List[LabelConfidence]] = None + confidences: Optional[list[LabelConfidence]] = None @document() diff --git a/gradio/components/line_plot.py b/gradio/components/line_plot.py index ebddcc278c..c80b885989 100644 --- a/gradio/components/line_plot.py +++ b/gradio/components/line_plot.py @@ -3,7 +3,8 @@ from __future__ import annotations import warnings -from typing import TYPE_CHECKING, Any, Callable, Literal, Sequence +from collections.abc import Callable, Sequence +from typing import TYPE_CHECKING, Any, Literal from gradio_client.documentation import document diff --git a/gradio/components/login_button.py b/gradio/components/login_button.py index 35bba307fc..1a062a1ce4 100644 --- a/gradio/components/login_button.py +++ b/gradio/components/login_button.py @@ -5,7 +5,8 @@ import json import time import warnings -from typing import TYPE_CHECKING, Literal, Sequence +from collections.abc import Sequence +from typing import TYPE_CHECKING, Literal from gradio_client.documentation import document diff --git a/gradio/components/logout_button.py b/gradio/components/logout_button.py index 9cee4098ea..c064e7994e 100644 --- a/gradio/components/logout_button.py +++ b/gradio/components/logout_button.py @@ -3,7 +3,8 @@ from __future__ import annotations import warnings -from typing import TYPE_CHECKING, Literal, Sequence +from collections.abc import Sequence +from typing import TYPE_CHECKING, Literal from gradio_client.documentation import document diff --git a/gradio/components/markdown.py b/gradio/components/markdown.py index 265d65d68b..98e0489796 100644 --- a/gradio/components/markdown.py +++ b/gradio/components/markdown.py @@ -3,7 +3,8 @@ from __future__ import annotations import inspect -from typing import TYPE_CHECKING, Any, Callable, Sequence +from collections.abc import Callable, Sequence +from typing import TYPE_CHECKING, Any from gradio_client.documentation import document diff --git a/gradio/components/model3d.py b/gradio/components/model3d.py index f421b8a9ec..a4a6744c66 100644 --- a/gradio/components/model3d.py +++ b/gradio/components/model3d.py @@ -2,8 +2,9 @@ from __future__ import annotations +from collections.abc import Callable, Sequence from pathlib import Path -from typing import TYPE_CHECKING, Callable, Literal, Sequence +from typing import TYPE_CHECKING, Literal from gradio_client import handle_file from gradio_client.documentation import document diff --git a/gradio/components/multimodal_textbox.py b/gradio/components/multimodal_textbox.py index d91051a4c4..aee8ccfcf0 100644 --- a/gradio/components/multimodal_textbox.py +++ b/gradio/components/multimodal_textbox.py @@ -2,8 +2,9 @@ from __future__ import annotations +from collections.abc import Callable, Sequence from pathlib import Path -from typing import TYPE_CHECKING, Any, Callable, List, Literal, Sequence, TypedDict +from typing import TYPE_CHECKING, Any, Literal, TypedDict import gradio_client.utils as client_utils from gradio_client.documentation import document @@ -20,12 +21,12 @@ class MultimodalData(GradioModel): text: str - files: List[FileData] = Field(default_factory=list) + files: list[FileData] = Field(default_factory=list) class MultimodalPostprocess(TypedDict): text: str - files: List[FileData] + files: list[FileData] class MultimodalValue(TypedDict): diff --git a/gradio/components/native_plot.py b/gradio/components/native_plot.py index 8414fd68dc..c840660f7a 100644 --- a/gradio/components/native_plot.py +++ b/gradio/components/native_plot.py @@ -2,15 +2,11 @@ import json import warnings +from collections.abc import Callable, Sequence, Set from typing import ( TYPE_CHECKING, - AbstractSet, Any, - Callable, - Dict, - List, Literal, - Sequence, ) import pandas as pd @@ -25,9 +21,9 @@ class PlotData(GradioModel): - columns: List[str] - data: List[List[Any]] - datatypes: Dict[str, Literal["quantitative", "nominal", "temporal"]] + columns: list[str] + data: list[list[Any]] + datatypes: dict[str, Literal["quantitative", "nominal", "temporal"]] mark: str @@ -68,7 +64,7 @@ def __init__( scale: int | None = None, min_width: int = 160, every: Timer | float | None = None, - inputs: Component | Sequence[Component] | AbstractSet[Component] | None = None, + inputs: Component | Sequence[Component] | Set[Component] | None = None, visible: bool = True, elem_id: str | None = None, elem_classes: list[str] | str | None = None, diff --git a/gradio/components/number.py b/gradio/components/number.py index 05b2e21f2d..b79e201002 100644 --- a/gradio/components/number.py +++ b/gradio/components/number.py @@ -2,7 +2,8 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, Callable, Sequence +from collections.abc import Callable, Sequence +from typing import TYPE_CHECKING, Any from gradio_client.documentation import document diff --git a/gradio/components/paramviewer.py b/gradio/components/paramviewer.py index 1d20d81c2c..4b244694fe 100644 --- a/gradio/components/paramviewer.py +++ b/gradio/components/paramviewer.py @@ -1,6 +1,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Literal, Mapping, Sequence, TypedDict +from collections.abc import Mapping, Sequence +from typing import TYPE_CHECKING, Literal, TypedDict from gradio_client.documentation import document diff --git a/gradio/components/plot.py b/gradio/components/plot.py index 166ccac380..02c21b1531 100644 --- a/gradio/components/plot.py +++ b/gradio/components/plot.py @@ -3,8 +3,9 @@ from __future__ import annotations import json +from collections.abc import Sequence from types import ModuleType -from typing import TYPE_CHECKING, Any, Literal, Sequence +from typing import TYPE_CHECKING, Any, Literal from gradio_client.documentation import document diff --git a/gradio/components/radio.py b/gradio/components/radio.py index 414118eae4..16021eb2ed 100644 --- a/gradio/components/radio.py +++ b/gradio/components/radio.py @@ -2,7 +2,8 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, Callable, Literal, Sequence +from collections.abc import Callable, Sequence +from typing import TYPE_CHECKING, Any, Literal from gradio_client.documentation import document diff --git a/gradio/components/scatter_plot.py b/gradio/components/scatter_plot.py index 5351971a26..0557554864 100644 --- a/gradio/components/scatter_plot.py +++ b/gradio/components/scatter_plot.py @@ -3,7 +3,8 @@ from __future__ import annotations import warnings -from typing import TYPE_CHECKING, Any, Callable, Literal, Sequence +from collections.abc import Callable, Sequence +from typing import TYPE_CHECKING, Any, Literal from gradio_client.documentation import document diff --git a/gradio/components/slider.py b/gradio/components/slider.py index 384d3f3239..076df2faf1 100644 --- a/gradio/components/slider.py +++ b/gradio/components/slider.py @@ -4,7 +4,8 @@ import math import random -from typing import TYPE_CHECKING, Any, Callable, Sequence +from collections.abc import Callable, Sequence +from typing import TYPE_CHECKING, Any from gradio_client.documentation import document diff --git a/gradio/components/state.py b/gradio/components/state.py index 305ce37ec7..e77f3c81b6 100644 --- a/gradio/components/state.py +++ b/gradio/components/state.py @@ -3,8 +3,9 @@ from __future__ import annotations import math +from collections.abc import Callable from copy import deepcopy -from typing import Any, Callable +from typing import Any from gradio_client.documentation import document diff --git a/gradio/components/textbox.py b/gradio/components/textbox.py index 32202a9b04..7f38b3639e 100644 --- a/gradio/components/textbox.py +++ b/gradio/components/textbox.py @@ -2,7 +2,8 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, Callable, Literal, Sequence +from collections.abc import Callable, Sequence +from typing import TYPE_CHECKING, Any, Literal from gradio_client.documentation import document diff --git a/gradio/components/upload_button.py b/gradio/components/upload_button.py index a75cf757e7..d377cd73a8 100644 --- a/gradio/components/upload_button.py +++ b/gradio/components/upload_button.py @@ -4,8 +4,9 @@ import tempfile import warnings +from collections.abc import Callable, Sequence from pathlib import Path -from typing import TYPE_CHECKING, Any, Callable, Literal, Sequence +from typing import TYPE_CHECKING, Any, Literal import gradio_client.utils as client_utils from gradio_client import handle_file diff --git a/gradio/components/video.py b/gradio/components/video.py index 9f5bb4f862..8464f3a572 100644 --- a/gradio/components/video.py +++ b/gradio/components/video.py @@ -7,8 +7,9 @@ import subprocess import tempfile import warnings +from collections.abc import Callable, Sequence from pathlib import Path -from typing import TYPE_CHECKING, Any, Callable, Literal, Optional, Sequence +from typing import TYPE_CHECKING, Any, Literal, Optional from gradio_client import handle_file from gradio_client import utils as client_utils @@ -378,9 +379,10 @@ def _format_subtitle(self, subtitle: str | Path | None) -> FileData | None: def srt_to_vtt(srt_file_path, vtt_file_path): """Convert an SRT subtitle file to a VTT subtitle file""" - with open(srt_file_path, encoding="utf-8") as srt_file, open( - vtt_file_path, "w", encoding="utf-8" - ) as vtt_file: + with ( + open(srt_file_path, encoding="utf-8") as srt_file, + open(vtt_file_path, "w", encoding="utf-8") as vtt_file, + ): vtt_file.write("WEBVTT\n\n") for subtitle_block in srt_file.read().strip().split("\n\n"): subtitle_lines = subtitle_block.split("\n") diff --git a/gradio/data_classes.py b/gradio/data_classes.py index ba02f4d6d1..0311ea8f85 100644 --- a/gradio/data_classes.py +++ b/gradio/data_classes.py @@ -7,15 +7,13 @@ import secrets import shutil from abc import ABC, abstractmethod +from collections.abc import Iterator from enum import Enum, auto from typing import ( Any, - Iterator, - List, Literal, NewType, Optional, - Tuple, TypedDict, Union, ) @@ -42,7 +40,7 @@ class CancelBody(BaseModel): class SimplePredictBody(BaseModel): - data: List[Any] + data: list[Any] session_hash: Optional[str] = None @@ -51,7 +49,7 @@ class PredictBody(BaseModel): session_hash: Optional[str] = None event_id: Optional[str] = None - data: List[Any] + data: list[Any] event_data: Optional[Any] = None fn_index: Optional[int] = None trigger_id: Optional[int] = None @@ -96,7 +94,7 @@ class ComponentServerJSONBody(BaseModel): class DataWithFiles(BaseModel): data: Any - files: List[Tuple[str, bytes]] + files: list[tuple[str, bytes]] class ComponentServerBlobBody(BaseModel): @@ -268,7 +266,7 @@ def is_file_data(cls, obj: Any) -> bool: class ListFiles(GradioRootModel): - root: List[FileData] + root: list[FileData] def __getitem__(self, index): return self.root[index] diff --git a/gradio/events.py b/gradio/events.py index 243f466b65..cf35ff61ab 100644 --- a/gradio/events.py +++ b/gradio/events.py @@ -4,16 +4,12 @@ from __future__ import annotations import dataclasses +from collections.abc import Callable, Sequence, Set from functools import partial, wraps from typing import ( TYPE_CHECKING, - AbstractSet, Any, - Callable, - Dict, - List, Literal, - Sequence, Union, cast, ) @@ -322,7 +318,7 @@ class EventListenerMethod: int, bool, bool, - Union[Dict[str, Any], List[Dict[str, Any]], None], + Union[dict[str, Any], list[dict[str, Any]], None], Union[float, None], Union[Literal["once", "multiple", "always_last"], None], Union[str, None], @@ -406,12 +402,12 @@ def event_trigger( inputs: Component | BlockContext | Sequence[Component | BlockContext] - | AbstractSet[Component | BlockContext] + | Set[Component | BlockContext] | None = None, outputs: Component | BlockContext | Sequence[Component | BlockContext] - | AbstractSet[Component | BlockContext] + | Set[Component | BlockContext] | None = None, api_name: str | None | Literal[False] = None, scroll_to_output: bool = False, @@ -545,12 +541,12 @@ def on( inputs: Component | BlockContext | Sequence[Component | BlockContext] - | AbstractSet[Component | BlockContext] + | Set[Component | BlockContext] | None = None, outputs: Component | BlockContext | Sequence[Component | BlockContext] - | AbstractSet[Component | BlockContext] + | Set[Component | BlockContext] | None = None, *, api_name: str | None | Literal[False] = None, diff --git a/gradio/external.py b/gradio/external.py index 7f2e4c32e2..3cca34d905 100644 --- a/gradio/external.py +++ b/gradio/external.py @@ -8,8 +8,9 @@ import re import tempfile import warnings +from collections.abc import Callable from pathlib import Path -from typing import TYPE_CHECKING, Callable, Literal +from typing import TYPE_CHECKING, Literal import httpx import huggingface_hub diff --git a/gradio/external_utils.py b/gradio/external_utils.py index ab982c0f92..7126489b49 100644 --- a/gradio/external_utils.py +++ b/gradio/external_utils.py @@ -204,6 +204,7 @@ def chatbot_postprocess(response): zip( response["conversation"]["past_user_inputs"], response["conversation"]["generated_responses"], + strict=False, ) ) return chatbot_history, response diff --git a/gradio/flagging.py b/gradio/flagging.py index f2d03e6cd5..490784377b 100644 --- a/gradio/flagging.py +++ b/gradio/flagging.py @@ -5,8 +5,9 @@ import os import time from abc import ABC, abstractmethod +from collections.abc import Sequence from pathlib import Path -from typing import TYPE_CHECKING, Any, Sequence +from typing import TYPE_CHECKING, Any from gradio_client import utils as client_utils from gradio_client.documentation import document @@ -87,7 +88,7 @@ def flag( log_filepath = Path(flagging_dir) / "log.csv" csv_data = [] - for component, sample in zip(self.components, flag_data): + for component, sample in zip(self.components, flag_data, strict=False): save_dir = Path( flagging_dir ) / client_utils.strip_invalid_filename_characters(component.label or "") @@ -153,7 +154,9 @@ def flag( ] csv_data = [] - for idx, (component, sample) in enumerate(zip(self.components, flag_data)): + for idx, (component, sample) in enumerate( + zip(self.components, flag_data, strict=False) + ): save_dir = Path( flagging_dir ) / client_utils.strip_invalid_filename_characters( diff --git a/gradio/helpers.py b/gradio/helpers.py index e70ad9e3f0..f4a5f45463 100644 --- a/gradio/helpers.py +++ b/gradio/helpers.py @@ -13,9 +13,10 @@ import subprocess import tempfile import warnings +from collections.abc import Callable, Iterable, Sequence from functools import partial from pathlib import Path -from typing import TYPE_CHECKING, Any, Callable, Iterable, Literal, Optional, Sequence +from typing import TYPE_CHECKING, Any, Literal, Optional import numpy as np import PIL @@ -227,10 +228,14 @@ def __init__( pass # If there are more example components than inputs, ignore. This can sometimes be intentional (e.g. loading from a log file where outputs and timestamps are also logged) inputs_with_examples = [ - inp for (inp, keep) in zip(inputs, input_has_examples) if keep + inp for (inp, keep) in zip(inputs, input_has_examples, strict=False) if keep ] non_none_examples = [ - [ex for (ex, keep) in zip(example, input_has_examples) if keep] + [ + ex + for (ex, keep) in zip(example, input_has_examples, strict=False) + if keep + ] for example in examples ] if example_labels is not None and len(example_labels) != len(examples): @@ -286,7 +291,7 @@ def _get_processed_example(self, example): return self.non_none_processed_examples[example] with utils.set_directory(self.working_directory): sub = [] - for component, sample in zip(self.inputs, example): + for component, sample in zip(self.inputs, example, strict=False): prediction_value = component.postprocess(sample) if isinstance(prediction_value, (GradioRootModel, GradioModel)): prediction_value = prediction_value.model_dump() @@ -296,7 +301,9 @@ def _get_processed_example(self, example): postprocess=True, ) sub.append(prediction_value) - return [ex for (ex, keep) in zip(sub, self.input_has_examples) if keep] + return [ + ex for (ex, keep) in zip(sub, self.input_has_examples, strict=False) if keep + ] def create(self) -> None: """Caches the examples if self.cache_examples is True and creates the Dataset @@ -564,7 +571,7 @@ def load_from_cache(self, example_id: int) -> list[Any]: output = [] if self.outputs is None: raise ValueError("self.outputs is missing") - for component, value in zip(self.outputs, example): + for component, value in zip(self.outputs, example, strict=False): value_to_use = value try: value_as_dict = ast.literal_eval(value) @@ -908,12 +915,8 @@ def special_args( if inputs is not None: inputs.insert(i, request) elif type_hint in ( - # Note: "OAuthProfile | None" is equals to Optional[OAuthProfile] in Python - # => it is automatically handled as well by the above condition - # (adding explicit "OAuthProfile | None" would break in Python3.9) - # (same for "OAuthToken") - Optional[oauth.OAuthProfile], - Optional[oauth.OAuthToken], + oauth.OAuthProfile | None, + oauth.OAuthToken | None, oauth.OAuthProfile, oauth.OAuthToken, ): diff --git a/gradio/interface.py b/gradio/interface.py index ce7d98e8dd..382115c110 100644 --- a/gradio/interface.py +++ b/gradio/interface.py @@ -9,7 +9,8 @@ import os import warnings import weakref -from typing import TYPE_CHECKING, Any, Callable, Literal, Sequence +from collections.abc import Callable, Sequence +from typing import TYPE_CHECKING, Any, Literal from gradio_client.documentation import document @@ -289,7 +290,10 @@ def __init__( if len(self.input_components) == len(self.output_components): same_components = [ - i is o for i, o in zip(self.input_components, self.output_components) + i is o + for i, o in zip( + self.input_components, self.output_components, strict=False + ) ] if all(same_components): self.interface_type = InterfaceTypes.UNIFIED @@ -445,7 +449,9 @@ def __init__( param_names.remove(param_name) except (TypeError, ValueError): param_names = utils.default_input_labels() - for component, param_name in zip(self.input_components, param_names): + for component, param_name in zip( + self.input_components, param_names, strict=False + ): if not isinstance(component, Component): raise TypeError( f"Input component must be a Component, not {type(component)}" @@ -834,7 +840,9 @@ def attach_flagging_events( else: flag_components = self.input_components + self.output_components - for flag_btn, (label, value) in zip(flag_btns, self.flagging_options): + for flag_btn, (label, value) in zip( + flag_btns, self.flagging_options, strict=False + ): if not isinstance(value, str): raise TypeError( f"Flagging option value must be a string, not {value!r}" @@ -951,7 +959,7 @@ def __init__( f"