Skip to content

Commit 877a41e

Browse files
committed
Merge develop into maint/20260525120751
# Conflicts: # progressbar/utils.py # tests/test_utils.py
2 parents 3f0b275 + dfd0b66 commit 877a41e

79 files changed

Lines changed: 8093 additions & 1526 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

ISSUE_TEMPLATE renamed to .github/ISSUE_TEMPLATE.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,3 @@ If applicable, code to reproduce the issue and/or the stacktrace of the issue
1212
- Python distribution/environment: CPython/Anaconda/IPython/IDLE
1313
- Operating System: Windows 10, Ubuntu Linux, etc.
1414
- Package version: `import progressbar; print(progressbar.__version__)`
15-

.github/workflows/codeql.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,23 @@ jobs:
2020
strategy:
2121
fail-fast: false
2222
matrix:
23-
language: [ python, javascript ]
23+
language: [ python ]
2424

2525
steps:
2626
- name: Checkout
27-
uses: actions/checkout@v3
27+
uses: actions/checkout@v6
2828

2929
- name: Initialize CodeQL
30-
uses: github/codeql-action/init@v2
30+
uses: github/codeql-action/init@v3
3131
with:
3232
languages: ${{ matrix.language }}
3333
queries: +security-and-quality
3434

3535
- name: Autobuild
36-
uses: github/codeql-action/autobuild@v2
37-
if: ${{ matrix.language == 'python' || matrix.language == 'javascript' }}
36+
uses: github/codeql-action/autobuild@v3
37+
if: ${{ matrix.language == 'python' }}
3838

3939
- name: Perform CodeQL Analysis
40-
uses: github/codeql-action/analyze@v2
40+
uses: github/codeql-action/analyze@v3
4141
with:
4242
category: "/language:${{ matrix.language }}"

.github/workflows/main.yml

Lines changed: 93 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,107 @@ name: tox
22

33
on:
44
push:
5+
branches: [develop]
56
pull_request:
67
workflow_dispatch:
78

9+
concurrency:
10+
group: "${{ github.workflow }}-${{ github.ref }}"
11+
cancel-in-progress: true
12+
13+
permissions:
14+
contents: read
15+
816
jobs:
17+
perf-budget:
18+
name: Performance budget
19+
runs-on: ubuntu-latest
20+
timeout-minutes: 10
21+
steps:
22+
- uses: actions/checkout@v6
23+
- name: Set up Python 3.13
24+
uses: actions/setup-python@v6
25+
with:
26+
python-version: '3.13'
27+
- name: Install dependencies
28+
run: |
29+
python -m pip install --upgrade pip
30+
python -m pip install -r tests/requirements.txt
31+
python -m pip install -e .
32+
- name: Performance budget
33+
run: python -m pytest tests/test_perf_budget.py -v --no-cov
34+
935
build:
36+
name: tox (${{ matrix.tox-env }})
1037
runs-on: ubuntu-latest
1138
timeout-minutes: 10
1239
strategy:
40+
fail-fast: false
1341
matrix:
14-
python-version: ['3.9', '3.10', '3.11', '3.12']
42+
include:
43+
- python-version: '3.10'
44+
tox-env: py310
45+
- python-version: '3.11'
46+
tox-env: py311
47+
- python-version: '3.12'
48+
tox-env: py312
49+
- python-version: '3.13'
50+
tox-env: py313
51+
- python-version: '3.14'
52+
tox-env: py314
53+
# Python 3.15 is a pre-release and currently unsupported by
54+
# typing_extensions (no released version survives
55+
# `from typing_extensions import *` on 3.15 because
56+
# no_type_check_decorator is still listed in __all__ after its
57+
# removal from typing), which breaks the python_utils import.
58+
# Failures are advisory until upstream catches up.
59+
- python-version: '3.15-dev'
60+
tox-env: py315
61+
experimental: true
62+
- python-version: '3.14'
63+
tox-env: docs
64+
- python-version: '3.14'
65+
tox-env: ruff
66+
- python-version: '3.14'
67+
tox-env: codespell
68+
69+
steps:
70+
- uses: actions/checkout@v6
71+
- name: Set up Python ${{ matrix.python-version }}
72+
uses: actions/setup-python@v6
73+
with:
74+
python-version: ${{ matrix.python-version }}
75+
allow-prereleases: true
76+
- name: Install dependencies
77+
run: |
78+
python -m pip install --upgrade pip tox
79+
- name: Test with tox
80+
# Step-level continue-on-error keeps the job green for
81+
# experimental (pre-release Python) environments while still
82+
# showing the failing step in the logs
83+
continue-on-error: ${{ matrix.experimental || false }}
84+
run: tox -e ${{ matrix.tox-env }}
1585

