File: test_tqdm.py

package info (click to toggle)
magicgui 0.10.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 21,880 kB
  • sloc: python: 11,573; makefile: 11; sh: 9
file content (210 lines) | stat: -rw-r--r-- 5,594 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
"""Tests for the tqdm wrapper."""

from time import sleep

import pytest

from magicgui import magicgui

tqdm = pytest.importorskip("tqdm", reason="need tqdm installed to test tqdm")
from magicgui.tqdm import tqdm, trange  # noqa


def test_tqdm_outside_of_functiongui():
    """Test that we can make a tqdm wrapper with ProgressBar outside of @magicgui."""
    with trange(10) as pbar:
        assert pbar.n == 0
        assert pbar.total == 10
        assert not pbar._mgui

    assert tuple(trange(5)) == tuple(range(5))


def test_indeterminate_tqdm_outside_of_functiongui():
    """Test that we can have tqdm with an indeterminate total range."""
    with tqdm(total=None) as pbar:
        assert pbar.total is None
        assert pbar.n == 0
        pbar.update()
        assert pbar.n == 1


def test_disabled_tqdm():
    """Test that a disabled tqdm does not have a progressbar or magicgui."""

    @magicgui
    def f():
        with trange(10, disable=True) as pbar:
            assert not hasattr(pbar, "progressbar")
            assert not pbar._mgui


def test_no_leave_tqdm():
    """Test that leave=False hides the progressbar when done (tqdm API wording)"""

    @magicgui
    def f():
        with trange(10, leave=True) as pbar1:
            pass
        assert pbar1.progressbar.visible is True

    f.show()
    f()

    @magicgui
    def f2():
        with trange(10, leave=False) as pbar2:
            pass
        assert pbar2.progressbar.visible is False

    f2.show()
    f2()


def test_unbound_tqdm():
    """Test that tqdm without defined total sill have a range of (0, 0)."""

    @magicgui
    def f():
        with tqdm() as pbar:
            assert pbar.total is None
            # undefined range will render as a "busy" indicator
            assert pbar.progressbar.range == (0, 0)

    f.show()
    f()


def test_tqdm_std_err(capsys):
    """Test that tqdm inside an invisible magicgui falls back to console behavior."""

    # outside of a magicgui it falls back to tqdm_std behavior
    with tqdm(range(10)) as t_obj:
        iter(t_obj)
    captured = capsys.readouterr()

    assert "0%|" in str(captured.err)
    assert "| 0/10" in str(captured.err)
    assert not str(captured.out)


def test_tqdm_in_visible_mgui_std_err(capsys):
    """Test that tqdm inside an mgui outputs to console only when mgui not visible."""

    # inside of a of a magicgui it falls back to tqdm_std behavior
    @magicgui
    def f():
        with tqdm(range(10)) as t_obj:
            iter(t_obj)

    f()
    captured = capsys.readouterr()
    assert "0%|" in str(captured.err)
    assert "| 0/10" in str(captured.err)
    assert not str(captured.out)

    # showing the widget disables the output to console behavior
    f.show()
    f()
    captured = capsys.readouterr()
    assert not str(captured.err)
    assert not str(captured.out)


# Test various ways that tqdm might need to traverse the frame stack:


def test_tqdm_inside_of_magicgui():
    """Test that tqdm can find the magicgui within which it is called."""

    @magicgui
    def long_func(steps=2):
        for _i in tqdm([0, 1]):
            sleep(0.02)

    # before calling the function, we won't have any progress bars
    long_func.show()
    assert not long_func._tqdm_pbars
    long_func()
    # after calling the it, we should now have a progress bars
    assert len(long_func._tqdm_pbars) == 1
    # but calling it again won't add more
    long_func()
    assert len(long_func._tqdm_pbars) == 1


def test_trange_inside_of_magicgui():
    """Test that trange can find the magicgui within which it is called."""

    @magicgui
    def long_func(steps=2):
        for _i in trange(4):
            pass

    long_func.show()
    assert not long_func._tqdm_pbars
    long_func()
    assert len(long_func._tqdm_pbars) == 1


def test_indeterminate_tqdm_inside_magicgui():
    """Test that we can have tqdm with an indeterminate total range."""

    @magicgui
    def long_func():
        """Long running computation with indeterminate range."""
        with tqdm(total=None):
            pass

    long_func.show()
    assert not long_func._tqdm_pbars
    long_func()
    assert len(long_func._tqdm_pbars) == 1


def _indirectly_decorated(steps=2):
    for _i in trange(4):
        pass


def test_trange_inside_of_indirectly_decorated_magicgui():
    """Test that trange can find the magicgui within which it is called."""
    indirectly_decorated = magicgui(_indirectly_decorated)
    indirectly_decorated.show()
    assert not indirectly_decorated._tqdm_pbars
    indirectly_decorated()
    assert len(indirectly_decorated._tqdm_pbars) == 1


def test_tqdm_nested():
    """Test that tqdm can find the magicgui within which it is called."""

    @magicgui
    def long_func():
        for _i in trange(4):
            for _x in trange(4):
                pass

    long_func.show()
    # before calling the function, we won't have any progress bars
    assert not long_func._tqdm_pbars
    long_func()
    # after calling the it, we should now have a progress bars
    assert len(long_func._tqdm_pbars) == 2

    # the depth is all that matters... not the total number of tqdms
    @magicgui
    def long_func2():
        for _i in trange(4):
            for _x in trange(4):
                pass

        for _x in trange(4):
            pass

    long_func2.show()
    # before calling the function, we won't have any progress bars
    assert not long_func2._tqdm_pbars
    long_func2()
    # after calling the it, we should now have a progress bars
    assert len(long_func2._tqdm_pbars) == 2