progress-table 3.0.0__py3-none-any.whl

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.
@@ -0,0 +1,567 @@
1
+ # Copyright (c) 2022-2025 Szymon Mikler
2
+ # Licensed under the MIT License
3
+
4
+ """Module defining styles for progress bars and tables.
5
+
6
+ Also includes functions to interpret style descriptions and converting them into style objects.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from progress_table.common import ALL_COLOR_NAME, ColorFormat, maybe_convert_to_colorama
12
+
13
+
14
+ def _contains_word(short: str, long: str) -> bool:
15
+ return any(short == word.strip(" ") for word in long.split(" "))
16
+
17
+
18
+ def _parse_colors_from_description(description: str) -> tuple[str, str, str]:
19
+ color = ""
20
+ color_empty = ""
21
+ for word in description.split():
22
+ for color_name in ALL_COLOR_NAME:
23
+ if color_name.lower() == word.lower():
24
+ if not color:
25
+ color = color_name
26
+ else:
27
+ color_empty = color_name
28
+ description = description.replace(word, "")
29
+ return color, color_empty, description
30
+
31
+
32
+ class UnknownStyleError(ValueError):
33
+ """Raised when style description is not recognized."""
34
+
35
+ pass
36
+
37
+
38
+ def parse_pbar_style(description: str | PbarStyleBase) -> PbarStyleBase:
39
+ """Parse progress bar style description and return a style object.
40
+
41
+ Example:
42
+ >>> parse_pbar_style("square alt clean")
43
+
44
+ """
45
+ if isinstance(description, str):
46
+ for obj in available_pbar_styles():
47
+ if _contains_word(obj.name, description):
48
+ description = description.replace(obj.name, "")
49
+ color, color_empty, description = _parse_colors_from_description(description)
50
+ is_alt = "alt" in description
51
+ is_clean = "clean" in description
52
+ description = description.replace("alt", "").replace("clean", "").strip(" ")
53
+ if description.strip(" "):
54
+ msg = f"Name '{description}' is not recognized as a part of progress bar style"
55
+ raise UnknownStyleError(msg)
56
+
57
+ return obj(alt=is_alt, clean=is_clean, color=color, color_empty=color_empty)
58
+
59
+ available_names = ", ".join([obj.name for obj in available_pbar_styles()])
60
+ msg = f"Progress bar style '{description}' not found. Available: {available_names}"
61
+ raise UnknownStyleError(msg)
62
+ return description
63
+
64
+
65
+ def parse_table_style(description: str | TableStyleBase) -> TableStyleBase:
66
+ """Parse table style description and return a style object.
67
+
68
+ Example:
69
+ >>> parse_table_style("modern")
70
+
71
+ """
72
+ if isinstance(description, str):
73
+ for obj in available_table_styles():
74
+ if _contains_word(obj.name, description):
75
+ description = description.replace(obj.name, "").strip(" ")
76
+ if description:
77
+ msg = f"Name '{description}' is not recognized as a part of table style"
78
+ raise UnknownStyleError(msg)
79
+
80
+ return obj()
81
+ available_names = ", ".join([obj.name for obj in available_table_styles()])
82
+ msg = f"Table style '{description}' not found. Available: {available_names}"
83
+ raise UnknownStyleError(msg)
84
+ return description
85
+
86
+
87
+ def available_table_styles() -> list[type[TableStyleBase]]:
88
+ """Return a list of available table styles."""
89
+ return [
90
+ obj
91
+ for name, obj in globals().items()
92
+ if isinstance(obj, type) and issubclass(obj, TableStyleBase) and hasattr(obj, "name")
93
+ ]
94
+
95
+
96
+ def available_pbar_styles() -> list[type[PbarStyleBase]]:
97
+ """Return a list of available progress bar styles."""
98
+ return [
99
+ obj
100
+ for name, obj in globals().items()
101
+ if isinstance(obj, type) and issubclass(obj, PbarStyleBase) and hasattr(obj, "name")
102
+ ]
103
+
104
+
105
+ #################
106
+ ## PBAR STYLES ##
107
+ #################
108
+
109
+
110
+ class PbarStyleBase:
111
+ """Base class for progress bar styles."""
112
+
113
+ name: str
114
+ filled: str
115
+ empty: str
116
+ head: str | tuple[str, ...]
117
+ color: str = ""
118
+ color_empty: str = ""
119
+
120
+ def __init__(
121
+ self,
122
+ *,
123
+ alt: bool = False,
124
+ clean: bool = False,
125
+ color: ColorFormat = None,
126
+ color_empty: ColorFormat = None,
127
+ ) -> None:
128
+ """Initialize progress bar style.
129
+
130
+ Args:
131
+ alt: Use the same character for filled and empty parts.
132
+ clean: Use space for empty parts.
133
+ color: Color of the filled part.
134
+ color_empty: Color of the empty part.
135
+
136
+ """
137
+ if color is not None:
138
+ self.color = maybe_convert_to_colorama(color)
139
+ if color_empty is not None:
140
+ self.color_empty = maybe_convert_to_colorama(color_empty)
141
+ if alt:
142
+ self.empty = self.filled
143
+ if clean:
144
+ self.empty = " "
145
+
146
+
147
+ class PbarStyleSquare(PbarStyleBase):
148
+ """Progress bar style.
149
+
150
+ Example:
151
+ >>> ■■■■■◩□□□□□
152
+
153
+ """
154
+
155
+ name = "square"
156
+ filled = "■"
157
+ empty = "□"
158
+ head = "◩"
159
+
160
+
161
+ class PbarStyleFull(PbarStyleBase):
162
+ """Progress bar style.
163
+
164
+ Example:
165
+ >>> █████▌
166
+
167
+ """
168
+
169
+ name = "full"
170
+ filled = "█"
171
+ empty = " "
172
+ head = ("▏", "▎", "▍", "▌", "▋", "▊", "▉")
173
+
174
+
175
+ class PbarStyleDots(PbarStyleBase):
176
+ """Progress bar style.
177
+
178
+ Example:
179
+ >>> ⣿⣿⣿⣿⣿⣦⣀⣀⣀⣀⣀
180
+
181
+ """
182
+
183
+ name = "dots"
184
+ filled = "⣿"
185
+ empty = "⣀"
186
+ head = ("⣄", "⣤", "⣦", "⣶", "⣷")
187
+
188
+
189
+ class PbarStyleShort(PbarStyleBase):
190
+ """Progress bar style.
191
+
192
+ Example:
193
+ >>> ▬▬▬▬▬▬▭▭▭▭▭
194
+
195
+ """
196
+
197
+ name = "short"
198
+ filled = "▬"
199
+ empty = "▭"
200
+ head = "▬"
201
+
202
+
203
+ class PbarStyleCircle(PbarStyleBase):
204
+ """Progress bar style.
205
+
206
+ Example:
207
+ >>> ●●●●●◉○○○○
208
+
209
+ """
210
+
211
+ name = "circle"
212
+ filled = "●"
213
+ empty = "○"
214
+ head = "◉"
215
+
216
+
217
+ class PbarStyleAngled(PbarStyleBase):
218
+ """Progress bar style.
219
+
220
+ Example:
221
+ >>> ▰▰▰▰▰▰▱▱▱▱
222
+
223
+ """
224
+
225
+ name = "angled"
226
+ filled = "▰"
227
+ empty = "▱"
228
+ head = "▰"
229
+
230
+
231
+ class PbarStyleRich(PbarStyleBase):
232
+ """Progress bar style.
233
+
234
+ Example:
235
+ >>> ━━━━━━━━
236
+
237
+ """
238
+
239
+ name = "rich"
240
+ filled = "━"
241
+ empty = " "
242
+ head = "━"
243
+
244
+ def __init__(self, *args, **kwds) -> None:
245
+ """Similar to the default progress bar from rich."""
246
+ super().__init__(*args, **kwds)
247
+ if not self.color and not self.color_empty:
248
+ self.color = maybe_convert_to_colorama("red")
249
+ self.color_empty = maybe_convert_to_colorama("black")
250
+ self.empty = self.filled
251
+
252
+
253
+ class PbarStyleCdots(PbarStyleBase):
254
+ """Progress bar style.
255
+
256
+ Example:
257
+ >>> ꞏꞏꞏꞏꞏꞏꞏꞏ>
258
+
259
+ """
260
+
261
+ name = "cdots"
262
+ filled = "ꞏ"
263
+ empty = " "
264
+ head = ">"
265
+
266
+
267
+ class PbarStyleDash(PbarStyleBase):
268
+ """Progress bar style.
269
+
270
+ Example:
271
+ >>> ----->
272
+
273
+ """
274
+
275
+ name = "dash"
276
+ filled = "-"
277
+ empty = " "
278
+ head = ">"
279
+
280
+
281
+ class PbarStyleUnder(PbarStyleBase):
282
+ """Progress bar style.
283
+
284
+ Example:
285
+ >>> ________
286
+
287
+ """
288
+
289
+ name = "under"
290
+ filled = "_"
291
+ empty = " "
292
+ head = "_"
293
+
294
+
295
+ class PbarStyleDoubleDash(PbarStyleBase):
296
+ """Progress bar style.
297
+
298
+ Example:
299
+ >>> ========>
300
+
301
+ """
302
+
303
+ name = "doubledash"
304
+ filled = "="
305
+ empty = " "
306
+ head = ">"
307
+
308
+
309
+ class PbarStyleNone(PbarStyleBase):
310
+ """Progress bar style.
311
+
312
+ Example:
313
+ >>>
314
+
315
+ """
316
+
317
+ name = "hidden"
318
+ filled = " "
319
+ empty = " "
320
+ head = " "
321
+
322
+
323
+ ##################
324
+ ## TABLE STYLES ##
325
+ ##################
326
+
327
+
328
+ class TableStyleBase:
329
+ """Base class for table styles."""
330
+
331
+ name: str
332
+ cell_overflow: str
333
+ horizontal: str
334
+ vertical: str
335
+ all: str
336
+ up_left: str
337
+ up_right: str
338
+ down_left: str
339
+ down_right: str
340
+ no_left: str
341
+ no_right: str
342
+ no_up: str
343
+ no_down: str
344
+
345
+
346
+ class TableStyleModern(TableStyleBase):
347
+ """Table style.
348
+
349
+ Example:
350
+ >>> ┌─────────┬─────────┐
351
+ >>> │ H1 │ H2 │
352
+ >>> ├─────────┼─────────┤
353
+ >>> │ V1 │ V2 │
354
+ >>> │ V3 │ V4 │
355
+ >>> └─────────┴─────────┘
356
+
357
+ """
358
+
359
+ name = "modern"
360
+ cell_overflow = "…"
361
+ horizontal = "─"
362
+ vertical = "│"
363
+ all = "┼"
364
+ up_left = "┘"
365
+ up_right = "└"
366
+ down_left = "┐"
367
+ down_right = "┌"
368
+ no_left = "├"
369
+ no_right = "┤"
370
+ no_up = "┬"
371
+ no_down = "┴"
372
+
373
+
374
+ class TableStyleUnicodeBare(TableStyleBase):
375
+ """Table style.
376
+
377
+ Example:
378
+ >>> ────────── ──────────
379
+ >>> H1 H2
380
+ >>> ────────── ──────────
381
+ >>> V1 V2
382
+ >>> V3 V4
383
+ >>> ────────── ──────────
384
+
385
+ """
386
+
387
+ name = "bare"
388
+ cell_overflow = "…"
389
+ horizontal = "─"
390
+ vertical = " "
391
+ all = "─"
392
+ up_left = "─"
393
+ up_right = "─"
394
+ down_left = "─"
395
+ down_right = "─"
396
+ no_left = "─"
397
+ no_right = "─"
398
+ no_up = "─"
399
+ no_down = "─"
400
+
401
+
402
+ class TableStyleUnicodeRound(TableStyleBase):
403
+ """Table style.
404
+
405
+ Example:
406
+ >>> ╭─────────┬─────────╮
407
+ >>> │ H1 │ H2 │
408
+ >>> ├─────────┼─────────┤
409
+ >>> │ V1 │ V2 │
410
+ >>> │ V3 │ V4 │
411
+ >>> ╰─────────┴─────────╯
412
+
413
+ """
414
+
415
+ name = "round"
416
+ cell_overflow = "…"
417
+ horizontal = "─"
418
+ vertical = "│"
419
+ all = "┼"
420
+ up_left = "╯"
421
+ up_right = "╰"
422
+ down_left = "╮"
423
+ down_right = "╭"
424
+ no_left = "├"
425
+ no_right = "┤"
426
+ no_up = "┬"
427
+ no_down = "┴"
428
+
429
+
430
+ class TableStyleUnicodeDouble(TableStyleBase):
431
+ """Table style.
432
+
433
+ Example:
434
+ >>> ╔═════════╦═════════╗
435
+ >>> ║ H1 ║ H2 ║
436
+ >>> ╠═════════╬═════════╣
437
+ >>> ║ V1 ║ V2 ║
438
+ >>> ║ V3 ║ V4 ║
439
+ >>> ╚═════════╩═════════╝
440
+
441
+ """
442
+
443
+ name = "double"
444
+ cell_overflow = "…"
445
+ horizontal = "═"
446
+ vertical = "║"
447
+ all = "╬"
448
+ up_left = "╝"
449
+ up_right = "╚"
450
+ down_left = "╗"
451
+ down_right = "╔"
452
+ no_left = "╠"
453
+ no_right = "╣"
454
+ no_up = "╦"
455
+ no_down = "╩"
456
+
457
+
458
+ class TableStyleUnicodeBold(TableStyleBase):
459
+ """Table style.
460
+
461
+ Example:
462
+ >>> ┏━━━━━━━━━┳━━━━━━━━━┓
463
+ >>> ┃ H1 ┃ H2 ┃
464
+ >>> ┣━━━━━━━━━╋━━━━━━━━━┫
465
+ >>> ┃ V1 ┃ V2 ┃
466
+ >>> ┃ V3 ┃ V4 ┃
467
+ >>> ┗━━━━━━━━━┻━━━━━━━━━┛
468
+
469
+ """
470
+
471
+ name = "bold"
472
+ cell_overflow = "…"
473
+ horizontal = "━"
474
+ vertical = "┃"
475
+ all = "╋"
476
+ up_left = "┛"
477
+ up_right = "┗"
478
+ down_left = "┓"
479
+ down_right = "┏"
480
+ no_left = "┣"
481
+ no_right = "┫"
482
+ no_up = "┳"
483
+ no_down = "┻"
484
+
485
+
486
+ class TableStyleAscii(TableStyleBase):
487
+ """Table style.
488
+
489
+ Example:
490
+ >>> +---------+---------+
491
+ >>> | H1 | H2 |
492
+ >>> +---------+---------+
493
+ >>> | V1 | V2 |
494
+ >>> | V3 | V4 |
495
+ >>> +---------+---------+
496
+
497
+ """
498
+
499
+ name = "ascii"
500
+ cell_overflow = "_"
501
+ horizontal = "-"
502
+ vertical = "|"
503
+ all = "+"
504
+ up_left = "+"
505
+ up_right = "+"
506
+ down_left = "+"
507
+ down_right = "+"
508
+ no_left = "+"
509
+ no_right = "+"
510
+ no_up = "+"
511
+ no_down = "+"
512
+
513
+
514
+ class TableStyleAsciiBare(TableStyleBase):
515
+ """Table style.
516
+
517
+ Example:
518
+ >>> --------- ---------
519
+ >>> H1 H2
520
+ >>> --------- ---------
521
+ >>> V1 V2
522
+ >>> V3 V4
523
+ >>> --------- ---------
524
+
525
+ """
526
+
527
+ name = "asciib"
528
+ cell_overflow = "_"
529
+ horizontal = "-"
530
+ vertical = " "
531
+ all = "-"
532
+ up_left = "-"
533
+ up_right = "-"
534
+ down_left = "-"
535
+ down_right = "-"
536
+ no_left = "-"
537
+ no_right = "-"
538
+ no_up = "-"
539
+ no_down = "-"
540
+
541
+
542
+ class TableStyleHidden(TableStyleBase):
543
+ """Table style.
544
+
545
+ Example:
546
+ >>>
547
+ >>> H1 H2
548
+ >>>
549
+ >>> V1 V2
550
+ >>> V3 V4
551
+ >>>
552
+
553
+ """
554
+
555
+ name = "hidden"
556
+ cell_overflow = " "
557
+ horizontal = " "
558
+ vertical = " "
559
+ all = " "
560
+ up_left = " "
561
+ up_right = " "
562
+ down_left = " "
563
+ down_right = " "
564
+ no_left = " "
565
+ no_right = " "
566
+ no_up = " "
567
+ no_down = " "
@@ -0,0 +1,25 @@
1
+ Metadata-Version: 2.4
2
+ Name: progress-table
3
+ Version: 3.0.0
4
+ Summary: Display progress as a pretty table in the command line.
5
+ Project-URL: Home, https://github.com/gahaalt/progress-table.git
6
+ Project-URL: Docs, https://github.com/sjmikler/progress-table/blob/main/docs
7
+ Author-email: Szymon Mikler <sjmikler@gmail.com>
8
+ License: MIT
9
+ License-File: LICENSE.txt
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.7
13
+ Classifier: Programming Language :: Python :: 3.8
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Requires-Python: >=3.7
20
+ Requires-Dist: colorama
21
+ Provides-Extra: dev
22
+ Requires-Dist: black; extra == 'dev'
23
+ Requires-Dist: build; extra == 'dev'
24
+ Requires-Dist: isort; extra == 'dev'
25
+ Requires-Dist: twine; extra == 'dev'
@@ -0,0 +1,8 @@
1
+ progress_table/__init__.py,sha256=AgeBX1BauYj8ol-U1e197RdYSj1zZFuk0lJIrwy3X4c,454
2
+ progress_table/common.py,sha256=NWQCKXMCMwZ2seRjG-Vsz41-CWzAoMlNwXBNwFboOQc,1656
3
+ progress_table/progress_table.py,sha256=fgBcAQWKYSg2nKwLEybyGY2LSpqPE7eJa_M9CrHTpQw,53056
4
+ progress_table/styles.py,sha256=SDWw38vylnV6Lx4wJhjBtTYSr2NF3fmAcAimClvwjsw,12827
5
+ progress_table-3.0.0.dist-info/METADATA,sha256=Dkkpxg55GKDFjjrdyez1hCt9unooVDB0X0OziHctRqc,1021
6
+ progress_table-3.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
7
+ progress_table-3.0.0.dist-info/licenses/LICENSE.txt,sha256=-nWX5QKbedRcllCNBCmI-IMkbdgy7PDnjn-UWzaWn50,1052
8
+ progress_table-3.0.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.27.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,7 @@
1
+ Copyright 2022 Szymon Mikler
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.