Skip to content

Make progress.py portable and stop redrawing per character - #15

Merged
ESultanik merged 1 commit into
masterfrom
progress-portability
Aug 7, 2026
Merged

Make progress.py portable and stop redrawing per character#15
ESultanik merged 1 commit into
masterfrom
progress-portability

Conversation

@ESultanik

Copy link
Copy Markdown
Owner

Stacked on #14.

progress.py imported fcntl and termios at module scope for a hand-rolled 20-line terminal-size probe. Both are Unix-only, and __main__ imports progress unconditionally, so the whole package was unimportable on Windowsimport lenticrypt.__main__ failed outright. shutil.get_terminal_size() does the same job portably, including the COLUMNS fallback, in one line. Both bare except: clauses go with it.

Other fixes

  • ProgressBar.update divided by max_value without guarding zero. The index builder derives its range from the certificate length, which is <= 0 for a short certificate and a long nibble-gram, so ZeroDivisionError was reachable.
  • ProgressBarCallback bound max_value from its first call and never updated it, so every phase after the first was drawn against the first phase's scale. update now takes the maximum per call.
  • Rendering issued one stream.write() per column — 200 write calls per redraw on a 200-column terminal. The bar is built as one string and written once. Redraws are also skipped when neither the rounded percentage nor the status text would change.

Adds a StatusCallback Protocol so the reporter contract is explicit and checkable, and makes ProgressBarCallback a context manager, replacing the create/try/finally-clear dance repeated three times in main.

CI

windows-latest joins the matrix in this commit, so the leg demonstrates the import fix rather than being added on faith.

Verification

First tests for this module: ten cases covering zero and negative maxima, clamping, rescaling across phases, width, redraw suppression, the Protocol, the context manager, and importability with fcntl/termios blocked. The zero-max xfail marker is removed since it now passes.

🤖 Generated with Claude Code

https://claude.ai/code/session_01367hFob9sd4xpDmVT4uoFy

`progress.py` imported `fcntl` and `termios` at module scope for a hand-rolled
20-line terminal-size probe. Both are Unix-only, and `__main__` imports
`progress` unconditionally, so the whole package was unimportable on Windows --
`import lenticrypt.__main__` failed outright. `shutil.get_terminal_size()` does
the same job portably, including the COLUMNS fallback, in one line. Both bare
`except:` clauses go with it.

Other fixes:

  * `ProgressBar.update` divided by `max_value` without guarding zero. The index
    builder derives its range from the certificate length, which is <= 0 for a
    short certificate and a long nibble-gram, so ZeroDivisionError was reachable.
  * `ProgressBarCallback` bound `max_value` from its first call and never updated
    it, so every phase after the first was drawn against the first phase's scale.
    `update` now takes the maximum per call.
  * Rendering issued one `stream.write()` per column -- 200 write calls per
    redraw on a 200-column terminal. The bar is built as one string and written
    once. Redraws are also skipped when neither the rounded percentage nor the
    status text would change.

Adds a `StatusCallback` Protocol so the reporter contract is explicit and
checkable, and makes `ProgressBarCallback` a context manager, which replaces the
create/try/finally-clear dance repeated three times in `main`.

windows-latest joins the CI matrix in the same commit, so the leg demonstrates
the import fix rather than being added on faith.

First tests for this module: ten cases covering the zero and negative maxima,
clamping, rescaling across phases, width, redraw suppression, the Protocol, the
context manager, and importability with `fcntl`/`termios` blocked. The zero-max
xfail marker is removed since it now passes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01367hFob9sd4xpDmVT4uoFy
@ESultanik
ESultanik force-pushed the progress-portability branch from 36f70db to 794125c Compare August 7, 2026 19:25
Base automatically changed from fix-gzip-filename-leak to master August 7, 2026 19:29
@ESultanik
ESultanik merged commit bb0d934 into master Aug 7, 2026
11 checks passed
@ESultanik
ESultanik deleted the progress-portability branch August 7, 2026 19:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant