Incremental GSC parsing (exact copy of the tutorials shared as a separate project) / tqdm / _main.py
1576 viewsfrom ._tqdm import tqdm, TqdmTypeError, TqdmKeyError1from ._version import __version__ # NOQA2import sys3import re4__all__ = ["main"]567def cast(val, typ):8# sys.stderr.write('\ndebug | `val:type`: `' + val + ':' + typ + '`.\n')9if typ == 'bool':10if (val == 'True') or (val == ''):11return True12elif val == 'False':13return False14else:15raise TqdmTypeError(val + ' : ' + typ)16try:17return eval(typ + '("' + val + '")')18except:19if (typ == 'chr'):20return chr(ord(eval('"' + val + '"')))21else:22raise TqdmTypeError(val + ' : ' + typ)232425def posix_pipe(fin, fout, delim='\n', buf_size=256,26callback=lambda int: None # pragma: no cover27):28"""29Params30------31fin : file with `read(buf_size : int)` method32fout : file with `write` (and optionally `flush`) methods.33callback : function(int), e.g.: `tqdm.update`34"""35fp_write = fout.write3637buf = ''38tmp = ''39# n = 040while True:41tmp = fin.read(buf_size)4243# flush at EOF44if not tmp:45if buf:46fp_write(buf)47callback(1 + buf.count(delim)) # n += 1 + buf.count(delim)48getattr(fout, 'flush', lambda: None)() # pragma: no cover49return # n5051while True:52try:53i = tmp.index(delim)54except ValueError:55buf += tmp56break57else:58fp_write(buf + tmp[:i + len(delim)])59callback(1) # n += 160buf = ''61tmp = tmp[i + len(delim):]626364# ((opt, type), ... )65RE_OPTS = re.compile(r'\n {8}(\S+)\s{2,}:\s*([^\s,]+)')66# better split method assuming no positional args67RE_SHLEX = re.compile(r'\s*--?([^\s=]+)(?:\s*|=|$)')6869# TODO: add custom support for some of the following?70UNSUPPORTED_OPTS = ('iterable', 'gui', 'out', 'file')7172# The 8 leading spaces are required for consistency73CLI_EXTRA_DOC = r"""74Extra CLI Options75-----------------76delim : chr, optional77Delimiting character [default: '\n']. Use '\0' for null.78N.B.: on Windows systems, Python converts '\n' to '\r\n'.79buf_size : int, optional80String buffer size in bytes [default: 256]81used when `delim` is specified.82"""838485def main():86d = tqdm.__init__.__doc__ + CLI_EXTRA_DOC8788opt_types = dict(RE_OPTS.findall(d))8990for o in UNSUPPORTED_OPTS:91opt_types.pop(o)9293# d = RE_OPTS.sub(r' --\1=<\1> : \2', d)94split = RE_OPTS.split(d)95opt_types_desc = zip(split[1::3], split[2::3], split[3::3])96d = ''.join('\n --{0}=<{0}> : {1}{2}'.format(*otd)97for otd in opt_types_desc if otd[0] not in UNSUPPORTED_OPTS)9899__doc__ = """Usage:100tqdm [--help | options]101102Options:103-h, --help Print this help and exit104-v, --version Print version and exit105106""" + d.strip('\n') + '\n'107108# opts = docopt(__doc__, version=__version__)109if any(v in sys.argv for v in ('-v', '--version')):110sys.stdout.write(__version__ + '\n')111sys.exit(0)112elif any(v in sys.argv for v in ('-h', '--help')):113sys.stdout.write(__doc__ + '\n')114sys.exit(0)115116argv = RE_SHLEX.split(' '.join(sys.argv))117opts = dict(zip(argv[1::2], argv[2::2]))118119tqdm_args = {}120try:121for (o, v) in opts.items():122try:123tqdm_args[o] = cast(v, opt_types[o])124except KeyError as e:125raise TqdmKeyError(str(e))126# sys.stderr.write('\ndebug | args: ' + str(tqdm_args) + '\n')127except:128sys.stderr.write('\nError:\nUsage:\n tqdm [--help | options]\n')129for i in sys.stdin:130sys.stdout.write(i)131raise132else:133delim = tqdm_args.pop('delim', '\n')134buf_size = tqdm_args.pop('buf_size', 256)135if delim == '\n':136for i in tqdm(sys.stdin, **tqdm_args):137sys.stdout.write(i)138else:139with tqdm(**tqdm_args) as t:140posix_pipe(sys.stdin, sys.stdout,141delim, buf_size, t.update)142143144