Skip to content

Commit

Permalink
tests, tidy command line interface and remove docopt dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
casperdcl committed Apr 22, 2016
1 parent 8e1ce8b commit d632b1a
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 37 deletions.
2 changes: 0 additions & 2 deletions tox.ini
Expand Up @@ -13,7 +13,6 @@ deps =
nose-timer
coverage<4
coveralls
docopt
commands =
nosetests --with-coverage --with-timer --cover-package=tqdm --ignore-files="tests_perf\.py" -d -v tqdm/
coveralls
Expand All @@ -38,6 +37,5 @@ commands =
deps =
nose
nose-timer
docopt
commands =
nosetests --with-timer tqdm/tests/tests_perf.py -d -v
69 changes: 41 additions & 28 deletions tqdm/_main.py
@@ -1,3 +1,4 @@
from __future__ import print_function
from ._tqdm import tqdm
from ._version import __version__ # NOQA
import sys
Expand All @@ -6,51 +7,63 @@


def cast(val, typ):
if val == 'None':
return None
if typ == 'bool':
return str(val) == 'True'
# try:
return (str(val) == 'True') or not str(val)
return eval(typ + '("' + str(val) + '")')
# except:
# # print val, typ
# if val == 'special':
# return 'whatever... just an example'
# else:
# return eval(typ + '()')


RE_OPTS = re.compile(r' {8}(\w+)\s{2,}:\s*(str|int|float|bool)', flags=re.M)
# RE_OPTS_SOME = re.compile(r' {8}(\w+) : (str|int|float)', flags=re.M)
# RE_OPTS_BOOL = re.compile(r' {8}(\w+) : bool', flags=re.M)
# Don't have to worry about Python 2.6 not supporting re flags
# since it does not support executing modules either.
# RE_OPTS = re.compile(r' {8}(\S+)\s{2,}:\s*(str|int|float|bool)', flags=re.M)
RE_OPTS = re.compile(r' {8}(\S+)\s{2,}:\s*([^\s,]+)', flags=re.M)

# TODO: add custom support for some of the following?
UNSUPPORTED_OPTS = ('iterable', 'gui', 'out', 'file')

def main():
from docopt import docopt

def main():
d = tqdm.__init__.__doc__

opt_types = dict(RE_OPTS.findall(d))
# d = RE_OPTS_SOME.sub(r' --\1=<v> ', d)
# d = RE_OPTS_BOOL.sub(r' --\1 ', d)
d = RE_OPTS.sub(r' --\1=<v> : \2', d)
d = d[d.find(' --desc='):d.find('Returns\n')]
__doc__ = """
Usage:
tqdm [--help | options]

for o in UNSUPPORTED_OPTS:
opt_types.pop(o)

# 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])
d = ''.join(' --{0}=<{0}> : {1}{2}'.format(*otd)
for otd in opt_types_desc if otd[0] not in UNSUPPORTED_OPTS)

__doc__ = """Usage:
tqdm [--help | options]
Options:
-h, --help Print this help and exit
-v, --version Print version and exit
""" + d
opts = docopt(__doc__, version=__version__)
""" + d.strip('\n') + '\n'

# opts = docopt(__doc__, version=__version__)
if any(v in sys.argv for v in ('-v', '--version')):
sys.stdout.write(__version__ + '\n')
sys.exit(0)
elif any(v in sys.argv for v in ('-h', '--help')):
sys.stdout.write(__doc__ + '\n')
sys.exit(0)

argv = re.split('(--\S+)[=\s]*', ' '.join(sys.argv[1:]))
opts = dict(zip(argv[1::2], argv[2::2]))

tqdm_args = {}
try:
for opt in opt_types:
opt_types[opt] = cast(opts['--' + opt], opt_types[opt])
for i in tqdm(sys.stdin, **opt_types):
for (o, v) in opts.items():
tqdm_args[o[2:]] = cast(v, opt_types[o[2:]])
# print('debug |', tqdm_args)
for i in tqdm(sys.stdin, **tqdm_args):
sys.stdout.write(i)
except: # pragma: no cover
sys.stderr.write(__doc__ + '\n')
for i in sys.stdin:
sys.stdout.write(i)
sys.stderr.write('\nUsage:\n tqdm [--help | options]\n')
raise
6 changes: 4 additions & 2 deletions tqdm/_tqdm.py
Expand Up @@ -300,7 +300,8 @@ def write(cls, s, file=sys.stdout, end="\n"):
# Force refresh display of all bars
for inst in cls._instances:
inst.refresh()
# TODO: make a list with all instances including absolutely positioned ones?
# TODO: make a list with all instances
# including absolutely positioned ones?

def __init__(self, iterable=None, desc=None, total=None, leave=True,
file=sys.stderr, ncols=None, mininterval=0.1,
Expand All @@ -321,7 +322,8 @@ def __init__(self, iterable=None, desc=None, total=None, leave=True,
len(iterable) is used if possible. As a last resort, only basic
progress statistics are displayed (no ETA, no progressbar).
If `gui` is True and this parameter needs subsequent updating,
specify an initial arbitrary large positive integer, e.g. int(9e9).
specify an initial arbitrary large positive integer,
e.g. int(9e9).
leave : bool, optional
If [default: True], keeps all traces of the progressbar
upon termination of iteration.
Expand Down
16 changes: 11 additions & 5 deletions tqdm/tests/tests_main.py
@@ -1,7 +1,6 @@
import sys
import subprocess
from tqdm import main
from docopt import DocoptExit
from copy import deepcopy

from tests_tqdm import with_setup, pretest, posttest, _range
Expand Down Expand Up @@ -37,15 +36,22 @@ def test_main():
'--ascii', 'True', '--unit_scale', 'True']
import tqdm.__main__ # NOQA

sys.argv = ['', '--bad', 'arg',
sys.argv = ['', '--bad_arg_u_ment', 'foo',
'--ascii', 'True', '--unit_scale', 'True']
try:
main()
except DocoptExit as e:
if """Usage:
tqdm [--help | options]""" not in str(e):
except KeyError as e:
if 'bad_arg_u_ment' not in str(e):
raise

for i in ('-h', '--help', '-v', '--version'):
sys.argv = ['', i]
try:
main()
except SystemExit:
pass

# clean up
try:
sys.stdin, sys.argv = _SYS
except:
Expand Down

0 comments on commit d632b1a

Please sign in to comment.