File tree Expand file tree Collapse file tree 2 files changed +52
-0
lines changed
Expand file tree Collapse file tree 2 files changed +52
-0
lines changed Original file line number Diff line number Diff line change 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
Original file line number Diff line number Diff line change 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 )
You can’t perform that action at this time.
0 commit comments