Implementing a Python decorator for enforcing type checking on function arguments
10. Implement a decorator to enforce type checking on arguments
Write a Python program that implements a decorator to enforce type checking on the arguments of a function.
Sample Solution:
Python Code:
import inspect
def enforce_type_checking(func):
def wrapper(*args, **kwargs):
# Get the function signature and parameter names
signature = inspect.signature(func)
parameters = signature.parameters
# Iterate over the positional arguments
for i, arg in enumerate(args):
param_name = list(parameters.keys())[i]
param_type = parameters[param_name].annotation
if not isinstance(arg, param_type):
raise TypeError(f"Argument '{param_name}' must be of type '{param_type.__name__}'")
# Iterate over the keyword arguments
for param_name, arg in kwargs.items():
param_type = parameters[param_name].annotation
if not isinstance(arg, param_type):
raise TypeError(f"Argument '{param_name}' must be of type '{param_type.__name__}'")
# Call the original function
return func(*args, **kwargs)
return wrapper
# Example usage
@enforce_type_checking
def multiply_numbers(x: int, y: int) -> int:
return x * y
# Call the decorated function
result = multiply_numbers(5, 7) # No type errors, returns 30
print("Result:", result)
result = multiply_numbers("5", 7) # Type error: 'x' must be of type 'int'
Sample Output:
Result: 35 Traceback (most recent call last): File h:\anaconda3\lib\site-packages\spyder_kernels\py3compat.py:356 in compat_exec exec(code, globals, locals) File c:\users\me\.spyder-py3\history_internal.py:35 result = multiply_numbers("5", 7) # Type error: 'x' must be of type 'int' File c:\users\me\.spyder-py3\history_internal.py:13 in wrapper raise TypeError(f"Argument '{param_name}' must be of type '{param_type.__name__}'") TypeError: Argument 'x' must be of type 'int'
Explanation:
In the above exercise, the 'enforce_type_checking' decorator is defined. It takes a function as an argument and returns a wrapper function that checks the type on the arguments. The wrapper function inspects the function's signature using inspect.signature to get the parameter names and their annotations. It then iterates over the positional and keyword arguments, checking their types against the corresponding parameter annotations. It raises a TypeError if the types do not match.
Flowchart:


For more Practice: Solve these Related Problems:
- Write a Python decorator that checks the types of arguments passed to a function against its annotations and raises a TypeError if they don't match.
- Write a Python decorator that uses isinstance() to verify that all function arguments are of expected types before execution.
- Write a Python decorator that inspects a function’s signature using the inspect module to enforce type constraints on its arguments.
- Write a Python decorator that validates input types for a function and logs an error if a type mismatch is detected, then returns a default value.
Python Code Editor :
Have another way to solve this solution? Contribute your code (and comments) through Disqus.
Previous: Implementing a Python decorator for exception handling with a default response.
Next: Implementing a Python decorator to measure memory usage of a function.
What is the difficulty level of this exercise?
Test your Programming skills with w3resource's quiz.