|
9 | 9 | 'inum_methods', 'fastuple', 'trace', 'compose', 'maps', 'partialler', 'mapped', 'instantiate', 'using_attr', |
10 | 10 | 'Self', 'Self', 'save_pickle', 'load_pickle', 'bunzip', 'join_path_file', 'urlread', 'urljson', 'run', |
11 | 11 | 'do_request', 'sort_by_run', 'PrettyString', 'round_multiple', 'even_mults', 'num_cpus', 'add_props', |
12 | | - 'ContextManagers', 'set_num_threads', 'ProcessPoolExecutor', 'ThreadPoolExecutor', 'parallel', 'run_procs', |
13 | | - 'parallel_gen', 'threaded'] |
| 12 | + 'ContextManagers', 'typed', 'set_num_threads', 'ProcessPoolExecutor', 'ThreadPoolExecutor', 'parallel', |
| 13 | + 'run_procs', 'parallel_gen', 'threaded'] |
14 | 14 |
|
15 | 15 | # Cell |
16 | 16 | from .imports import * |
@@ -675,6 +675,23 @@ def __init__(self, mgrs): self.default,self.stack = L(mgrs),ExitStack() |
675 | 675 | def __enter__(self): self.default.map(self.stack.enter_context) |
676 | 676 | def __exit__(self, *args, **kwargs): self.stack.__exit__(*args, **kwargs) |
677 | 677 |
|
| 678 | +# Cell |
| 679 | +def typed(f): |
| 680 | + "Decorator to check param and return types at runtime" |
| 681 | + names = f.__code__.co_varnames |
| 682 | + anno = f.__annotations__ |
| 683 | + ret = anno.pop('return',None) |
| 684 | + def _f(*args,**kwargs): |
| 685 | + kw = {**kwargs} |
| 686 | + if len(anno) > 0: |
| 687 | + for i,arg in enumerate(args): kw[names[i]] = arg |
| 688 | + for k,v in kw.items(): |
| 689 | + if not isinstance(v,anno[k]): raise TypeError(f"{k}=={v} not {anno[k]}") |
| 690 | + res = f(*args,**kwargs) |
| 691 | + if ret is not None and not isinstance(res,ret): raise TypeError(f"return=={res} not {ret}") |
| 692 | + return res |
| 693 | + return functools.update_wrapper(_f, f) |
| 694 | + |
678 | 695 | # Cell |
679 | 696 | from multiprocessing import Process, Queue |
680 | 697 | import concurrent.futures |
|
0 commit comments