From 74498dc34bc96a701abb2a1e04b4a61c3b524c5f Mon Sep 17 00:00:00 2001 From: Mike Bloy Date: Sun, 7 Jan 2024 11:54:24 -0600 Subject: [PATCH] Ex 7.1 --- logcall.py | 6 ++++++ sample.py | 11 +++++++++++ validate.py | 31 ++++++++++++++++++++++++++++++- 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 logcall.py create mode 100644 sample.py diff --git a/logcall.py b/logcall.py new file mode 100644 index 0000000..c0ae43f --- /dev/null +++ b/logcall.py @@ -0,0 +1,6 @@ +def logged(func): + print('Adding logging to', func.__name__) + def wrapper(*args, **kwargs): + print('Calling', func.__name__) + return func(*args, **kwargs) + return wrapper diff --git a/sample.py b/sample.py new file mode 100644 index 0000000..017dfb2 --- /dev/null +++ b/sample.py @@ -0,0 +1,11 @@ +from logcall import logged + + +@logged +def add(x, y): + return x + y + + +@logged +def sub(x, y): + return x - y diff --git a/validate.py b/validate.py index 986d678..d7fe4fe 100644 --- a/validate.py +++ b/validate.py @@ -66,6 +66,31 @@ class NonEmptyString(String, NonEmpty): pass +def validated(func): + sig = inspect.signature(func) + annotations = dict(func.__annotations__) + retcheck = annotations.pop('return', None) + + def wrapper(*args, **kwargs): + bound = sig.bind(*args, **kwargs) + errors = [] + for name, validator in annotations.items(): + try: + validator.check(bound.arguments[name]) + except Exception as e: + errors.append(f' {name}: {e}') + if errors: + raise TypeError('Bad Arguments\n' + '\n'.join(errors)) + result = func(*args, **kwargs) + if retcheck: + try: + retcheck.check(result) + except Exception as e: + raise TypeError(f'Bad return: {e}') from None + return result + return wrapper + + class ValidatedFunction: def __init__(self, func): self.func = func @@ -83,6 +108,10 @@ class ValidatedFunction: if __name__ == '__main__': + @validated def add(x: Integer, y: Integer): return x + y - add = ValidatedFunction(add) + + @validated + def power(x: Integer, y: Integer): + return x ** y