def type_check(func_handle):
    def checkType(var_name, var_val, annot):
        if var_name in annot:
            var_anno = annot[var_name]
            if var_val is None:
                type_ok = True
            elif (type(var_val) is bool):
                type_ok = (type(var_val) in var_anno)
            else:
                type_ok = True in [isinstance(var_val, _) for _ in var_anno]
        else:
            var_anno = 'Unspecified'
            type_ok = True
        if not type_ok:
            args = (var_name, func_handle.__name__, var_anno, type(var_val))
            raise QtmacsArgumentError(*args)
    @functools.wraps(func_handle)
    def wrapper(*args, **kwds):
        argspec = inspect.getfullargspec(func_handle)
        annot = {}
        for key, val in argspec.annotations.items():
            if isinstance(val, tuple) or isinstance(val, list):
                annot[key] = val
            else:
                annot[key] = val,
        if argspec.defaults is None:
            defaults = tuple([None] * len(argspec.args))
        else:
            num_none = len(argspec.args) - len(argspec.defaults)
            defaults = tuple([None] * num_none) + argspec.defaults
        ofs = len(args)
        for idx, var_name in enumerate(argspec.args[:ofs]):
            var_val = args[idx]
            checkType(var_name, var_val, annot)
        for idx, var_name in enumerate(argspec.args[ofs:]):
            if var_name in kwds:
                var_val = kwds[var_name]
            else:
                var_val = defaults[idx + ofs]
            checkType(var_name, var_val, annot)
        return func_handle(*args, **kwds)
    return wrapper