86+
windows:
87+
name: tox (windows / py312)
88+
runs-on: windows-latest
89+
timeout-minutes: 10
90+
env:
91+
# Force UTF-8 I/O so unicode-marker tests (e.g. test_unicode) don't
92+
# hit UnicodeEncodeError against the legacy Windows code page under
93+
# pytest's fd-level capture.
94+
PYTHONUTF8: '1'
1695
steps:
17-
- uses: actions/checkout@v3
18-
- name: Set up Python ${{ matrix.python-version }}
19-
uses: actions/setup-python@v4
20-
with:
21-
python-version: ${{ matrix.python-version }}
22-
- name: Install dependencies
23-
run: |
24-
python -m pip install --upgrade pip tox
25-
- name: Test with tox
26-
run: tox
96+
- uses: actions/checkout@v6
97+
- name: Set up Python 3.12
98+
uses: actions/setup-python@v6
99+
with:
100+
python-version: '3.12'
101+
- name: Install dependencies
102+
run: |
103+
python -m pip install --upgrade pip tox
104+
- name: Test with tox
105+
# The 100% coverage gate cannot be met on Windows: POSIX-only
106+
# branches never execute there, so run without the coverage gate
107+
# (`--no-cov` posarg). Linux jobs still enforce full coverage.
108+
run: tox -e py312 -- --no-cov

.github/workflows/stale.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ on:
88
jobs:
99
stale:
1010
runs-on: ubuntu-latest
11+
permissions:
12+
issues: write
13+
pull-requests: write
1114
steps:
1215
- uses: actions/stale@v8
1316
with:
1417
days-before-issue-stale: 30
1518
exempt-issue-labels: in-progress,help-wanted,pinned,security,enhancement
1619
exempt-all-assignees: true
17-

.pre-commit-config.yaml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@
22
# See https://pre-commit.com/hooks.html for more hooks
33
repos:
44
- repo: https://github.com/pre-commit/pre-commit-hooks
5-
rev: v2.4.0
5+
rev: v6.0.0
66
hooks:
7+
- id: end-of-file-fixer
78
- id: trailing-whitespace
89
- id: check-yaml
910
- id: check-added-large-files
1011

11-
- repo: https://gitlab.com/pycqa/flake8
12-
rev: 3.7.9
12+
- repo: https://github.com/astral-sh/ruff-pre-commit
13+
rev: v0.15.20
1314
hooks:
14-
- id: flake8
15+
- id: ruff-check
16+
- id: ruff-format

AGENTS.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<claude-mem-context>
2+
# Memory Context
3+
4+
# [python-progressbar] recent context, 2026-05-11 12:05am GMT+2
5+
6+
Legend: 🎯session 🔴bugfix 🟣feature 🔄refactor ✅change 🔵discovery ⚖️decision 🚨security_alert 🔐security_note
7+
Format: ID TIME TYPE TITLE
8+
Fetch details: get_observations([IDs]) | Search: mem-search skill
9+
10+
Stats: 1 obs (414t read) | 19,980t work | 98% savings
11+
12+
### May 11, 2026
13+
2388 12:04a ✅ CI/tox config updated to test Python 3.10–3.15
14+
15+
Access 20k tokens of past work via get_observations([IDs]) or mem-search skill.
16+
</claude-mem-context>

