Source code for titan_pylib.others.antirec
1from types import GeneratorType
2
3# ref: https://github.com/cheran-senthil/PyRival/blob/master/pyrival/misc/bootstrap.py
4# ref: https://twitter.com/onakasuita_py/status/1731535542305907041
5
6
[docs]
7def antirec(func):
8 stack = []
9
10 def wrappedfunc(*args, **kwargs):
11 if stack:
12 return func(*args, **kwargs)
13 to = func(*args, **kwargs)
14 while True:
15 if isinstance(to, GeneratorType):
16 stack.append(to)
17 to = next(to)
18 else:
19 stack.pop()
20 if not stack:
21 break
22 to = stack[-1].send(to)
23 return to
24
25 return wrappedfunc
26
27
[docs]
28def antirec_cache(func):
29 stack = []
30 memo = {}
31 args_list = []
32
33 def wrappedfunc(*args):
34 args_list.append(args)
35 if stack:
36 return func(*args)
37 to = func(*args)
38 while True:
39 if args_list[-1] in memo:
40 res = memo[args_list.pop()]
41 if not stack:
42 return res
43 to = stack[-1].send(res)
44 continue
45 if isinstance(to, GeneratorType):
46 stack.append(to)
47 to = next(to)
48 else:
49 memo[args_list.pop()] = to
50 stack.pop()
51 if not stack:
52 break
53 to = stack[-1].send(to)
54 return to
55
56 return wrappedfunc