mirror of
https://github.com/gradio-app/gradio.git
synced 2024-11-21 01:01:05 +08:00
Fix for typing.get_type_hints()
on Python 3.9 or lower (#4228)
* fix * fix docstring * type hint fix * fix test * Update gradio/utils.py Co-authored-by: Aarni Koskela <akx@iki.fi> * fix indentation --------- Co-authored-by: Aarni Koskela <akx@iki.fi>
This commit is contained in:
parent
7241cdaf91
commit
6bace9765c
@ -6,12 +6,14 @@
|
||||
- Added `format` argument to `Audio` component by [@freddyaboulton](https://github.com/freddyaboulton) in [PR 4178](https://github.com/gradio-app/gradio/pull/4178)
|
||||
- Add JS client code snippets to use via api page by [@aliabd](https://github.com/aliabd) in [PR 3927](https://github.com/gradio-app/gradio/pull/3927).
|
||||
|
||||
|
||||
## Bug Fixes:
|
||||
|
||||
- Fix "TypeError: issubclass() arg 1 must be a class" When use Optional[Types] by [@lingfengchencn](https://github.com/lingfengchencn) in [PR 4200](https://github.com/gradio-app/gradio/pull/4200).
|
||||
- Gradio will no longer send any analytics if analytics are disabled with the GRADIO_ANALYTICS_ENABLED environment variable. By [@akx](https://github.com/akx) in [PR 4194](https://github.com/gradio-app/gradio/pull/4194)
|
||||
- The deprecation warnings for kwargs now show the actual stack level for the invocation, by [@akx](https://github.com/akx) in [PR 4203](https://github.com/gradio-app/gradio/pull/4203).
|
||||
- Fix "TypeError: issubclass() arg 1 must be a class" When use Optional[Types] by [@lingfengchencn](https://github.com/lingfengchencn) in [PR 4200](https://github.com/gradio-app/gradio/pull/4200).
|
||||
- Fixes a bug with typing.get_type_hints() on Python 3.9 by [@abidlabs](https://github.com/abidlabs) in [PR 4228](https://github.com/gradio-app/gradio/pull/4228).
|
||||
|
||||
## Other Changes:
|
||||
|
||||
|
@ -683,12 +683,42 @@ def get_cancel_function(
|
||||
|
||||
|
||||
def get_type_hints(fn):
|
||||
# Importing gradio with the canonical abbreviation. Used in typing._eval_type.
|
||||
import gradio as gr # noqa: F401
|
||||
from gradio import Request # noqa: F401
|
||||
|
||||
if inspect.isfunction(fn) or inspect.ismethod(fn):
|
||||
return typing.get_type_hints(fn)
|
||||
pass
|
||||
elif callable(fn):
|
||||
return typing.get_type_hints(fn.__call__)
|
||||
fn = fn.__call__
|
||||
else:
|
||||
return {}
|
||||
|
||||
try:
|
||||
return typing.get_type_hints(fn)
|
||||
except TypeError:
|
||||
# On Python 3.9 or earlier, get_type_hints throws a TypeError if the function
|
||||
# has a type annotation that include "|". We resort to parsing the signature
|
||||
# manually using inspect.signature.
|
||||
type_hints = {}
|
||||
sig = inspect.signature(fn)
|
||||
for name, param in sig.parameters.items():
|
||||
if param.annotation is inspect.Parameter.empty:
|
||||
continue
|
||||
if "|" in str(param.annotation):
|
||||
continue
|
||||
# To convert the string annotation to a class, we use the
|
||||
# internal typing._eval_type function. This is not ideal, but
|
||||
# it's the only way to do it without eval-ing the string.
|
||||
# Since the API is internal, it may change in the future.
|
||||
try:
|
||||
type_hints[name] = typing._eval_type( # type: ignore
|
||||
typing.ForwardRef(param.annotation), globals(), locals()
|
||||
)
|
||||
except (NameError, TypeError):
|
||||
pass
|
||||
return type_hints
|
||||
|
||||
|
||||
def is_special_typed_parameter(name, parameter_types):
|
||||
from gradio.helpers import EventData
|
||||
|
@ -1,9 +1,10 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import copy
|
||||
import os
|
||||
import sys
|
||||
import unittest.mock as mock
|
||||
import warnings
|
||||
from typing import List
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
@ -570,7 +571,7 @@ class TestGetTypeHints:
|
||||
assert len(get_type_hints(GenericObject())) == 0
|
||||
|
||||
def test_is_special_typed_parameter(self):
|
||||
def func(a: List[str], b: Literal["a", "b"], c, d: Request):
|
||||
def func(a: list[str], b: Literal["a", "b"], c, d: Request):
|
||||
pass
|
||||
|
||||
hints = get_type_hints(func)
|
||||
@ -579,6 +580,15 @@ class TestGetTypeHints:
|
||||
assert not is_special_typed_parameter("c", hints)
|
||||
assert is_special_typed_parameter("d", hints)
|
||||
|
||||
def test_is_special_typed_parameter_with_pipe(self):
|
||||
def func(a: Request, b: str | int, c: list[str]):
|
||||
pass
|
||||
|
||||
hints = get_type_hints(func)
|
||||
assert is_special_typed_parameter("a", hints)
|
||||
assert not is_special_typed_parameter("b", hints)
|
||||
assert not is_special_typed_parameter("c", hints)
|
||||
|
||||
|
||||
class TestCheckFunctionInputsMatch:
|
||||
def test_check_function_inputs_match(self):
|
||||
|
Loading…
Reference in New Issue
Block a user