diff --git a/setup.py b/setup.py index da931b15..3b880b2e 100755 --- a/setup.py +++ b/setup.py @@ -7,23 +7,22 @@ try: except ImportError: from distutils.core import setup import sys -import subprocess +from subprocess import check_call +from io import open + # For Makefile parsing import shlex try: # pragma: no cover import ConfigParser import StringIO except ImportError: # pragma: no cover - # Python 3 compatibility import configparser as ConfigParser import io as StringIO -import io import re """ Makefile auxiliary functions """ - RE_MAKE_CMD = re.compile('^\t(@\+?)(make)?', flags=re.M) @@ -38,7 +37,7 @@ def parse_makefile_aliases(filepath): # -- Parsing the Makefile using ConfigParser # Adding a fake section to make the Makefile a valid Ini file ini_str = '[root]\n' - with io.open(filepath, mode='r') as fd: + with open(filepath, mode='r') as fd: ini_str = ini_str + RE_MAKE_CMD.sub('\t', fd.read()) ini_fp = StringIO.StringIO(ini_str) # Parse using ConfigParser @@ -114,16 +113,15 @@ def execute_makefile_commands(commands, alias, verbose=False): if verbose: print("Running command: " + cmd) # Launch the command and wait to finish (synchronized call) - subprocess.check_call(parsed_cmd) + check_call(parsed_cmd) """ Main setup.py config """ - # Get version from tqdm/_version.py __version__ = None version_file = os.path.join(os.path.dirname(__file__), 'tqdm', '_version.py') -with io.open(version_file, mode='r') as fd: +with open(version_file, mode='r') as fd: exec(fd.read()) # Executing makefile commands if specified @@ -158,9 +156,8 @@ if sys.argv[1].lower().strip() == 'make': """ Python package config """ - README_rst = '' -with io.open('README.rst', mode='r', encoding='utf-8') as fd: +with open('README.rst', mode='r', encoding='utf-8') as fd: README_rst = fd.read() setup( diff --git a/tqdm/_main.py b/tqdm/_main.py index 095a63e5..76cee8ff 100644 --- a/tqdm/_main.py +++ b/tqdm/_main.py @@ -31,7 +31,9 @@ def cast(val, typ): raise TqdmTypeError(val + ' : ' + typ) -def posix_pipe(fin, fout, delim='\n', buf_size=256, callback=None): +def posix_pipe(fin, fout, delim='\n', buf_size=256, + callback=lambda int: None # pragma: no cover + ): """ Params ------ @@ -39,9 +41,7 @@ def posix_pipe(fin, fout, delim='\n', buf_size=256, callback=None): fout : file with `write` (and optionally `flush`) methods. callback : function(int), e.g.: `tqdm.update` """ - if callback is None: # pragma: no cover - def callback(i): - pass + fp_write = fout.write buf = '' tmp = '' @@ -52,7 +52,7 @@ def posix_pipe(fin, fout, delim='\n', buf_size=256, callback=None): # flush at EOF if not tmp: if buf: - fout.write(buf) + fp_write(buf) callback(1 + buf.count(delim)) # n += 1 + buf.count(delim) getattr(fout, 'flush', lambda: None)() # pragma: no cover return # n @@ -64,7 +64,7 @@ def posix_pipe(fin, fout, delim='\n', buf_size=256, callback=None): buf += tmp break else: - fout.write(buf + tmp[:i + len(delim)]) + fp_write(buf + tmp[:i + len(delim)]) callback(1) # n += 1 buf = '' tmp = tmp[i + len(delim):] @@ -133,7 +133,12 @@ Options: except KeyError as e: raise TqdmKeyError(str(e)) # sys.stderr.write('\ndebug | args: ' + str(tqdm_args) + '\n') - + except: + sys.stderr.write('\nError:\nUsage:\n tqdm [--help | options]\n') + for i in sys.stdin: + sys.stdout.write(i) + raise + else: delim = tqdm_args.pop('delim', '\n') buf_size = tqdm_args.pop('buf_size', 256) if delim == '\n': @@ -143,8 +148,3 @@ Options: with tqdm(**tqdm_args) as t: posix_pipe(sys.stdin, sys.stdout, delim, buf_size, t.update) - except: # pragma: no cover - sys.stderr.write('\nError:\nUsage:\n tqdm [--help | options]\n') - for i in sys.stdin: - sys.stdout.write(i) - raise diff --git a/tqdm/_tqdm.py b/tqdm/_tqdm.py index da45e48d..abfb34a6 100644 --- a/tqdm/_tqdm.py +++ b/tqdm/_tqdm.py @@ -85,19 +85,17 @@ class tqdm(object): updating may not work (it will print a new line at each refresh). """ fp = file - if not getattr(fp, 'flush', False): # pragma: no cover - fp.flush = lambda: None + fp_flush = getattr(fp, 'flush', lambda: None) # pragma: no cover def fp_write(s): fp.write(_unicode(s)) + fp_flush() - last_printed_len = [0] # closure over mutable variable (fast) - + last_len = [0] def print_status(s): len_s = len(s) - fp_write('\r' + s + (' ' * max(last_printed_len[0] - len_s, 0))) - fp.flush() - last_printed_len[0] = len_s + fp_write('\r' + s + (' ' * max(last_len[0] - len_s, 0))) + last_len[0] = len_s return print_status @staticmethod @@ -305,20 +303,21 @@ class tqdm(object): """ Print a message via tqdm (without overlap with bars) """ + fp = file + # Clear all bars inst_cleared = [] for inst in cls._instances: # Clear instance if in the target output file # or if write output + tqdm output are both either # sys.stdout or sys.stderr (because both are mixed in terminal) - if inst.fp == file or \ - (file in [sys.stdout, sys.stderr] and - inst.fp in [sys.stdout, sys.stderr]): + if inst.fp == fp or all(f in (sys.stdout, sys.stderr) + for f in (fp, inst.fp)): inst.clear() inst_cleared.append(inst) # Write the message - file.write(s) - file.write(end) + fp.write(s) + fp.write(end) # Force refresh display of bars we cleared for inst in inst_cleared: inst.refresh() @@ -434,11 +433,11 @@ class tqdm(object): total = None if ((ncols is None) and (file in (sys.stderr, sys.stdout))) or \ - dynamic_ncols: - if dynamic_ncols: # pragma: no cover + dynamic_ncols: # pragma: no cover + if dynamic_ncols: dynamic_ncols = _environ_cols_wrapper() ncols = dynamic_ncols(file) - else: # pragma: no cover + else: ncols = _environ_cols_wrapper()(file) if miniters is None: diff --git a/tqdm/_tqdm_gui.py b/tqdm/_tqdm_gui.py index 428a5f43..83607295 100644 --- a/tqdm/_tqdm_gui.py +++ b/tqdm/_tqdm_gui.py @@ -148,7 +148,7 @@ class tqdm_gui(tqdm): # pragma: no cover if delta_it >= miniters: cur_t = time() delta_t = cur_t - last_print_t - if delta_t >= mininterval: # pragma: no cover + if delta_t >= mininterval: elapsed = cur_t - start_t # EMA (not just overall average) if smoothing and delta_t: diff --git a/tqdm/_tqdm_notebook.py b/tqdm/_tqdm_notebook.py index ff39ed2b..8d761a04 100644 --- a/tqdm/_tqdm_notebook.py +++ b/tqdm/_tqdm_notebook.py @@ -17,71 +17,57 @@ from ._utils import _range from ._tqdm import tqdm -# import IPython/Jupyter base widget and display utilities -try: # pragma: no cover - # For IPython 4.x using ipywidgets - import ipywidgets -except ImportError: # pragma: no cover - # For IPython 3.x / 2.x - import warnings - with warnings.catch_warnings(): - ipy_deprecation_msg = "The `IPython.html` package has been deprecated" - warnings.filterwarnings('error', - message=".*" + ipy_deprecation_msg + ".*") - try: - import IPython.html.widgets as ipywidgets - except Warning as e: - if ipy_deprecation_msg not in str(e): - raise - warnings.simplefilter('ignore') +if True: # pragma: no cover + # import IPython/Jupyter base widget and display utilities + try: # IPython 4.x + import ipywidgets + except ImportError: # IPython 3.x / 2.x + import warnings + with warnings.catch_warnings(): + ipy_deprecation_msg = "The `IPython.html` package" \ + " has been deprecated" + warnings.filterwarnings('error', + message=".*" + ipy_deprecation_msg + ".*") try: - import IPython.html.widgets as ipywidgets # NOQA + import IPython.html.widgets as ipywidgets + except Warning as e: + if ipy_deprecation_msg not in str(e): + raise + warnings.simplefilter('ignore') + try: + import IPython.html.widgets as ipywidgets # NOQA + except ImportError: + pass except ImportError: pass + + try: # IPython 4.x / 3.x + from ipywidgets import IntProgress, HBox, HTML + except ImportError: + try: # IPython 2.x + from ipywidgets import IntProgressWidget as IntProgress + from ipywidgets import ContainerWidget as HBox + from ipywidgets import HTML except ImportError: pass -try: # pragma: no cover - # For IPython 4.x / 3.x - from ipywidgets import IntProgress, HBox, HTML -except ImportError: # pragma: no cover try: - # For IPython 2.x - from ipywidgets import IntProgressWidget as IntProgress - from ipywidgets import ContainerWidget as HBox - from ipywidgets import HTML + from IPython.display import display # , clear_output except ImportError: - # from ._tqdm import tqdm, trange - # def warnWrap(fn, msg): - # def inner(*args, **kwargs): - # from sys import stderr - # stderr.write(msg) - # return fn(*args, **kwargs) - # return inner - # tqdm_notebook = warnWrap(tqdm, "Warning:\n\tNo ipywidgets." - # "\ntFalling back to `tqdm`.\n") - # tnrange = warnWrap(trange, "Warning:\n\tNo ipywidgets." - # "\n\tFalling back to `trange`.\n") - # exit pass -try: # pragma: no cover - from IPython.display import display # , clear_output -except ImportError: # pragma: no cover - pass - -# HTML encoding -try: # pragma: no cover - from html import escape # python 3.x -except ImportError: # pragma: no cover - from cgi import escape # python 2.x + # HTML encoding + try: # Py3 + from html import escape + except ImportError: # Py2 + from cgi import escape __author__ = {"github.com/": ["lrq3000", "casperdcl", "alexanderkuk"]} __all__ = ['tqdm_notebook', 'tnrange'] -class tqdm_notebook(tqdm): # pragma: no cover +class tqdm_notebook(tqdm): """ Experimental IPython/Jupyter Notebook widget using tqdm! """ @@ -97,8 +83,6 @@ class tqdm_notebook(tqdm): # pragma: no cover # return super(tqdm_notebook, tqdm_notebook).status_printer(file) fp = file - if not getattr(fp, 'flush', False): # pragma: no cover - fp.flush = lambda: None # Prepare IPython progress bar if total: @@ -224,7 +208,7 @@ class tqdm_notebook(tqdm): # pragma: no cover return -def tnrange(*args, **kwargs): # pragma: no cover +def tnrange(*args, **kwargs): """ A shortcut for tqdm_notebook(xrange(*args), **kwargs). On Python3+ range is used instead of xrange. diff --git a/tqdm/_tqdm_pandas.py b/tqdm/_tqdm_pandas.py index 87f3752b..798547ca 100644 --- a/tqdm/_tqdm_pandas.py +++ b/tqdm/_tqdm_pandas.py @@ -7,7 +7,7 @@ __author__ = "github.com/casperdcl" __all__ = ['tqdm_pandas'] -def tqdm_pandas(t): # pragma: no cover +def tqdm_pandas(t): """ Registers the given `tqdm` instance with `pandas.core.groupby.DataFrameGroupBy.progress_apply`. diff --git a/tqdm/_utils.py b/tqdm/_utils.py index 4695f939..a4e14ede 100644 --- a/tqdm/_utils.py +++ b/tqdm/_utils.py @@ -8,38 +8,35 @@ IS_NIX = (not IS_WIN) and any( ['CYGWIN', 'MSYS', 'Linux', 'Darwin', 'SunOS', 'FreeBSD']) -try: # pragma: no cover - _range = xrange -except NameError: # pragma: no cover - _range = range +if True: # pragma: no cover + try: + _range = xrange + except NameError: + _range = range + try: + _unich = unichr + except NameError: + _unich = chr -try: # pragma: no cover - _unich = unichr -except NameError: # pragma: no cover - _unich = chr + try: + _unicode = unicode + except NameError: + _unicode = str -try: # pragma: no cover - _unicode = unicode -except NameError: # pragma: no cover - _unicode = str # in Py3, all strings are unicode - - -try: # pragma: no cover - if IS_WIN: - import colorama - colorama.init() - else: + try: + if IS_WIN: + import colorama + colorama.init() + else: + colorama = None + except ImportError: colorama = None -except ImportError: # pragma: no cover - colorama = None -except: # pragma: no cover - raise # try updating colorama? -try: # pragma: no cover - from weakref import WeakSet -except ImportError: # pragma: nocover - WeakSet = set + try: + from weakref import WeakSet + except ImportError: + WeakSet = set def _is_utf(encoding): @@ -47,12 +44,10 @@ def _is_utf(encoding): def _supports_unicode(file): - if not getattr(file, 'encoding', None): - return False - if not getattr(file, 'interface', None): # pragma: no cover + return _is_utf(file.encoding) if ( + getattr(file, 'encoding', None) or # FakeStreams from things like bpython-curses can lie - return _is_utf(file.encoding) - return False # pragma: no cover + getattr(file, 'interface', None)) else False # pragma: no cover def _environ_cols_wrapper(): # pragma: no cover @@ -137,10 +132,7 @@ def _environ_cols_linux(fp): # pragma: no cover def _term_move_up(): # pragma: no cover - if os.name == 'nt': - if colorama is None: - return '' - return '\x1b[A' + return '' if (os.name == 'nt') and (colorama is None) else '\x1b[A' def _sh(*cmd, **kwargs): diff --git a/tqdm/_version.py b/tqdm/_version.py index c22a1095..5893322e 100644 --- a/tqdm/_version.py +++ b/tqdm/_version.py @@ -1,5 +1,5 @@ # Definition of the version number -try: # pragma: no cover +try: from ._utils import _sh except: # pragma: no cover _sh = None