diff --git a/CHANGES.rst b/CHANGES.rst index 7f1530ab4..dce2f9513 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -31,6 +31,8 @@ Unreleased - When generating a command's name from a decorated function's name, the suffixes ``_command``, ``_cmd``, ``_group``, and ``_grp`` are removed. :issue:`2322` +- Specialized typing of ``progressbar(length=...)`` as ``ProgressBar[int]``. + :pr:`2630` Version 8.1.7 diff --git a/src/click/termui.py b/src/click/termui.py index 95f6aaee1..df585917b 100644 --- a/src/click/termui.py +++ b/src/click/termui.py @@ -284,6 +284,46 @@ def echo_via_pager( return pager(itertools.chain(text_generator, "\n"), color) +@t.overload +def progressbar( + *, + length: int, + label: str | None = None, + show_eta: bool = True, + show_percent: bool | None = None, + show_pos: bool = False, + fill_char: str = "#", + empty_char: str = "-", + bar_template: str = "%(label)s [%(bar)s] %(info)s", + info_sep: str = " ", + width: int = 36, + color: bool | None = None, + update_min_steps: int = 1, +) -> ProgressBar[int]: + ... + + +@t.overload +def progressbar( + iterable: cabc.Iterable[V] | None = None, + length: int | None = None, + label: str | None = None, + show_eta: bool = True, + show_percent: bool | None = None, + show_pos: bool = False, + item_show_func: t.Callable[[V | None], str | None] | None = None, + fill_char: str = "#", + empty_char: str = "-", + bar_template: str = "%(label)s [%(bar)s] %(info)s", + info_sep: str = " ", + width: int = 36, + file: t.TextIO | None = None, + color: bool | None = None, + update_min_steps: int = 1, +) -> ProgressBar[V]: + ... + + def progressbar( iterable: cabc.Iterable[V] | None = None, length: int | None = None, diff --git a/tests/typing/typing_progressbar.py b/tests/typing/typing_progressbar.py new file mode 100644 index 000000000..995502408 --- /dev/null +++ b/tests/typing/typing_progressbar.py @@ -0,0 +1,18 @@ +from typing_extensions import assert_type + +from click import progressbar +from click._termui_impl import ProgressBar + + +def test_length_is_int() -> None: + with progressbar(length=5) as bar: + assert_type(bar, ProgressBar[int]) + for i in bar: + assert_type(i, int) + + +def test_generic_on_iterable() -> None: + with progressbar(("hello", "world")) as bar: + assert_type(bar, ProgressBar[str]) + for s in bar: + assert_type(s, str)