Skip to content

Commit b070e19

Browse files
authored
Merge pull request #14 from comfuture/feature-check
Feature check
2 parents a1173ae + 886dd3f commit b070e19

File tree

5 files changed

+66
-57
lines changed

5 files changed

+66
-57
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
steps:
2222
- uses: actions/checkout@v4
2323
- name: Set up Python ${{ matrix.python-version }}
24-
uses: actions/setup-python@v4
24+
uses: actions/setup-python@v5
2525
with:
2626
python-version: ${{ matrix.python-version }}
2727
- name: Set up uv

function_schema/core.py

Lines changed: 8 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -11,63 +11,19 @@
1111
get_origin,
1212
)
1313

14-
from .types import FunctionSchema
15-
from .utils import is_py310_atleast
14+
from .types import FunctionSchema, Doc
15+
from .utils import unwrap_doc
1616

17-
if is_py310_atleast():
18-
from types import UnionType
19-
else:
20-
UnionType = Union # type: ignore
2117

2218
try:
23-
from typing import Doc
19+
from types import UnionType
2420
except ImportError:
25-
try:
26-
from typing_extensions import Doc
27-
except ImportError:
28-
29-
class Doc:
30-
def __init__(self, documentation: str, /):
31-
self.documentation = documentation
21+
UnionType = Union # type: ignore
3222

3323

3424
__all__ = ("get_function_schema", "guess_type", "Doc", "Annotated")
3525

3626

37-
def is_doc_meta(
38-
obj: Annotated[Any, Doc("The object to be checked.")],
39-
) -> Annotated[
40-
bool, Doc("True if the object is a documentation object, False otherwise.")
41-
]:
42-
"""
43-
Check if the given object is a documentation object.
44-
45-
Example:
46-
>>> is_doc_meta(Doc("This is a documentation object"))
47-
True
48-
"""
49-
return getattr(obj, "__class__") == Doc and hasattr(obj, "documentation")
50-
51-
52-
def unwrap_doc(
53-
obj: Annotated[
54-
Union[Doc, str], Doc("The object to get the documentation string from.")
55-
],
56-
) -> Annotated[str, Doc("The documentation string.")]:
57-
"""
58-
Get the documentation string from the given object.
59-
60-
Example:
61-
>>> unwrap_doc(Doc("This is a documentation object"))
62-
'This is a documentation object'
63-
>>> unwrap_doc("This is a documentation string")
64-
'This is a documentation string'
65-
"""
66-
if is_doc_meta(obj):
67-
return obj.documentation
68-
return str(obj)
69-
70-
7127
def get_function_schema(
7228
func: Annotated[Callable, Doc("The function to get the schema for")],
7329
format: Annotated[
@@ -175,7 +131,8 @@ def get_function_schema(
175131
}
176132

177133
if enum_ is not None:
178-
schema["properties"][name]["enum"] = [t for t in enum_ if t is not None]
134+
schema["properties"][name]["enum"] = [
135+
t for t in enum_ if t is not None]
179136

180137
if default_value is not inspect._empty:
181138
schema["properties"][name]["default"] = default_value
@@ -205,7 +162,8 @@ def get_function_schema(
205162
def guess_type(
206163
T: Annotated[type, Doc("The type to guess the JSON schema type for")],
207164
) -> Annotated[
208-
Union[str, list[str]], Doc("str | list of str that representing JSON schema type")
165+
Union[str, list[str]], Doc(
166+
"str | list of str that representing JSON schema type")
209167
]:
210168
"""Guesses the JSON schema type for the given python type."""
211169

function_schema/types.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,17 @@
88
except ImportError:
99
from typing import Optional as NotRequired
1010

11+
try:
12+
from typing import Doc
13+
except ImportError:
14+
try:
15+
from typing_extensions import Doc
16+
except ImportError:
17+
18+
class Doc:
19+
def __init__(self, documentation: str, /):
20+
self.documentation = documentation
21+
1122

1223
class ParamSchema(TypedDict):
1324
"""

function_schema/utils.py

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,46 @@
1-
import platform
1+
from typing import Annotated, Any, Union
2+
from .types import Doc
23

34

4-
def is_py310_atleast():
5-
version_tuple = tuple(map(int, platform.python_version_tuple()))
6-
return version_tuple >= (3, 10)
5+
def is_support_uniontype():
6+
"""Check if current python version supports UnionType or not"""
7+
try:
8+
from types import UnionType # noqa
9+
except ImportError:
10+
return False
11+
return True
12+
13+
14+
def is_doc_meta(
15+
obj: Annotated[Any, Doc("The object to be checked.")],
16+
) -> Annotated[
17+
bool, Doc("True if the object is a documentation object, False otherwise.")
18+
]:
19+
"""
20+
Check if the given object is a documentation object.
21+
22+
Example:
23+
>>> is_doc_meta(Doc("This is a documentation object"))
24+
True
25+
"""
26+
return getattr(obj, "__class__") == Doc and hasattr(obj, "documentation")
27+
28+
29+
def unwrap_doc(
30+
obj: Annotated[
31+
Union[Doc, str], Doc(
32+
"The object to get the documentation string from.")
33+
],
34+
) -> Annotated[str, Doc("The documentation string.")]:
35+
"""
36+
Get the documentation string from the given object.
37+
38+
Example:
39+
>>> unwrap_doc(Doc("This is a documentation object"))
40+
'This is a documentation object'
41+
>>> unwrap_doc("This is a documentation string")
42+
'This is a documentation string'
43+
"""
44+
if is_doc_meta(obj):
45+
return obj.documentation
46+
return str(obj)

test/test_guess_type.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import pytest
44

55
from function_schema.core import guess_type
6-
from function_schema.utils import is_py310_atleast
6+
from function_schema.utils import is_support_uniontype
77

88

99
def test_primitive():
@@ -68,7 +68,7 @@ def test_union():
6868

6969

7070
@pytest.mark.skipif(
71-
not is_py310_atleast(), reason="Union type is only available in Python 3.10+"
71+
not is_support_uniontype(), reason="Union type is only available in Python 3.10+"
7272
)
7373
def test_union_type():
7474
"""Test union types in Python 3.10+"""

0 commit comments

Comments
 (0)