barflow 0.2.2__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {barflow-0.2.2/src/barflow.egg-info → barflow-0.3.0}/PKG-INFO +7 -4
- {barflow-0.2.2 → barflow-0.3.0}/README.md +2 -2
- {barflow-0.2.2 → barflow-0.3.0}/pyproject.toml +13 -2
- {barflow-0.2.2 → barflow-0.3.0}/src/barflow/__init__.py +1 -1
- {barflow-0.2.2 → barflow-0.3.0}/src/barflow/_core.cpp +85 -5
- {barflow-0.2.2 → barflow-0.3.0/src/barflow.egg-info}/PKG-INFO +7 -4
- {barflow-0.2.2 → barflow-0.3.0}/LICENSE +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/MANIFEST.in +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/benchmarks/bench.py +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/benchmarks/bench_first_frame.py +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/benchmarks/bench_import_to_iter.py +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/benchmarks/bench_memory.py +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/benchmarks/bench_metadata_churn.py +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/benchmarks/bench_multibar.py +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/benchmarks/bench_raw.md +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/benchmarks/bench_tail_latency.py +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/benchmarks/results.md +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/docs/DESIGN.md +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/docs/FEATURE_REQUESTS.md +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/docs/PUBLISHING.md +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/examples/async_stream.py +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/examples/gallery.py +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/examples/parallel_presets.py +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/examples/presets_gallery.py +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/examples/showcase.py +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/examples/themes_showcase.py +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/setup.cfg +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/setup.py +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/src/barflow/_progress.py +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/src/barflow/aio.py +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/src/barflow/bar_styles.py +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/src/barflow/columns.py +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/src/barflow/hooks.py +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/src/barflow/spinners.py +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/src/barflow/style.py +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/src/barflow/themes.py +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/src/barflow.egg-info/SOURCES.txt +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/src/barflow.egg-info/dependency_links.txt +0 -0
- {barflow-0.2.2 → barflow-0.3.0}/src/barflow.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: barflow
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Fast Python progress bars with a C++ core. Windows-first.
|
|
5
5
|
Author: NevermindNilas
|
|
6
6
|
License-Expression: MIT
|
|
@@ -20,13 +20,16 @@ Classifier: Programming Language :: C++
|
|
|
20
20
|
Classifier: Programming Language :: Python
|
|
21
21
|
Classifier: Programming Language :: Python :: 3
|
|
22
22
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
26
|
Classifier: Programming Language :: Python :: 3.13
|
|
24
27
|
Classifier: Programming Language :: Python :: 3.14
|
|
25
28
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
26
29
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
27
30
|
Classifier: Topic :: Terminals
|
|
28
31
|
Classifier: Topic :: Utilities
|
|
29
|
-
Requires-Python: >=3.
|
|
32
|
+
Requires-Python: >=3.10
|
|
30
33
|
Description-Content-Type: text/markdown
|
|
31
34
|
License-File: LICENSE
|
|
32
35
|
Dynamic: license-file
|
|
@@ -302,7 +305,7 @@ pip install barflow
|
|
|
302
305
|
```
|
|
303
306
|
|
|
304
307
|
Wheels are published for Windows (AMD64), Linux (x86_64, aarch64), and
|
|
305
|
-
macOS (x86_64, arm64) for CPython 3.
|
|
308
|
+
macOS (x86_64, arm64) for CPython 3.10 through 3.14, including the
|
|
306
309
|
free-threaded `cp313t` / `cp314t` builds.
|
|
307
310
|
|
|
308
311
|
## Features
|
|
@@ -418,7 +421,7 @@ and the benchmarks methodology.
|
|
|
418
421
|
## Build from source
|
|
419
422
|
|
|
420
423
|
Requires Visual Studio 2022+ (Windows) or GCC/Clang + Python headers
|
|
421
|
-
(POSIX) and Python ≥ 3.
|
|
424
|
+
(POSIX) and Python ≥ 3.10.
|
|
422
425
|
|
|
423
426
|
```
|
|
424
427
|
# Windows
|
|
@@ -269,7 +269,7 @@ pip install barflow
|
|
|
269
269
|
```
|
|
270
270
|
|
|
271
271
|
Wheels are published for Windows (AMD64), Linux (x86_64, aarch64), and
|
|
272
|
-
macOS (x86_64, arm64) for CPython 3.
|
|
272
|
+
macOS (x86_64, arm64) for CPython 3.10 through 3.14, including the
|
|
273
273
|
free-threaded `cp313t` / `cp314t` builds.
|
|
274
274
|
|
|
275
275
|
## Features
|
|
@@ -385,7 +385,7 @@ and the benchmarks methodology.
|
|
|
385
385
|
## Build from source
|
|
386
386
|
|
|
387
387
|
Requires Visual Studio 2022+ (Windows) or GCC/Clang + Python headers
|
|
388
|
-
(POSIX) and Python ≥ 3.
|
|
388
|
+
(POSIX) and Python ≥ 3.10.
|
|
389
389
|
|
|
390
390
|
```
|
|
391
391
|
# Windows
|
|
@@ -4,10 +4,10 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "barflow"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3.0"
|
|
8
8
|
description = "Fast Python progress bars with a C++ core. Windows-first."
|
|
9
9
|
readme = "README.md"
|
|
10
|
-
requires-python = ">=3.
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
11
|
license = "MIT"
|
|
12
12
|
license-files = ["LICENSE"]
|
|
13
13
|
authors = [
|
|
@@ -28,6 +28,9 @@ classifiers = [
|
|
|
28
28
|
"Programming Language :: Python",
|
|
29
29
|
"Programming Language :: Python :: 3",
|
|
30
30
|
"Programming Language :: Python :: 3 :: Only",
|
|
31
|
+
"Programming Language :: Python :: 3.10",
|
|
32
|
+
"Programming Language :: Python :: 3.11",
|
|
33
|
+
"Programming Language :: Python :: 3.12",
|
|
31
34
|
"Programming Language :: Python :: 3.13",
|
|
32
35
|
"Programming Language :: Python :: 3.14",
|
|
33
36
|
"Programming Language :: Python :: Implementation :: CPython",
|
|
@@ -53,3 +56,11 @@ where = ["src"]
|
|
|
53
56
|
build-verbosity = 1
|
|
54
57
|
test-command = 'python -c "import barflow; list(barflow.track(range(1000)))"'
|
|
55
58
|
skip = ["*-musllinux_i686", "*-win32"]
|
|
59
|
+
|
|
60
|
+
[tool.cibuildwheel.macos]
|
|
61
|
+
# The C++17 core uses aligned new/delete, which Clang only emits for a
|
|
62
|
+
# deployment target of macOS 10.13+. CPython 3.12+ already defaults the
|
|
63
|
+
# x86_64 target high enough, but 3.10/3.11 default to 10.9 and fail to
|
|
64
|
+
# compile. Pin the floor to 10.13 for every macOS build (arm64 is always
|
|
65
|
+
# 11.0+ regardless, so this only lifts the x86_64 leg).
|
|
66
|
+
environment = { MACOSX_DEPLOYMENT_TARGET = "10.13" }
|
|
@@ -244,6 +244,14 @@ struct ProgressState {
|
|
|
244
244
|
std::thread render_thread;
|
|
245
245
|
std::once_flag close_once;
|
|
246
246
|
|
|
247
|
+
// pause()/resume() let an external writer (e.g. an output redirector)
|
|
248
|
+
// suspend the render thread, emit lines on the cleared bar area, and
|
|
249
|
+
// then have the bar repainted below. `paused` is checked by the render
|
|
250
|
+
// loop on every wakeup; `force_render` makes the first frame after
|
|
251
|
+
// resume repaint even if no counter moved while paused.
|
|
252
|
+
std::atomic<bool> paused{false};
|
|
253
|
+
bool force_render{false}; // guarded by render_mtx
|
|
254
|
+
|
|
247
255
|
double min_interval{0.05};
|
|
248
256
|
bool disable{false};
|
|
249
257
|
bool vt_enabled{false};
|
|
@@ -1340,11 +1348,17 @@ void render_loop(ProgressState* st) {
|
|
|
1340
1348
|
st->render_cv.wait_for(lock, interval);
|
|
1341
1349
|
if (!st->running.load(std::memory_order_acquire)) break;
|
|
1342
1350
|
|
|
1351
|
+
// Suspended for external writing: do not touch the terminal until
|
|
1352
|
+
// resume() clears the flag. pause() already erased the bar area, so
|
|
1353
|
+
// the external writer owns the screen meanwhile.
|
|
1354
|
+
if (st->paused.load(std::memory_order_acquire)) continue;
|
|
1355
|
+
|
|
1343
1356
|
// Render unconditionally if there is a spinner (it animates even
|
|
1344
|
-
// with no producer progress)
|
|
1345
|
-
// The spinner flag is cached at
|
|
1346
|
-
// the column vector on every
|
|
1347
|
-
|
|
1357
|
+
// with no producer progress) or if a resume forced a repaint;
|
|
1358
|
+
// otherwise only if counters moved. The spinner flag is cached at
|
|
1359
|
+
// column setup so we don't re-scan the column vector on every
|
|
1360
|
+
// wakeup (every `min_interval`).
|
|
1361
|
+
bool any_dirty = st->has_spinner_col || st->force_render;
|
|
1348
1362
|
if (!any_dirty) {
|
|
1349
1363
|
for (auto& t : st->tasks) {
|
|
1350
1364
|
if (t->completed.load(std::memory_order_acquire) != t->last_snapshot) {
|
|
@@ -1353,7 +1367,10 @@ void render_loop(ProgressState* st) {
|
|
|
1353
1367
|
}
|
|
1354
1368
|
}
|
|
1355
1369
|
}
|
|
1356
|
-
if (any_dirty)
|
|
1370
|
+
if (any_dirty) {
|
|
1371
|
+
render_frame(st);
|
|
1372
|
+
st->force_render = false;
|
|
1373
|
+
}
|
|
1357
1374
|
}
|
|
1358
1375
|
// Final frame, still under the lock.
|
|
1359
1376
|
render_frame(st);
|
|
@@ -1948,6 +1965,65 @@ PyObject* Progress_write_above(PyProgress* self, PyObject* text_obj) {
|
|
|
1948
1965
|
Py_RETURN_NONE;
|
|
1949
1966
|
}
|
|
1950
1967
|
|
|
1968
|
+
// pause() — suspend the render thread and erase the bar area, leaving the
|
|
1969
|
+
// cursor at column 0 of the cleared region so an external writer can emit
|
|
1970
|
+
// lines there without the bar repainting on top. Mirrors the walk-back +
|
|
1971
|
+
// erase that write_above performs. Idempotent and safe to call when the bar
|
|
1972
|
+
// is disabled or closed (no-op). Pairs with resume().
|
|
1973
|
+
PyObject* Progress_pause(PyProgress* self, PyObject* /*args*/) {
|
|
1974
|
+
auto* st = self->state;
|
|
1975
|
+
if (st->disable || st->closed) Py_RETURN_NONE;
|
|
1976
|
+
{
|
|
1977
|
+
std::lock_guard<std::mutex> lg(st->render_mtx);
|
|
1978
|
+
// Acquiring render_mtx guarantees no frame is mid-flight: the render
|
|
1979
|
+
// loop only holds the lock outside its cv wait, so once we hold it
|
|
1980
|
+
// the last frame is fully written.
|
|
1981
|
+
st->paused.store(true, std::memory_order_release);
|
|
1982
|
+
|
|
1983
|
+
if (st->vt_enabled) {
|
|
1984
|
+
std::string& buf = st->scratch;
|
|
1985
|
+
buf.clear();
|
|
1986
|
+
int term_w = query_terminal_width(st);
|
|
1987
|
+
if (!st->last_task_cells.empty()) {
|
|
1988
|
+
int total_rows = 0;
|
|
1989
|
+
for (int c : st->last_task_cells) {
|
|
1990
|
+
int r = (term_w > 0) ? ((c + term_w - 1) / term_w) : 1;
|
|
1991
|
+
if (r < 1) r = 1;
|
|
1992
|
+
total_rows += r;
|
|
1993
|
+
}
|
|
1994
|
+
if (total_rows > 0) {
|
|
1995
|
+
buf.append("\x1b[", 2);
|
|
1996
|
+
char tmp[20];
|
|
1997
|
+
size_t n = u64_to_chars(tmp, static_cast<uint64_t>(total_rows));
|
|
1998
|
+
buf.append(tmp, n);
|
|
1999
|
+
buf.push_back('A');
|
|
2000
|
+
}
|
|
2001
|
+
}
|
|
2002
|
+
buf.push_back('\r');
|
|
2003
|
+
buf.append("\x1b[J", 3); // erase from cursor to end of screen
|
|
2004
|
+
write_bytes(st, buf.data(), buf.size());
|
|
2005
|
+
st->last_rendered_lines = 0;
|
|
2006
|
+
st->last_task_cells.clear();
|
|
2007
|
+
st->delta_valid = false; // resume repaints from scratch
|
|
2008
|
+
}
|
|
2009
|
+
}
|
|
2010
|
+
Py_RETURN_NONE;
|
|
2011
|
+
}
|
|
2012
|
+
|
|
2013
|
+
// resume() — undo pause(): clear the suspend flag and force the next render
|
|
2014
|
+
// loop wakeup to repaint the bar below whatever the external writer emitted.
|
|
2015
|
+
PyObject* Progress_resume(PyProgress* self, PyObject* /*args*/) {
|
|
2016
|
+
auto* st = self->state;
|
|
2017
|
+
if (st->disable || st->closed) Py_RETURN_NONE;
|
|
2018
|
+
{
|
|
2019
|
+
std::lock_guard<std::mutex> lg(st->render_mtx);
|
|
2020
|
+
st->paused.store(false, std::memory_order_release);
|
|
2021
|
+
st->force_render = true;
|
|
2022
|
+
}
|
|
2023
|
+
st->render_cv.notify_one();
|
|
2024
|
+
Py_RETURN_NONE;
|
|
2025
|
+
}
|
|
2026
|
+
|
|
1951
2027
|
PyObject* Progress_get_completed(PyProgress* self, void* /*closure*/) {
|
|
1952
2028
|
Task* t = self->state->task0.load(std::memory_order_acquire);
|
|
1953
2029
|
uint64_t v = t ? t->completed.load(std::memory_order_relaxed) : 0;
|
|
@@ -1989,6 +2065,10 @@ PyMethodDef Progress_methods[] = {
|
|
|
1989
2065
|
"Force an immediate render frame."},
|
|
1990
2066
|
{"write_above",reinterpret_cast<PyCFunction>(Progress_write_above),
|
|
1991
2067
|
METH_O, "Emit text above the bar area without tearing."},
|
|
2068
|
+
{"pause", reinterpret_cast<PyCFunction>(Progress_pause), METH_NOARGS,
|
|
2069
|
+
"Suspend the render thread and clear the bar so external writes are clean."},
|
|
2070
|
+
{"resume", reinterpret_cast<PyCFunction>(Progress_resume), METH_NOARGS,
|
|
2071
|
+
"Resume rendering after pause(), repainting the bar."},
|
|
1992
2072
|
{nullptr, nullptr, 0, nullptr}
|
|
1993
2073
|
};
|
|
1994
2074
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: barflow
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Fast Python progress bars with a C++ core. Windows-first.
|
|
5
5
|
Author: NevermindNilas
|
|
6
6
|
License-Expression: MIT
|
|
@@ -20,13 +20,16 @@ Classifier: Programming Language :: C++
|
|
|
20
20
|
Classifier: Programming Language :: Python
|
|
21
21
|
Classifier: Programming Language :: Python :: 3
|
|
22
22
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
26
|
Classifier: Programming Language :: Python :: 3.13
|
|
24
27
|
Classifier: Programming Language :: Python :: 3.14
|
|
25
28
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
26
29
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
27
30
|
Classifier: Topic :: Terminals
|
|
28
31
|
Classifier: Topic :: Utilities
|
|
29
|
-
Requires-Python: >=3.
|
|
32
|
+
Requires-Python: >=3.10
|
|
30
33
|
Description-Content-Type: text/markdown
|
|
31
34
|
License-File: LICENSE
|
|
32
35
|
Dynamic: license-file
|
|
@@ -302,7 +305,7 @@ pip install barflow
|
|
|
302
305
|
```
|
|
303
306
|
|
|
304
307
|
Wheels are published for Windows (AMD64), Linux (x86_64, aarch64), and
|
|
305
|
-
macOS (x86_64, arm64) for CPython 3.
|
|
308
|
+
macOS (x86_64, arm64) for CPython 3.10 through 3.14, including the
|
|
306
309
|
free-threaded `cp313t` / `cp314t` builds.
|
|
307
310
|
|
|
308
311
|
## Features
|
|
@@ -418,7 +421,7 @@ and the benchmarks methodology.
|
|
|
418
421
|
## Build from source
|
|
419
422
|
|
|
420
423
|
Requires Visual Studio 2022+ (Windows) or GCC/Clang + Python headers
|
|
421
|
-
(POSIX) and Python ≥ 3.
|
|
424
|
+
(POSIX) and Python ≥ 3.10.
|
|
422
425
|
|
|
423
426
|
```
|
|
424
427
|
# Windows
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|