1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
|
import os.path
from collections import deque
from random import randint
from threading import local
def expose(func):
func.exposed = True
return func
class flattener: # noqa: N801
def __init__(self, iterator):
while type(iterator) == flattener:
iterator = iterator.iterator
self.iterator = iterator
@classmethod
def decorate(cls, func):
def inner(*args, **kwargs):
return cls(func(*args, **kwargs))
return inner
def accumulate_str(self):
if type(self.iterator) == flattener:
return self.iterator.accumulate_str()
s = ""
iter_stack = [self.iterator]
while iter_stack:
try:
x = next(iter_stack[-1])
except StopIteration:
iter_stack.pop()
continue
if type(x) == flattener:
iter_stack.append(x.iterator)
elif x is None:
pass
else:
s += x
return s
def __iter__(self):
for x in self.iterator:
if type(x) == flattener:
for xx in x:
if xx is not None:
yield xx
elif x is not None:
yield x
def literal(text):
return flattener(iter([text]))
class NameGen:
lcl = local()
def __init__(self):
self.names = set()
@classmethod
def gen(cls, hint):
if not hasattr(cls.lcl, "inst"):
cls.lcl.inst = NameGen()
return cls.lcl.inst._gen(hint) # noqa: SLF001
def _gen(self, hint):
r = hint
while r in self.names:
r = "%s_%d" % (hint, randint(0, len(self.names) * 10)) # noqa: S311
self.names.add(r)
return r
def gen_name(hint="_kj_"):
return NameGen.gen(hint)
def window(seq, n=2):
"""Return a sliding window of size ``n`` over an iterator"""
win = deque((next(seq, None) for _ in range(n)), maxlen=n)
yield win
for item in seq:
win.append(item)
yield win
def default_alias_for(name):
return os.path.splitext(os.path.basename(name))[0]
|