CLI improvements

- add `--log`
- fix `--unit_scale`
- make `--bytes` more intelligent (closes #503)
- update tests & documentation
This commit is contained in:
Casper da Costa-Luis 2018-01-19 13:00:42 +00:00
parent 69ca16d6a8
commit 1da038c1cf
No known key found for this signature in database
GPG Key ID: 986B408043AE090D
3 changed files with 56 additions and 8 deletions

10
tqdm.1
View File

@ -215,7 +215,15 @@ specified.
.TP
.B \-\-bytes=\f[I]bytes\f[]
bool, optional.
If true, will count bytes and ignore \f[C]delim\f[].
If true, will count bytes, ignore \f[C]delim\f[], and default
\f[C]unit_scale\f[] to True, \f[C]unit_divisor\f[] to 1024, and
\f[C]unit\f[] to \[aq]B\[aq].
.RS
.RE
.TP
.B \-\-log=\f[I]log\f[]
str, optional.
CRITICAL|FATAL|ERROR|WARN(ING)|[default: \[aq]INFO\[aq]]|DEBUG|NOTSET.
.RS
.RE
.SH AUTHORS

View File

@ -2,10 +2,21 @@ from ._tqdm import tqdm, TqdmTypeError, TqdmKeyError
from ._version import __version__ # NOQA
import sys
import re
import logging
__all__ = ["main"]
def cast(val, typ):
log = logging.getLogger(__name__)
log.debug((val, typ))
if " or " in typ:
for t in typ.split(" or "):
try:
return cast(val, t)
except TqdmTypeError:
pass
raise TqdmTypeError(val + ' : ' + typ)
# sys.stderr.write('\ndebug | `val:type`: `' + val + ':' + typ + '`.\n')
if typ == 'bool':
if (val == 'True') or (val == ''):
@ -76,7 +87,7 @@ def posix_pipe(fin, fout, delim='\n', buf_size=256,
# ((opt, type), ... )
RE_OPTS = re.compile(r'\n {8}(\S+)\s{2,}:\s*([^\s,]+)')
RE_OPTS = re.compile(r'\n {8}(\S+)\s{2,}:\s*([^,]+)')
# better split method assuming no positional args
RE_SHLEX = re.compile(r'\s*--?([^\s=]+)(?:\s*|=|$)')
@ -87,6 +98,8 @@ UNSUPPORTED_OPTS = ('iterable', 'gui', 'out', 'file')
CLI_EXTRA_DOC = r"""
Extra CLI Options
-----------------
name : type, optional
TODO: find out why this is needed.
delim : chr, optional
Delimiting character [default: '\n']. Use '\0' for null.
N.B.: on Windows systems, Python converts '\n' to '\r\n'.
@ -94,7 +107,10 @@ CLI_EXTRA_DOC = r"""
String buffer size in bytes [default: 256]
used when `delim` is specified.
bytes : bool, optional
If true, will count bytes and ignore `delim`.
If true, will count bytes, ignore `delim`, and default
`unit_scale` to True, `unit_divisor` to 1024, and `unit` to 'B'.
log : str, optional
CRITICAL|FATAL|ERROR|WARN(ING)|[default: 'INFO']|DEBUG|NOTSET.
"""
@ -104,13 +120,27 @@ def main(fp=sys.stderr):
---------
fp : file-like object for tqdm
"""
try:
log = sys.argv.index('--log')
except ValueError:
logLevel = 'INFO'
else:
# sys.argv.pop(log)
# logLevel = sys.argv.pop(log)
logLevel = sys.argv[log + 1]
logging.basicConfig(level=getattr(logging, logLevel))
log = logging.getLogger(__name__)
d = tqdm.__init__.__doc__ + CLI_EXTRA_DOC
opt_types = dict(RE_OPTS.findall(d))
# opt_types['delim'] = 'chr'
for o in UNSUPPORTED_OPTS:
opt_types.pop(o)
log.debug(sorted(opt_types.items()))
# d = RE_OPTS.sub(r' --\1=<\1> : \2', d)
split = RE_OPTS.split(d)
opt_types_desc = zip(split[1::3], split[2::3], split[3::3])
@ -137,6 +167,9 @@ Options:
argv = RE_SHLEX.split(' '.join(["tqdm"] + sys.argv[1:]))
opts = dict(zip(argv[1::2], argv[2::2]))
log.debug(opts)
opts.pop('log', True)
tqdm_args = {'file': fp}
try:
for (o, v) in opts.items():
@ -144,7 +177,7 @@ Options:
tqdm_args[o] = cast(v, opt_types[o])
except KeyError as e:
raise TqdmKeyError(str(e))
# fp.write('\ndebug | args: ' + str(tqdm_args) + '\n')
log.debug('args:' + str(tqdm_args))
except:
fp.write('\nError:\nUsage:\n tqdm [--help | options]\n')
for i in sys.stdin:
@ -155,13 +188,19 @@ Options:
delim = tqdm_args.pop('delim', '\n')
delim_per_char = tqdm_args.pop('bytes', False)
if delim_per_char:
tqdm_args.setdefault('unit', 'B')
tqdm_args.setdefault('unit_scale', True)
tqdm_args.setdefault('unit_divisor', 1024)
log.debug(tqdm_args)
with tqdm(**tqdm_args) as t:
posix_pipe(sys.stdin, sys.stdout,
'', buf_size, t.update)
elif delim == '\n':
log.debug(tqdm_args)
for i in tqdm(sys.stdin, **tqdm_args):
sys.stdout.write(i)
else:
log.debug(tqdm_args)
with tqdm(**tqdm_args) as t:
posix_pipe(sys.stdin, sys.stdout,
delim, buf_size, t.update)

View File

@ -2,7 +2,8 @@ import sys
import subprocess
from tqdm import main, TqdmKeyError, TqdmTypeError
from tests_tqdm import with_setup, pretest, posttest, _range, closing, UnicodeIO
from tests_tqdm import with_setup, pretest, posttest, _range, closing, \
UnicodeIO, StringIO
def _sh(*cmd, **kwargs):
@ -28,7 +29,7 @@ def test_main():
# semi-fake test which gets coverage:
_SYS = sys.stdin, sys.argv
with closing(UnicodeIO()) as sys.stdin:
with closing(StringIO()) as sys.stdin:
sys.argv = ['', '--desc', 'Test CLI delims',
'--ascii', 'True', '--delim', r'\0', '--buf_size', '64']
sys.stdin.write('\0'.join(map(str, _range(int(1e3)))))
@ -42,10 +43,10 @@ def test_main():
import tqdm.__main__ # NOQA
IN_DATA = '\0'.join(IN_DATA_LIST)
with closing(UnicodeIO()) as sys.stdin:
with closing(StringIO()) as sys.stdin:
sys.stdin.write(IN_DATA)
sys.stdin.seek(0)
sys.argv = ['', '--ascii', '--bytes']
sys.argv = ['', '--ascii', '--bytes', '--unit_scale', 'False']
with closing(UnicodeIO()) as fp:
main(fp=fp)
assert (str(len(IN_DATA)) in fp.getvalue())