LICENSE

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,3 @@ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2525
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2626
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
2727
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28-

MANIFEST.in

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
recursive-exclude *.pyc
22
recursive-exclude *.pyo
3-
recursive-exclude *.html
4-
include AUTHORS.rst
53
include CHANGES.rst
64
include CONTRIBUTING.rst
75
include LICENSE
86
include README.rst
97
include examples.py
10-
include requirements.txt
11-
include Makefile
128
include pytest.ini

README.rst

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Text progress bar library for Python.
55
Build status:
66

77
.. image:: https://github.com/WoLpH/python-progressbar/actions/workflows/main.yml/badge.svg
8-
:alt: python-progressbar test status
8+
:alt: python-progressbar test status
99
:target: https://github.com/WoLpH/python-progressbar/actions
1010

1111
Coverage:
@@ -72,6 +72,54 @@ of widgets:
7272
The progressbar module is very easy to use, yet very powerful. It will also
7373
automatically enable features like auto-resizing when the system supports it.
7474

75+
******************************************************************************
76+
Performance
77+
******************************************************************************
78+
79+
The default ``progressbar.progressbar(...)`` is the **fastest** progress bar
80+
available -- on iteration overhead, per-update render cost, *and* import time.
81+
On the benchmark machine (CPython 3.13, macOS arm64):
82+
83+
============ ==================== ============== ===========
84+
Metric progressbar2 tqdm rich
85+
============ ==================== ============== ===========
86+
Per iter **5 ns** *(fast)* 54 ns 19 ns
87+
Per render **~5 us** *(fast)* 11 us 172 us
88+
Cold import **~1.5 ms** ~22 ms ~47 ms
89+
============ ==================== ============== ===========
90+
91+
How the default stays fast:
92+
93+
- **Iteration** -- an integer "next update" gate keeps the common iteration to
94+
an increment and a compare, entering the (rate-limited) redraw machinery only
95+
a few times per second. ~30 ns/iter in pure Python (already faster than
96+
tqdm); ~5 ns with the optional native iterator
97+
(``pip install progressbar2[fast]``), which counts in a C field.
98+
- **Render** -- the default bar uses a fixed formatter (percentage, count, bar,
99+
elapsed/ETA) built directly each redraw, so it renders in ~5 us/update,
100+
roughly **2x faster than tqdm**, without the per-widget overhead.
101+
- **Import** -- ``import progressbar`` is lazy (PEP 562): widgets, the
102+
terminal/colour tables and multi-bar support load only when used, so a bare
103+
import is ~1.5 ms and pulls in nothing heavy (no ``asyncio``).
104+
105+
The fast path stays close to the classic look but drops the gradient and
106+
per-iteration ``value`` liveness (``value`` is synced at redraw crossings, like
107+
``tqdm.n``). For the full widget set -- gradient ``Bar``, custom widgets,
108+
dynamic variables -- pass ``widgets=[...]`` or ``fast=False`` to
109+
``progressbar()``, or construct ``progressbar.ProgressBar(...)`` directly; that
110+
path is unchanged (and intentionally richer, so a touch slower). Set
111+
``PROGRESSBAR_DISABLE_FASTPATH=1`` to force the classic path everywhere.
112+
113+
The benchmark is fully reproducible and pits ``progressbar2`` against ``tqdm``,
114+
``rich``, ``alive-progress`` and ``click`` across iteration overhead, forced
115+
redraw cost, and import time -- all rendered to a real pseudo-terminal so the
116+
comparison is apples-to-apples::
117+
118+
python benchmarks/bench.py && python benchmarks/report.py
119+
120+
.. image:: https://raw.githubusercontent.com/WoLpH/python-progressbar/master/benchmarks/chart.png
121+
:alt: progressbar2 vs common Python progress-bar libraries
122+
75123
******************************************************************************
76124
Known issues
77125
******************************************************************************

appveyor.yml

Lines changed: 0 additions & 41 deletions
This file was deleted.

0 commit comments

Comments
 (0)