You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

59 lines
1.7 KiB
Python

#!/usr/bin/env python3
# Play around with function annotations to implement a crude type checker.
import inspect
def typechecked(func):
wrapped_func = func
def typecheck(*args, **kvargs):
parameters = inspect.signature(wrapped_func).parameters
wants = [(par, parameters[par].annotation) for par in parameters]
for want, arg in zip(wants, args):
name, class_ = want
if not isinstance(arg, class_):
raise TypeError("arg {} is not "
"an instance of {}".format(name, class_))
return_ = wrapped_func(*args, **kvargs)
class_ = wrapped_func.__annotations__["return"]
if not isinstance(return_, class_):
raise TypeError("return value is not "
"an instance of {}".format(class_))
return return_
typecheck.__doc__ = wrapped_func.__doc__
return typecheck
@typechecked
def greet(name: str, age: int, fnord: str=None) -> str:
"""Greet someone.
>>> greet("Mike", 12)
'Hello Mike, you are 12 years old'
>>> greet("Florian", "eins")
Traceback (most recent call last):
File "func_annotations.py", line 14, in typecheck
"is not an instance of {}".format(name, class_))
TypeError: arg age is not an instance of <class 'int'>
"""
return 'Hello {0}, you are {1} years old'.format(name, age)
@typechecked
def test(foo: int) -> str:
""" Just a test.
>>> test(1)
Traceback (most recent call last):
File "func_annotations.py", line 21, in typecheck
"is not an instance of {}".format(class_))
TypeError: return value is not an instance of <class 'str'>
"""
return 1
import doctest
doctest.testmod()