Skip to content

Commit 55652f0

Browse files
authored
Replace tqdm with Rich for progress bar (#877)
* Throttle upload for testing * Add initial rich progress bar * Define progress bar columns * Remove throttling code * Remove tqdm * Rework retries test * Add custom time column * Add rich to intersphinx * Revert "Add rich to intersphinx" This reverts commit baa16c1. * Revert "Add custom time column" This reverts commit 7fed68d. * Use single compact time column * Add changelog entry
1 parent c506b22 commit 55652f0

File tree

5 files changed

+31
-32
lines changed

5 files changed

+31
-32
lines changed

changelog/877.feature.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Use Rich instead of tqdm for upload progress bar.

mypy.ini

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ show_traceback = True
55
warn_redundant_casts = True
66
warn_unused_configs = True
77
warn_unused_ignores = True
8-
; Enabling this will fail on subclasses of untyped imports, e.g. tqdm
8+
; Enabling this will fail on subclasses of untyped imports, e.g. pkginfo
99
; disallow_subclassing_any = True
1010
disallow_any_generics = True
1111
disallow_untyped_calls = True
@@ -33,10 +33,6 @@ ignore_missing_imports = True
3333
[mypy-rfc3986]
3434
ignore_missing_imports = True
3535

36-
[mypy-tqdm]
37-
; https://github.com/tqdm/tqdm/issues/260
38-
ignore_missing_imports = True
39-
4036
[mypy-urllib3]
4137
; https://github.com/urllib3/urllib3/issues/867
4238
ignore_missing_imports = True

setup.cfg

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,10 @@ install_requires=
4141
requests >= 2.20
4242
requests-toolbelt >= 0.8.0, != 0.9.0
4343
urllib3 >= 1.26.0
44-
tqdm >= 4.14
4544
importlib-metadata >= 3.6
4645
keyring >= 15.1
4746
rfc3986 >= 1.4.0
48-
rich
47+
rich >= 12.0.0
4948
include_package_data = True
5049

5150
[options.entry_points]

tests/test_repository.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,18 +185,21 @@ def test_package_is_registered(default_repo):
185185

186186

187187
@pytest.mark.parametrize("disable_progress_bar", [True, False])
188-
def test_disable_progress_bar_is_forwarded_to_tqdm(
188+
def test_disable_progress_bar_is_forwarded_to_rich(
189189
monkeypatch, tmpdir, disable_progress_bar, default_repo
190190
):
191191
"""Toggle display of upload progress bar."""
192192

193193
@contextmanager
194-
def progressbarstub(*args, **kwargs):
194+
def ProgressStub(*args, **kwargs):
195195
assert "disable" in kwargs
196196
assert kwargs["disable"] == disable_progress_bar
197-
yield
197+
yield pretend.stub(
198+
add_task=lambda description, total: None,
199+
update=lambda task_id, completed: None,
200+
)
198201

199-
monkeypatch.setattr(repository, "ProgressBar", progressbarstub)
202+
monkeypatch.setattr(repository.rich.progress, "Progress", ProgressStub)
200203
default_repo.disable_progress_bar = disable_progress_bar
201204

202205
default_repo.session = pretend.stub(

twine/repository.py

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,11 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414
import logging
15-
import sys
1615
from typing import Any, Dict, List, Optional, Set, Tuple, cast
1716

1817
import requests
1918
import requests_toolbelt
20-
import tqdm
19+
import rich.progress
2120
import urllib3
2221
from requests import adapters
2322
from requests_toolbelt.utils import user_agent
@@ -38,16 +37,6 @@
3837
logger = logging.getLogger(__name__)
3938

4039

41-
class ProgressBar(tqdm.tqdm):
42-
def update_to(self, n: int) -> None:
43-
"""Update the bar in the way compatible with requests-toolbelt.
44-
45-
This is identical to tqdm.update, except ``n`` will be the current
46-
value - not the delta as tqdm expects.
47-
"""
48-
self.update(n - self.n) # will also do self.n = n
49-
50-
5140
class Repository:
5241
def __init__(
5342
self,
@@ -156,17 +145,28 @@ def _upload(self, package: package_file.PackageFile) -> requests.Response:
156145
("content", (package.basefilename, fp, "application/octet-stream"))
157146
)
158147
encoder = requests_toolbelt.MultipartEncoder(data_to_send)
159-
with ProgressBar(
160-
total=encoder.len,
161-
unit="B",
162-
unit_scale=True,
163-
unit_divisor=1024,
164-
miniters=1,
165-
file=sys.stdout,
148+
149+
with rich.progress.Progress(
150+
"[progress.percentage]{task.percentage:>3.0f}%",
151+
rich.progress.BarColumn(),
152+
rich.progress.DownloadColumn(),
153+
"•",
154+
rich.progress.TimeRemainingColumn(
155+
compact=True,
156+
elapsed_when_finished=True,
157+
),
158+
"•",
159+
rich.progress.TransferSpeedColumn(),
166160
disable=self.disable_progress_bar,
167-
) as bar:
161+
) as progress:
162+
task_id = progress.add_task("", total=encoder.len)
163+
168164
monitor = requests_toolbelt.MultipartEncoderMonitor(
169-
encoder, lambda monitor: bar.update_to(monitor.bytes_read)
165+
encoder,
166+
lambda monitor: progress.update(
167+
task_id,
168+
completed=monitor.bytes_read,
169+
),
170170
)
171171

172172
resp = self.session.post(

0 commit comments

Comments
 (0)