w3resource

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:

Flowchart: Python - Implementing a Python decorator for enforcing type checking on function arguments.
Flowchart: Python - Implementing a Python decorator for enforcing type checking on function arguments.

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.



Follow us on Facebook and Twitter for latest update.