Skip to content

Commit

Permalink
cleaned up lib.log (#2902)
Browse files Browse the repository at this point in the history
- fix #2734
  (docs now build with sphinx 2.3)
- formally deprecated lib.log.echo() (CHANGELOG, @deprecate, and test)
- explicitly added docs to ProgressMeter
  - avoids sphinx failure due to wrong formatting in tqdm.auto.tqdm
  - add specific example for MDA
  - document our own verbose kwarg
  - improved markup
  - not documented: gui kwarg (discouraged in original docs)

(cherry picked from commit 5e68617)
  • Loading branch information
orbeckst committed Aug 16, 2020
1 parent 89cf0a3 commit 9100720
Show file tree
Hide file tree
Showing 3 changed files with 168 additions and 15 deletions.
1 change: 1 addition & 0 deletions package/CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ Enhancements
Deprecations
* waterdynamics.HydrogenBondLifetimes will be removed in 2.0.0 and
replaced with hydrogenbonds.HydrogenBondAnalysis.lifetime() (#2547)
* lib.util.echo() will be removed in 2.0.0


06/09/20 richardjgowers, kain88-de, lilyminium, p-j-smith, bdice, joaomcteixeira,
Expand Down
175 changes: 162 additions & 13 deletions package/MDAnalysis/lib/log.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
from tqdm.auto import tqdm

from .. import version
from .util import deprecate


def start_logging(logfile="MDAnalysis.log", version=version.__version__):
Expand Down Expand Up @@ -175,6 +176,7 @@ def emit(self, record):
pass


@deprecate(release="1.0.1", remove="2.0.0")
def echo(s='', replace=False, newline=True):
r"""Simple string output that immediately prints to the console.
Expand All @@ -190,7 +192,6 @@ def echo(s='', replace=False, newline=True):
practice, ``\r`` is added at the beginning of the string.
newline : bool
If ``True``, a newline is added at the end of the string.
"""
if replace:
s = '\r' + s
Expand All @@ -201,22 +202,16 @@ def echo(s='', replace=False, newline=True):
print(s, file=sys.stderr, end=end)
sys.stderr.flush()


def _new_format(template, variables):
"""Format a string that follows the {}-based syntax.
"""
"""Format a string that follows the `{}`-based syntax."""
return template.format(**variables)


def _legacy_format(template, variables):
"""Format a string that follows the %-based syntax.
"""
"""Format a string that follows the `%`-based syntax."""
return template % variables


def _guess_string_format(template):
"""Guess if the template follow {}-based or %-based syntax.
"""
"""Guess if the template follow `{}`-based or `%`-based syntax."""
match = re.search(r'%\((step|numsteps|percentage)\)', template)
if match is None:
return _new_format
Expand All @@ -228,8 +223,8 @@ class ProgressMeter(object):
r"""Simple progress meter (Deprecated)
..Warning:
This class is deprecated and will be removed in version 2.0.
Please use :class:`MDAnalysis.lib.log.ProgressBar` instead.
This class is deprecated and will be removed in version 2.0.
Please use :class:`MDAnalysis.lib.log.ProgressBar` instead.
The :class:`ProgressMeter` class can be used to show running progress such
as frames processed or percentage done to give the user feedback on the
Expand Down Expand Up @@ -320,6 +315,7 @@ class ProgressMeter(object):
RMSD 1.89 at 200/10000 [ 2.0%]
...
.. versionchanged:: 0.8
Keyword argument *quiet* was added.
Expand All @@ -330,7 +326,7 @@ class ProgressMeter(object):
Keyword argument *quiet* is deprecated in favor of *verbose*.
.. deprecated:: 1.0
This class is deprecated in favor of *ProgressBar*.
This class is deprecated in favor of :class:`ProgressBar`.
"""

Expand Down Expand Up @@ -412,7 +408,160 @@ def echo(self, step, **kwargs):


class ProgressBar(tqdm):
r"""Display a visual progress bar and time estimate.
The :class:`ProgressBar` decorates an iterable object, returning an
iterator which acts exactly like the original iterable, but prints a
dynamically updating progressbar every time a value is requested. See the
example below for how to use it when iterating over the frames of a
trajectory.
Parameters
----------
iterable : iterable, optional
Iterable to decorate with a progressbar.
Leave blank to manually manage the updates.
verbose : bool, optional
If ``True`` (the default) then show the progress bar, *unless* the
`disable` keyword is set to ``True`` (`disable` takes precedence over
`verbose`). If `verbose` is set to ``None`` then the progress bar is
displayed (like ``True``), *unless* this is a non-TTY output device
(see `disable`).
desc : str, optional
Prefix for the progressbar.
total : int or float, optional
The number of expected iterations. If unspecified,
``len(iterable)`` is used if possible. If ``float("inf")`` or as a last
resort, only basic progress statistics are displayed
(no ETA, no progressbar).
leave : bool, optional
If [default: ``True``], keeps all traces of the progressbar
upon termination of iteration.
If ``None``, will leave only if `position` is 0.
file : :class:`io.TextIOWrapper` or :class:`io.StringIO`, optional
Specifies where to output the progress messages (default:
:data:`sys.stderr`). Uses :meth:`file.write` and :meth:`file.flush`
methods. For encoding, see `write_bytes`.
ncols : int, optional
The width of the entire output message. If specified,
dynamically resizes the progressbar to stay within this bound.
If unspecified, attempts to use environment width. The
fallback is a meter width of 10 and no limit for the counter and
statistics. If 0, will not print any meter (only stats).
mininterval : float, optional
Minimum progress display update interval [default: 0.1] seconds.
maxinterval : float, optional
Maximum progress display update interval [default: 10] seconds.
Automatically adjusts `miniters` to correspond to `mininterval`
after long display update lag. Only works if `dynamic_miniters`
or monitor thread is enabled.
miniters : int or float, optional
Minimum progress display update interval, in iterations.
If 0 and `dynamic_miniters`, will automatically adjust to equal
`mininterval` (more CPU efficient, good for tight loops).
If > 0, will skip display of specified number of iterations.
Tweak this and `mininterval` to get very efficient loops.
If your progress is erratic with both fast and slow iterations
(network, skipping items, etc) you should set miniters=1.
ascii : bool or str, optional
If unspecified or ``False``, use unicode (smooth blocks) to fill
the meter. The fallback is to use ASCII characters " 123456789#".
disable : bool, optional
Whether to disable the entire progressbar wrapper
[default: ``False``]. If set to None, disable on non-TTY.
unit : str, optional
String that will be used to define the unit of each iteration
[default: it].
unit_scale : bool or int or float, optional
If 1 or True, the number of iterations will be reduced/scaled
automatically and a metric prefix following the
International System of Units standard will be added
(kilo, mega, etc.) [default: ``False``]. If any other non-zero
number, will scale `total` and `n`.
dynamic_ncols : bool, optional
If set, constantly alters `ncols` and `nrows` to the
environment (allowing for window resizes) [default: ``False``].
smoothing : float, optional
Exponential moving average smoothing factor for speed estimates
(ignored in GUI mode). Ranges from 0 (average speed) to 1
(current/instantaneous speed) [default: 0.3].
bar_format : str, optional
Specify a custom bar string formatting. May impact performance.
[default: ``'{l_bar}{bar}{r_bar}'``], where ``l_bar='{desc}:
{percentage:3.0f}%|'`` and ``r_bar='| {n_fmt}/{total_fmt}
[{elapsed}<{remaining}, {rate_fmt}{postfix}]'``
Possible vars: l_bar, bar, r_bar, n, n_fmt, total, total_fmt,
percentage, elapsed, elapsed_s, ncols, nrows, desc, unit,
rate, rate_fmt, rate_noinv, rate_noinv_fmt,
rate_inv, rate_inv_fmt, postfix, unit_divisor,
remaining, remaining_s.
Note that a trailing ": " is automatically removed after {desc}
if the latter is empty.
initial : int or float, optional
The initial counter value. Useful when restarting a progress bar
[default: 0]. If using :class:`float`, consider specifying ``{n:.3f}``
or similar in `bar_format`, or specifying `unit_scale`.
position : int, optional
Specify the line offset to print this bar (starting from 0)
Automatic if unspecified.
Useful to manage multiple bars at once (e.g., from threads).
postfix : dict or \*, optional
Specify additional stats to display at the end of the bar.
Calls ``set_postfix(**postfix)`` if possible (:class:`dict`).
unit_divisor : float, optional
[default: 1000], ignored unless `unit_scale` is ``True``.
write_bytes : bool, optional
If (default: ``None``) and `file` is unspecified,
bytes will be written in Python 2. If `True` will also write
bytes. In all other cases will default to unicode.
lock_args : tuple, optional
Passed to `refresh` for intermediate output
(initialisation, iterating, and updating).
nrows : int, optional
The screen height. If specified, hides nested bars outside this
bound. If unspecified, attempts to use environment height.
The fallback is 20.
Returns
-------
out : decorated iterator.
Example
-------
To get a progress bar when analyzing a trajectory::
from MDAnalysis.lib.log import ProgressBar
...
for ts in ProgressBar(u.trajectory):
# perform analysis
will produce something similar to ::
30%|███████████ | 3/10 [00:13<00:30, 4.42s/it]
in a terminal or Jupyter notebook.
See Also
--------
The :class:`ProgressBar` is derived from :class:`tqdm.auto.tqdm`; see the
`tqdm documentation`_ for further details on how to use it.
.. _`tqdm documentation`: https://tqdm.github.io/
"""
def __init__(self, *args, **kwargs):
""""""
# ^^^^ keep the empty doc string to avoid Sphinx doc errors with the
# original doc string from tqdm.auto.tqdm
verbose = kwargs.pop('verbose', True)
# disable: Whether to disable the entire progressbar wrapper [default: False].
# If set to None, disable on non-TTY.
Expand Down
7 changes: 5 additions & 2 deletions testsuite/MDAnalysisTests/lib/test_log.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import warnings
import pytest

from MDAnalysis.lib.log import ProgressMeter, ProgressBar
from MDAnalysis.lib.log import ProgressMeter, ProgressBar, echo


class TestProgressMeter(object):
Expand All @@ -49,7 +49,10 @@ def test_output(self, capsys):
expected = 'Step 10/10 [100.0%]'
actual = err.strip().split('\r')[-1]
assert actual == expected


def test_echo_deprecated():
with pytest.deprecated_call():
echo("F=ma -- Isaac Newton")

class TestProgressBar(object):

Expand Down

0 comments on commit 9100720

Please sign in to comment.