Skip to content

Commit b4c7e1e

Browse files
author
manas-shinde
committed
feat : Added new decorator - validate_types.
1 parent a8f34ab commit b4c7e1e

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

decorators/validate_types.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import functools
2+
import inspect
3+
4+
5+
def validate_types(func):
6+
"""Decorator to enforce type hints at runtime."""
7+
sig = inspect.signature(func)
8+
print(sig)
9+
10+
@functools.wraps(func)
11+
def wrapper(*args, **kwargs):
12+
bound = sig.bind(*args, **kwargs)
13+
bound.apply_defaults()
14+
15+
for name, value in bound.arguments.items():
16+
expected = sig.parameters[name].annotation
17+
if expected is not inspect._empty and not isinstance(value, expected):
18+
raise TypeError(
19+
f"Argument '{name}' must be {expected}, got {type(value)}")
20+
21+
result = func(*args, **kwargs)
22+
if sig.return_annotation is not inspect._empty and not isinstance(result, sig.return_annotation):
23+
raise TypeError(
24+
f"Return value must be {sig.return_annotation}, got {type(result)}")
25+
return result
26+
27+
return wrapper

tests/test_validate_types.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import pytest
2+
from decorators.validate_types import validate_types
3+
4+
5+
@validate_types
6+
def add(x: int, y: int) -> int:
7+
return x + y
8+
9+
10+
def test_validate_types_success():
11+
assert add(2, 3) == 5
12+
13+
14+
def test_validate_types_arg_error():
15+
with pytest.raises(TypeError):
16+
add("2", 3)
17+
18+
19+
def test_validate_types_return_error():
20+
@validate_types
21+
def broken_add(x: int, y: int) -> str:
22+
return x + y # Will return int, violates str
23+
24+
with pytest.raises(TypeError):
25+
broken_add(1, 2)

0 commit comments

Comments
 (0)