w3resource

Implementing a Python decorator for enforcing type checking on function arguments

Python Decorator: Exercise-10 with Solution

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.

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.