diff --git a/PQAnalysis/analysis/rdf/rdf.py b/PQAnalysis/analysis/rdf/rdf.py index ff8e37d1..129538db 100644 --- a/PQAnalysis/analysis/rdf/rdf.py +++ b/PQAnalysis/analysis/rdf/rdf.py @@ -21,7 +21,7 @@ from PQAnalysis.utils.progress import tqdm # local absolute imports -from PQAnalysis.config import with_progress_bar +from PQAnalysis import config from PQAnalysis.types import Np1DNumberArray, PositiveInt, PositiveReal from PQAnalysis.core import distance, Cell, Cells from PQAnalysis.traj import ( @@ -873,7 +873,7 @@ def _calculate_bins(self): for frame in tqdm( itertools.chain([self.first_frame], self.frame_generator), total=self.n_frames, - disable=not with_progress_bar + disable=not config.with_progress_bar ): for i, reference_index in enumerate(self.reference_indices): @@ -953,7 +953,7 @@ def _calculate_bins_raw(self): for values, cell in tqdm( self._raw_reader.raw_frame_generator(), total=self.n_frames, - disable=not with_progress_bar): + disable=not config.with_progress_bar): counter += 1 diff --git a/PQAnalysis/cli/_argument_parser.py b/PQAnalysis/cli/_argument_parser.py index bb26ec76..7eb924e2 100644 --- a/PQAnalysis/cli/_argument_parser.py +++ b/PQAnalysis/cli/_argument_parser.py @@ -195,7 +195,10 @@ def _parse_progress(self): The progress argument is an optional argument and defaults to True. """ super().add_argument( - '--progress', action='store_false', help='Show progress bar.' + '--progress', + action=argparse.BooleanOptionalAction, + default=True, + help='Show progress bar.' ) def _parse_version(self): diff --git a/tests/analysis/rdf/test_rdf.py b/tests/analysis/rdf/test_rdf.py index 09706041..0b7c0ae3 100644 --- a/tests/analysis/rdf/test_rdf.py +++ b/tests/analysis/rdf/test_rdf.py @@ -1,6 +1,9 @@ +import sys + import numpy as np import pytest +from PQAnalysis import config from PQAnalysis.analysis.rdf.exceptions import RDFError from PQAnalysis.analysis import RDF from PQAnalysis.traj import Trajectory @@ -298,6 +301,31 @@ def test__add_to_bins(): +def test_progress_bar_binds_config_at_call_time(monkeypatch): + # config.with_progress_bar is set by the CLI after the module + # import, so it must be read at call time, not bound by value + # at import time + captured = {} + + def fake_tqdm(iterable, **kwargs): + captured.update(kwargs) + return iterable + + rdf_module = sys.modules[RDF.__module__] + monkeypatch.setattr(rdf_module, "tqdm", fake_tqdm) + + monkeypatch.setattr(config, "with_progress_bar", False) + RDF(_make_no_intra_trajectory(), ["H"], ["C"], delta_r=0.5, n_bins=5).run() + assert captured["disable"] is True + + captured.clear() + + monkeypatch.setattr(config, "with_progress_bar", True) + RDF(_make_no_intra_trajectory(), ["H"], ["C"], delta_r=0.5, n_bins=5).run() + assert captured["disable"] is False + + + class TestRDF: def test__init__type_checking(self, caplog): diff --git a/tests/cli/test_main.py b/tests/cli/test_main.py index 224b4acd..618141a4 100644 --- a/tests/cli/test_main.py +++ b/tests/cli/test_main.py @@ -78,3 +78,35 @@ def test_argcomplete_is_loaded_only_for_shell_completion(monkeypatch): assert calls == [parser] assert args.progress is True + + + +@pytest.mark.parametrize( + ("flags", "expected"), + [ + ([], True), + (["--progress"], True), + (["--no-progress"], False), + ], +) +def test_progress_flag_matches_its_help_text(monkeypatch, flags, expected): + # --progress used to be a store_false flag, so passing it hid the + # progress bar although its help text reads "Show progress bar." + monkeypatch.setattr(argument_parser, "print_header", lambda: None) + monkeypatch.setattr( + argument_parser.config, + "with_progress_bar", + argument_parser.config.with_progress_bar, + ) + + parser = argument_parser._ArgumentParser(prog="pqanalysis-test") + root_logger = argument_parser.logging.getLogger() + original_level = root_logger.level + + try: + args = parser.parse_args([*flags, "--log-file", "off"]) + finally: + root_logger.setLevel(original_level) + + assert args.progress is expected + assert argument_parser.config.with_progress_bar is expected