Skip to content

Commit 23ed469

Browse files
feat: add type hints checking for callable functions
- Introduced `checking_type_hints_for_callable` function to validate the presence of type hints in callable functions, including return type. - Added `TypeHintsNotProvidedError` for handling missing type hints. - Implemented unit tests to verify behavior: - Test for functions missing return type hints. - Test for functions with no arguments. - Test for correctly provided type hints. - Test for missing and mismatched argument type hints.
1 parent 53be713 commit 23ed469

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

py_spring/core/utils.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import importlib.util
22
from inspect import isclass
33
from pathlib import Path
4-
from typing import Iterable, Type
4+
from typing import Any, Callable, Iterable, Optional, Type, get_type_hints
55

66
from loguru import logger
77

@@ -75,3 +75,24 @@ def dynamically_import_modules(
7575
returned_target_classes.add(loaded_class)
7676

7777
return returned_target_classes
78+
79+
80+
class TypeHintsNotProvidedError(Exception): ...
81+
82+
def checking_type_hints_for_callable(func: Callable[..., Any]) -> None:
83+
RETURN_ID = "return"
84+
85+
argument_count = func.__code__.co_argcount + 1 # plue one is for return type, return type is not included in co_argcount
86+
annotations = func.__annotations__
87+
args_type_hints = get_type_hints(func)
88+
full_type_hints = {**annotations, **args_type_hints}
89+
90+
if RETURN_ID not in full_type_hints:
91+
raise TypeHintsNotProvidedError("Type hints for 'return type' not provided for the function")
92+
if argument_count == 0:
93+
return
94+
if len(full_type_hints) == 0:
95+
raise TypeHintsNotProvidedError(f"Type hints not provided for the function, number of arguments: {argument_count} and type hints: {full_type_hints}")
96+
97+
if len(full_type_hints) != argument_count:
98+
raise TypeHintsNotProvidedError(f"Number of type hints does not match the number of arguments in the function: {full_type_hints}, number of arguments: {argument_count}")

tests/test_utils.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
2+
3+
import pytest
4+
from py_spring.core.utils import checking_type_hints_for_callable, TypeHintsNotProvidedError
5+
6+
7+
class TestFrameworkUtils:
8+
9+
def test_function_with_argument_type_hints_but_no_return_type(self):
10+
def test_func(a: int, b: str):
11+
pass # No return type hint
12+
with pytest.raises(TypeHintsNotProvidedError, match="Type hints for 'return type' not provided for the function"):
13+
checking_type_hints_for_callable(test_func)
14+
15+
def test_function_with_no_arguments(self):
16+
def test_func() -> None:
17+
pass
18+
# No exception should be raised for a function with no arguments
19+
checking_type_hints_for_callable(test_func)
20+
21+
def test_function_with_correct_type_hints(self):
22+
def test_func(a: int, b: str) -> None:
23+
pass
24+
# No exception should be raised
25+
checking_type_hints_for_callable(test_func)
26+
27+
def test_function_with_no_type_hints(self):
28+
def test_func(a, b) -> None:
29+
pass
30+
with pytest.raises(TypeHintsNotProvidedError, match="Number of type hints does not match the number of arguments"):
31+
checking_type_hints_for_callable(test_func)
32+
33+
def test_function_with_mismatched_type_hints(self):
34+
def test_func(a: int, b, c) -> None:
35+
pass
36+
# Intentionally using only one type hint
37+
38+
with pytest.raises(TypeHintsNotProvidedError, match="Number of type hints does not match the number of arguments in the function"):
39+
checking_type_hints_for_callable(test_func)
40+

0 commit comments

Comments
 (0)