#########################################################
# Copyright (C) 2023 SiMa Technologies, Inc.
#
# This material is SiMa proprietary and confidential.
#
# This material may not be copied or distributed without
# the express prior written permission of SiMa.
#
# All rights reserved.
#########################################################
# Code owner: Ljubomir Papuga
#########################################################
import functools
import inspect
from typing import Dict, List, Any, Type
[docs]
def type_check(method_name: str, op_name: str, argument_name: str,
obj: Any, expected_type: Type) -> None:
assert isinstance(obj, expected_type), \
f"Error: The method ({method_name}) in operation ({op_name}) expects the argument " \
f"({argument_name}) to have type ({expected_type}). Instead it received type ({type(obj)})"
[docs]
def dict_type_check(method_name: str, op_name: str, argument_name: str,
in_dict: Dict[Any, Any], expected_type: Type) -> None:
"""
Type check to be performed on input dictionaries where we expect all inputs to have the same type
"""
for k, v in in_dict.items():
type_check(method_name, op_name, argument_name, v, expected_type)
[docs]
def type_check_operation_arguments(types: List[Type], dict_mask: List[bool]):
"""
This function is used for type checking awesome operations to make sure the operations are receiving
the correct input types.
:param types: A list of types in the order of inputs to the function. Types either indicate the type of the input
or the type for the values of an input that is a dictionary. The types list can be shorter than
the number of inputs to the function if you do not care to check the types of some of the inputs.
:param dict_mask: A list equal in length to types that indicates whether an input is a dictionary or not
"""
assert len(types) == len(dict_mask), "Error: types list does not have the same length as the dict_mask "
def type_checker_decorator(func):
@functools.wraps(func)
def wrapper(cls, *args, **kwargs):
arg_names = inspect.getfullargspec(func)[0][1:]
arg_list = []
arg_list += args
arg_list += list(kwargs.values())
assert len(arg_list) >= len(types), \
"Error: number of arguments is less than the number of types in type checker"
for a, n, t, d in zip(arg_list, arg_names, types, dict_mask):
if d:
dict_type_check(func.__name__, cls.__name__, n, a, t)
else:
type_check(func.__name__, cls.__name__, "(dictionary) " + n, a, t)
return func(cls, *args, **kwargs)
return wrapper
return type_checker_decorator