Created
March 27, 2019 02:45
-
-
Save pirate/27b5437a92feb7c25b775d4f1ef753d7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This is a decorator that checks the function parameters as runtime against their type hints. | |
# | |
# @enforce_types | |
# def example(a: str, b: int): | |
# return 'Success!' | |
# | |
# if __name__ == '__main__': | |
# example('abc', 123) | |
# example(123, 'abc') # this throws a TypeError | |
def enforce_types(func): | |
""" | |
Enforce function arg and kwarg types at runtime using its python3 type hints | |
""" | |
# TODO: check return type as well | |
@wraps(func) | |
def typechecked_function(*args, **kwargs): | |
sig = signature(func) | |
def check_argument_type(arg_key, arg_val): | |
try: | |
annotation = sig.parameters[arg_key].annotation | |
except KeyError: | |
annotation = _empty | |
if annotation is not _empty and annotation.__class__ is type: | |
if not isinstance(arg_val, annotation): | |
raise TypeError( | |
'{}(..., {}: {}) got unexpected {} argument {}={}'.format( | |
func.__name__, | |
arg_key, | |
annotation.__name__, | |
type(arg_val).__name__, | |
arg_key, | |
arg_val, | |
) | |
) | |
# check args | |
for arg_val, arg_key in zip(args, sig.parameters): | |
check_argument_type(arg_key, arg_val) | |
# check kwargs | |
for arg_key, arg_val in kwargs.items(): | |
check_argument_type(arg_key, arg_val) | |
return func(*args, **kwargs) | |
return typechecked_function |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment