Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: annotations lazy evaluation #538

Merged
merged 2 commits into from
Jun 16, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mosec"
version = "0.8.4"
version = "0.8.6"
authors = ["Keming <kemingy94@gmail.com>", "Zichen <lkevinzc@gmail.com>"]
edition = "2021"
license = "Apache-2.0"
Expand Down
2 changes: 1 addition & 1 deletion mosec/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ def make_body(description, mime, schema):
if not return_schema
else {
"200": make_body(
"Mosec Inference Result",
"Mosec Inference Response",
response_worker_cls.resp_mime_type,
return_schema,
)
Expand Down
44 changes: 33 additions & 11 deletions mosec/utils/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,32 @@
"""Provide useful utils to inspect function type."""

import inspect
import sys
from enum import Enum
from typing import List
from typing import Any, List


def get_annotations(func) -> dict:
"""Get the annotations of a class method.

This will evaluation the annotations of the method and return a dict.
The implementation is based on the `inspect.get_annotations` (Py>=3.10).

``eval_str=True`` since ``from __future__ import annotations`` will change
all the annotations to string.
"""
if sys.version_info >= (3, 10):
return inspect.get_annotations(func, eval_str=True)
annotations = getattr(func, "__annotations__", None)
obj_globals = getattr(func, "__globals__", None)
if annotations is None:
return {}
if not isinstance(annotations, dict):
raise TypeError(f"{func.__name__} annotations must be a dict or None")
return {
key: value if not isinstance(value, str) else eval(value, obj_globals)
for key, value in annotations.items()
}


class ParseTarget(Enum):
Expand All @@ -32,22 +56,20 @@ def parse_func_type(func, target: ParseTarget) -> type:
- single request: return the type
- batch request: return the list item type
"""
sig = inspect.signature(func)
index = 0 if inspect.ismethod(func) else 1
annotations = get_annotations(func)
name = func.__name__
typ = Any
if target == ParseTarget.INPUT:
params = list(sig.parameters.values())
if len(params) < index + 1:
raise TypeError(
f"`{name}` method doesn't have enough({index + 1}) parameters"
)
typ = params[index].annotation
for key in annotations:
if key != "return":
typ = annotations[key]
break
else:
typ = sig.return_annotation
typ = annotations.get("return", Any)

origin = getattr(typ, "__origin__", None)
if origin is None:
return typ
return typ # type: ignore
# GenericAlias, `func` could be batch inference
if origin is list or origin is List:
if not hasattr(typ, "__args__") or len(typ.__args__) != 1: # type: ignore
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ changelog = "https://github.com/mosecorg/mosec/releases"

[tool.cibuildwheel]
build-frontend = "build"
skip = ["cp36-*", "*-musllinux_*", "pp*"]
skip = ["cp36-*", "cp37-*", "*-musllinux_*", "pp*"]
archs = ["auto64"]
before-all = "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y"
environment = { PRODUCTION_MODE="yes", PATH="$PATH:$HOME/.cargo/bin", PIP_NO_CLEAN="yes" }
Expand All @@ -54,6 +54,7 @@ requires = ["setuptools>=45", "wheel", "setuptools_scm>=7.0"]
write_to = "mosec/_version.py"

[tool.mypy]
python_version = "3.8"
warn_redundant_casts = true
warn_unreachable = true
pretty = true
Expand Down
6 changes: 3 additions & 3 deletions requirements/dev.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
setuptools_scm>=7
pytest>=6
pytest-mock>=3.5
mypy>=0.910
pyright>=1.1.290
ruff~=0.4.7
mypy~=1.10
pyright~=1.1
ruff~=0.4
pre-commit>=2.15.0
msgpack>=1.0.5
numpy>=1.24
Expand Down