progress-table 2.0.0__tar.gz → 2.2.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.
- {progress-table-2.0.0 → progress-table-2.2.0}/PKG-INFO +3 -3
- {progress-table-2.0.0 → progress-table-2.2.0}/README.md +2 -2
- {progress-table-2.0.0 → progress-table-2.2.0}/progress_table/__init__.py +1 -1
- progress-table-2.2.0/progress_table/v1/common.py +47 -0
- {progress-table-2.0.0 → progress-table-2.2.0}/progress_table/v1/progress_table.py +68 -65
- {progress-table-2.0.0 → progress-table-2.2.0}/progress_table/v1/styles.py +99 -41
- {progress-table-2.0.0 → progress-table-2.2.0}/progress_table.egg-info/PKG-INFO +3 -3
- {progress-table-2.0.0 → progress-table-2.2.0}/progress_table.egg-info/SOURCES.txt +1 -0
- {progress-table-2.0.0 → progress-table-2.2.0}/tests/test_examples_automated.py +2 -2
- {progress-table-2.0.0 → progress-table-2.2.0}/LICENSE.txt +0 -0
- {progress-table-2.0.0 → progress-table-2.2.0}/progress_table/v0/__init__.py +0 -0
- {progress-table-2.0.0 → progress-table-2.2.0}/progress_table/v0/progress_table.py +0 -0
- {progress-table-2.0.0 → progress-table-2.2.0}/progress_table/v0/symbols.py +0 -0
- {progress-table-2.0.0 → progress-table-2.2.0}/progress_table/v1/__init__.py +0 -0
- {progress-table-2.0.0 → progress-table-2.2.0}/progress_table.egg-info/PKG-INFO.sync-conflict-20240314-015933-NXTV2IO +0 -0
- {progress-table-2.0.0 → progress-table-2.2.0}/progress_table.egg-info/dependency_links.txt +0 -0
- {progress-table-2.0.0 → progress-table-2.2.0}/progress_table.egg-info/requires.txt +0 -0
- {progress-table-2.0.0 → progress-table-2.2.0}/progress_table.egg-info/top_level.txt +0 -0
- {progress-table-2.0.0 → progress-table-2.2.0}/pyproject.toml +0 -0
- {progress-table-2.0.0 → progress-table-2.2.0}/setup.cfg +0 -0
- {progress-table-2.0.0 → progress-table-2.2.0}/setup.py +0 -0
- {progress-table-2.0.0 → progress-table-2.2.0}/tests/test_docs_automated.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: progress-table
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: Display progress as a pretty table in the command line.
|
|
5
5
|
Home-page: https://github.com/gahaalt/progress-table.git
|
|
6
6
|
Author: Szymon Mikler
|
|
@@ -118,8 +118,8 @@ Progress Table works correctly in most consoles, but there are some exceptions:
|
|
|
118
118
|
* Some consoles like `PyCharm Python Console` or `IDLE` don't support cursor movement.
|
|
119
119
|
You can still use ProgressTable, but with `interactive=1` option. This mode displays only 1 progress bar at once.
|
|
120
120
|
|
|
121
|
-
> By default `interactive=2`. You can change the default `interactive`
|
|
122
|
-
> setting `PTABLE_INTERACTIVE` environment variable, e.g. `PTABLE_INTERACTIVE=1`.
|
|
121
|
+
> By default `interactive=2`. You can change the default `interactive` with an argument when creating the table object
|
|
122
|
+
> or by setting `PTABLE_INTERACTIVE` environment variable, e.g. `PTABLE_INTERACTIVE=1`.
|
|
123
123
|
|
|
124
124
|
## Installation
|
|
125
125
|
|
|
@@ -97,8 +97,8 @@ Progress Table works correctly in most consoles, but there are some exceptions:
|
|
|
97
97
|
* Some consoles like `PyCharm Python Console` or `IDLE` don't support cursor movement.
|
|
98
98
|
You can still use ProgressTable, but with `interactive=1` option. This mode displays only 1 progress bar at once.
|
|
99
99
|
|
|
100
|
-
> By default `interactive=2`. You can change the default `interactive`
|
|
101
|
-
> setting `PTABLE_INTERACTIVE` environment variable, e.g. `PTABLE_INTERACTIVE=1`.
|
|
100
|
+
> By default `interactive=2`. You can change the default `interactive` with an argument when creating the table object
|
|
101
|
+
> or by setting `PTABLE_INTERACTIVE` environment variable, e.g. `PTABLE_INTERACTIVE=1`.
|
|
102
102
|
|
|
103
103
|
## Installation
|
|
104
104
|
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Copyright (c) 2022-2024 Szymon Mikler
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Union
|
|
6
|
+
|
|
7
|
+
from colorama import Back, Fore, Style
|
|
8
|
+
|
|
9
|
+
ALL_COLOR_NAME = [x for x in dir(Fore) if not x.startswith("__")]
|
|
10
|
+
ALL_STYLE_NAME = [x for x in dir(Style) if not x.startswith("__")]
|
|
11
|
+
ALL_COLOR_STYLE_NAME = ALL_COLOR_NAME + ALL_STYLE_NAME
|
|
12
|
+
ALL_COLOR = [getattr(Fore, x) for x in ALL_COLOR_NAME] + [getattr(Back, x) for x in ALL_COLOR_NAME]
|
|
13
|
+
ALL_STYLE = [getattr(Style, x) for x in ALL_STYLE_NAME]
|
|
14
|
+
ALL_COLOR_STYLE = ALL_COLOR + ALL_STYLE
|
|
15
|
+
|
|
16
|
+
COLORAMA_TRANSLATE = {
|
|
17
|
+
"bold": "bright",
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
NoneType = type(None)
|
|
21
|
+
ColorFormat = Union[str, tuple, list, NoneType]
|
|
22
|
+
ColorFormatTuple = (str, tuple, list, NoneType)
|
|
23
|
+
|
|
24
|
+
CURSOR_UP = "\033[A"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def maybe_convert_to_colorama_str(color: str) -> str:
|
|
28
|
+
# Translation layer to fix unintuitive colorama names
|
|
29
|
+
color = COLORAMA_TRANSLATE.get(color.lower(), color)
|
|
30
|
+
|
|
31
|
+
if isinstance(color, str):
|
|
32
|
+
if hasattr(Fore, color.upper()):
|
|
33
|
+
return getattr(Fore, color.upper())
|
|
34
|
+
if hasattr(Style, color.upper()):
|
|
35
|
+
return getattr(Style, color.upper())
|
|
36
|
+
|
|
37
|
+
assert color in ALL_COLOR_STYLE, f"Color {color!r} incorrect! Available: {' '.join(ALL_COLOR_STYLE_NAME)}"
|
|
38
|
+
return color
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def maybe_convert_to_colorama(color: ColorFormat) -> str:
|
|
42
|
+
if color is None or color == "":
|
|
43
|
+
return ""
|
|
44
|
+
if isinstance(color, str):
|
|
45
|
+
color = color.split(" ")
|
|
46
|
+
results = [maybe_convert_to_colorama_str(x) for x in color]
|
|
47
|
+
return "".join(results)
|
|
@@ -12,30 +12,13 @@ import sys
|
|
|
12
12
|
import time
|
|
13
13
|
from dataclasses import dataclass
|
|
14
14
|
from threading import Thread
|
|
15
|
-
from typing import Any, Callable, Iterable, Sized, Type
|
|
15
|
+
from typing import Any, Callable, Iterable, Sized, Type
|
|
16
16
|
|
|
17
|
-
from colorama import
|
|
17
|
+
from colorama import Style
|
|
18
18
|
|
|
19
|
-
from . import styles
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
ALL_STYLE_NAME = [x for x in dir(Style) if not x.startswith("__")]
|
|
23
|
-
ALL_COLOR_STYLE_NAME = ALL_COLOR_NAME + ALL_STYLE_NAME
|
|
24
|
-
|
|
25
|
-
ALL_COLOR = [getattr(Fore, x) for x in ALL_COLOR_NAME] + [getattr(Back, x) for x in ALL_COLOR_NAME]
|
|
26
|
-
ALL_STYLE = [getattr(Style, x) for x in ALL_STYLE_NAME]
|
|
27
|
-
ALL_COLOR_STYLE = ALL_COLOR + ALL_STYLE
|
|
28
|
-
|
|
29
|
-
COLORAMA_TRANSLATE = {
|
|
30
|
-
"bold": "bright",
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
NoneType = type(None)
|
|
34
|
-
ColorFormat = Union[str, tuple, list, NoneType]
|
|
35
|
-
ColorFormatTuple = (str, tuple, list, NoneType)
|
|
36
|
-
|
|
37
|
-
EPS = 1e-9
|
|
38
|
-
CURSOR_UP = "\033[A"
|
|
19
|
+
from progress_table.v1 import styles
|
|
20
|
+
from progress_table.v1.common import CURSOR_UP, ColorFormat, ColorFormatTuple, maybe_convert_to_colorama
|
|
21
|
+
from progress_table.v1.styles import parse_pbar_style
|
|
39
22
|
|
|
40
23
|
# Flags that indicate if the warning was already triggered
|
|
41
24
|
WARNED_PBAR_HIDDEN = False
|
|
@@ -91,29 +74,6 @@ def get_aggregate_fn(aggregate: None | str | Callable):
|
|
|
91
74
|
raise ValueError(f"Unknown aggregate type: {type(aggregate)}")
|
|
92
75
|
|
|
93
76
|
|
|
94
|
-
def maybe_convert_to_colorama_str(color: str) -> str:
|
|
95
|
-
# Translation layer to fix unintuitive colorama names
|
|
96
|
-
color = COLORAMA_TRANSLATE.get(color.lower(), color)
|
|
97
|
-
|
|
98
|
-
if isinstance(color, str):
|
|
99
|
-
if hasattr(Fore, color.upper()):
|
|
100
|
-
return getattr(Fore, color.upper())
|
|
101
|
-
if hasattr(Style, color.upper()):
|
|
102
|
-
return getattr(Style, color.upper())
|
|
103
|
-
|
|
104
|
-
assert color in ALL_COLOR_STYLE, f"Color {color!r} incorrect! Available: {' '.join(ALL_COLOR_STYLE_NAME)}"
|
|
105
|
-
return color
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
def maybe_convert_to_colorama(color: ColorFormat) -> str:
|
|
109
|
-
if color is None or color == "":
|
|
110
|
-
return ""
|
|
111
|
-
if isinstance(color, str):
|
|
112
|
-
color = color.split(" ")
|
|
113
|
-
results = [maybe_convert_to_colorama_str(x) for x in color]
|
|
114
|
-
return "".join(results)
|
|
115
|
-
|
|
116
|
-
|
|
117
77
|
def get_default_format_func(decimal_places):
|
|
118
78
|
def fmt(x) -> str:
|
|
119
79
|
if isinstance(x, int):
|
|
@@ -151,19 +111,19 @@ class ProgressTableV1:
|
|
|
151
111
|
default_column_color: ColorFormat = None,
|
|
152
112
|
default_column_alignment: str | None = None,
|
|
153
113
|
default_column_aggregate: str | None = None,
|
|
114
|
+
default_header_color: ColorFormat = None,
|
|
154
115
|
default_row_color: ColorFormat = None,
|
|
155
116
|
pbar_show_throughput: bool = True,
|
|
156
117
|
pbar_show_progress: bool = False,
|
|
157
118
|
pbar_show_percents: bool = False,
|
|
158
119
|
pbar_show_eta: bool = False,
|
|
159
120
|
pbar_embedded: bool = True,
|
|
160
|
-
|
|
121
|
+
pbar_style: str | Type[styles.PbarStyleBase] = "square",
|
|
122
|
+
pbar_style_embed: str | Type[styles.PbarStyleBase] = "embed",
|
|
161
123
|
print_header_on_top: bool = True,
|
|
162
124
|
print_header_every_n_rows: int = 30,
|
|
163
125
|
custom_cell_format: Callable[[Any], str] | None = None,
|
|
164
126
|
table_style: str | Type[styles.TableStyleBase] = "round",
|
|
165
|
-
pbar_style: str | Type[styles.PbarStyleBase] = "normal",
|
|
166
|
-
pbar_style_embed: str | Type[styles.PbarStyleBase] = "embed",
|
|
167
127
|
file=None,
|
|
168
128
|
# Deprecated arguments
|
|
169
129
|
custom_format: None = None,
|
|
@@ -234,12 +194,14 @@ class ProgressTableV1:
|
|
|
234
194
|
if print_row_on_update is not None:
|
|
235
195
|
logging.warning("Argument `print_row_on_update` is deprecated. Specify `interactive` instead!")
|
|
236
196
|
|
|
237
|
-
self.table_style = styles.
|
|
238
|
-
|
|
239
|
-
self.
|
|
197
|
+
self.table_style = styles.parse_table_style(table_style)
|
|
198
|
+
|
|
199
|
+
self.pbar_style = styles.parse_pbar_style(pbar_style)
|
|
200
|
+
self.pbar_style_embed = styles.parse_pbar_style(pbar_style_embed)
|
|
240
201
|
|
|
241
202
|
assert isinstance(default_row_color, ColorFormatTuple), "Row color has to be a color format!" # type: ignore
|
|
242
203
|
assert isinstance(default_column_color, ColorFormatTuple), "Column color has to be a color format!" # type: ignore
|
|
204
|
+
assert isinstance(default_header_color, ColorFormatTuple), "Header color has to be a color format!" # type: ignore
|
|
243
205
|
|
|
244
206
|
# Default values for column and
|
|
245
207
|
self.column_width = default_column_width
|
|
@@ -247,6 +209,7 @@ class ProgressTableV1:
|
|
|
247
209
|
self.column_alignment = default_column_alignment
|
|
248
210
|
self.column_aggregate = default_column_aggregate
|
|
249
211
|
self.row_color = default_row_color
|
|
212
|
+
self.header_color = default_header_color
|
|
250
213
|
|
|
251
214
|
# We are storing column configs
|
|
252
215
|
self.column_widths: dict[str, int] = {}
|
|
@@ -282,7 +245,6 @@ class ProgressTableV1:
|
|
|
282
245
|
self.pbar_show_percents: bool = pbar_show_percents
|
|
283
246
|
self.pbar_show_eta: bool = pbar_show_eta
|
|
284
247
|
self.pbar_embedded: bool = pbar_embedded
|
|
285
|
-
self.pbar_color = pbar_color
|
|
286
248
|
|
|
287
249
|
self.refresh_rate: int = refresh_rate
|
|
288
250
|
|
|
@@ -786,8 +748,10 @@ class ProgressTableV1:
|
|
|
786
748
|
|
|
787
749
|
def _get_header(self):
|
|
788
750
|
content = []
|
|
751
|
+
colors = self.column_colors if self.header_color is None else self._resolve_row_color_dict(self.header_color)
|
|
752
|
+
|
|
789
753
|
for column in self.column_names:
|
|
790
|
-
value = self._apply_cell_formatting(column, column, color=
|
|
754
|
+
value = self._apply_cell_formatting(column, column, color=colors[column])
|
|
791
755
|
content.append(value)
|
|
792
756
|
s = "".join(["\r", self.table_style.vertical, self.table_style.vertical.join(content), self.table_style.vertical])
|
|
793
757
|
return s
|
|
@@ -802,7 +766,6 @@ class ProgressTableV1:
|
|
|
802
766
|
*range_args,
|
|
803
767
|
position=None,
|
|
804
768
|
static=False,
|
|
805
|
-
color="",
|
|
806
769
|
total=None,
|
|
807
770
|
refresh_rate=None,
|
|
808
771
|
description="",
|
|
@@ -810,6 +773,10 @@ class ProgressTableV1:
|
|
|
810
773
|
show_progress=None,
|
|
811
774
|
show_percents=None,
|
|
812
775
|
show_eta=None,
|
|
776
|
+
style=None,
|
|
777
|
+
style_embed=None,
|
|
778
|
+
color=None,
|
|
779
|
+
color_empty=None,
|
|
813
780
|
):
|
|
814
781
|
"""Create iterable progress bar object.
|
|
815
782
|
|
|
@@ -819,7 +786,6 @@ class ProgressTableV1:
|
|
|
819
786
|
position: Level of the progress bar. If not provided, it will be set automatically.
|
|
820
787
|
static: If True, the progress bar will stick to the row with index given by position.
|
|
821
788
|
If False, the position will be interpreted as the offset from the last row.
|
|
822
|
-
color: Color of the progress bar.
|
|
823
789
|
total: Total number of iterations. If not provided, it will be calculated from the length of the iterable.
|
|
824
790
|
refresh_rate: The maximal number of times per second the progress bar will be refreshed.
|
|
825
791
|
description: Custom description of the progress bar that will be shown as prefix.
|
|
@@ -827,6 +793,10 @@ class ProgressTableV1:
|
|
|
827
793
|
show_progress: If True, the progress will be displayed.
|
|
828
794
|
show_percents: If True, the percentage of the progress will be displayed.
|
|
829
795
|
show_eta: If True, the estimated time of finishing will be displayed.
|
|
796
|
+
style: Style of the progress bar. If None, the default style will be used.
|
|
797
|
+
style_embed: Style of the embedded progress bar. If None, the default style will be used.
|
|
798
|
+
color: Color of the progress bar. This overrides the default color.
|
|
799
|
+
color_empty: Color of the empty progress bar. This overrides the default color.
|
|
830
800
|
"""
|
|
831
801
|
if isinstance(iterable, int):
|
|
832
802
|
iterable = range(iterable, *range_args)
|
|
@@ -844,13 +814,19 @@ class ProgressTableV1:
|
|
|
844
814
|
|
|
845
815
|
total = total if total is not None else (len(iterable) if isinstance(iterable, Sized) else 0)
|
|
846
816
|
|
|
817
|
+
style = parse_pbar_style(style) if style else self.pbar_style
|
|
818
|
+
style_embed = parse_pbar_style(style_embed) if style_embed else self.pbar_style_embed
|
|
819
|
+
|
|
847
820
|
pbar = TableProgressBar(
|
|
848
821
|
iterable=iterable,
|
|
849
822
|
table=self,
|
|
850
823
|
total=total,
|
|
824
|
+
style=style,
|
|
825
|
+
style_embed=style_embed,
|
|
826
|
+
color=color,
|
|
827
|
+
color_empty=color_empty,
|
|
851
828
|
position=position,
|
|
852
829
|
static=static,
|
|
853
|
-
color=color or self.pbar_color,
|
|
854
830
|
description=description,
|
|
855
831
|
show_throughput=show_throughput if show_throughput is not None else self.pbar_show_throughput,
|
|
856
832
|
show_progress=show_progress if show_progress is not None else self.pbar_show_progress,
|
|
@@ -872,7 +848,10 @@ class TableProgressBar:
|
|
|
872
848
|
*,
|
|
873
849
|
table,
|
|
874
850
|
total,
|
|
851
|
+
style,
|
|
852
|
+
style_embed,
|
|
875
853
|
color,
|
|
854
|
+
color_empty,
|
|
876
855
|
position,
|
|
877
856
|
static,
|
|
878
857
|
description,
|
|
@@ -888,10 +867,21 @@ class TableProgressBar:
|
|
|
888
867
|
self._creation_time: float = time.perf_counter()
|
|
889
868
|
self._last_refresh_time: float = -float("inf")
|
|
890
869
|
|
|
870
|
+
self.style = style
|
|
871
|
+
self.style_embed = style_embed
|
|
872
|
+
|
|
873
|
+
# Modyfing styles
|
|
874
|
+
if color:
|
|
875
|
+
color = maybe_convert_to_colorama(color)
|
|
876
|
+
self.style.color = color
|
|
877
|
+
self.style_embed.color = color
|
|
878
|
+
if color_empty:
|
|
879
|
+
color_empty = maybe_convert_to_colorama(color_empty)
|
|
880
|
+
self.style.color_empty = color_empty
|
|
881
|
+
self.style_embed.color_empty = color_empty
|
|
882
|
+
|
|
891
883
|
self.position: int = position
|
|
892
884
|
self.static: bool = static
|
|
893
|
-
|
|
894
|
-
self.color: str = maybe_convert_to_colorama(color)
|
|
895
885
|
self.table: ProgressTableV1 = table
|
|
896
886
|
self.description: str = description
|
|
897
887
|
self.show_throughput: bool = show_throughput
|
|
@@ -977,6 +967,7 @@ class TableProgressBar:
|
|
|
977
967
|
total = tot_width
|
|
978
968
|
|
|
979
969
|
num_filled = math.ceil(step / total * tot_width)
|
|
970
|
+
frac_missing = step / total * tot_width - num_filled
|
|
980
971
|
num_empty = tot_width - num_filled
|
|
981
972
|
|
|
982
973
|
if embed_str is not None:
|
|
@@ -985,23 +976,35 @@ class TableProgressBar:
|
|
|
985
976
|
|
|
986
977
|
filled_part = row_str[:num_filled]
|
|
987
978
|
if len(filled_part) > 0 and filled_part[-1] == " ":
|
|
988
|
-
|
|
989
|
-
|
|
979
|
+
head = self.style_embed.head
|
|
980
|
+
if isinstance(head, (tuple, list)):
|
|
981
|
+
head = head[round(frac_missing * len(head))]
|
|
982
|
+
filled_part = filled_part[:-1] + head
|
|
983
|
+
filled_part = filled_part.replace(" ", self.style_embed.filled)
|
|
990
984
|
empty_part = row_str[num_filled:-1]
|
|
985
|
+
color_filled = self.style_embed.color
|
|
986
|
+
color_empty = self.style_embed.color_empty
|
|
991
987
|
else:
|
|
992
|
-
filled_part = self.
|
|
988
|
+
filled_part = self.style.filled * num_filled
|
|
993
989
|
if len(filled_part) > 0:
|
|
994
|
-
|
|
995
|
-
|
|
990
|
+
head = self.style.head
|
|
991
|
+
if isinstance(head, (tuple, list)):
|
|
992
|
+
head = head[round(frac_missing * len(head))]
|
|
993
|
+
filled_part = filled_part[:-1] + head
|
|
994
|
+
empty_part = self.style.empty * num_empty
|
|
995
|
+
color_filled = self.style.color
|
|
996
|
+
color_empty = self.style.color_empty
|
|
996
997
|
|
|
997
998
|
pbar_body = "".join(
|
|
998
999
|
[
|
|
999
1000
|
self.table.table_style.vertical,
|
|
1000
1001
|
infobar,
|
|
1001
|
-
|
|
1002
|
+
color_filled,
|
|
1002
1003
|
filled_part,
|
|
1003
|
-
Style.RESET_ALL if
|
|
1004
|
+
Style.RESET_ALL if color_filled else "",
|
|
1005
|
+
color_empty,
|
|
1004
1006
|
empty_part,
|
|
1007
|
+
Style.RESET_ALL if color_empty else "",
|
|
1005
1008
|
self.table.table_style.vertical,
|
|
1006
1009
|
]
|
|
1007
1010
|
)
|
|
@@ -1,28 +1,59 @@
|
|
|
1
1
|
# Copyright (c) 2022-2024 Szymon Mikler
|
|
2
2
|
|
|
3
|
+
from progress_table.v1.common import ALL_COLOR_NAME, maybe_convert_to_colorama
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
|
|
6
|
+
def contains_word(short, long):
|
|
7
|
+
return any([short == word.strip(" ") for word in long.split(" ")])
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def parse_colors_from_description(description):
|
|
11
|
+
color = ""
|
|
12
|
+
color_empty = ""
|
|
13
|
+
for word in description.split():
|
|
14
|
+
for color_name in ALL_COLOR_NAME:
|
|
15
|
+
if color_name.lower() == word.lower():
|
|
16
|
+
if not color:
|
|
17
|
+
color = color_name
|
|
18
|
+
else:
|
|
19
|
+
color_empty = color_name
|
|
20
|
+
description = description.replace(word, "")
|
|
21
|
+
return color, color_empty, description
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def parse_pbar_style(description):
|
|
25
|
+
if isinstance(description, str):
|
|
7
26
|
for obj in available_pbar_styles():
|
|
8
|
-
if obj.name
|
|
9
|
-
|
|
27
|
+
if contains_word(obj.name, description):
|
|
28
|
+
description = description.replace(obj.name, "")
|
|
29
|
+
color, color_empty, description = parse_colors_from_description(description)
|
|
30
|
+
is_alt = "alt" in description
|
|
31
|
+
is_clean = "clean" in description
|
|
32
|
+
description = description.replace("alt", "").replace("clean", "").strip(" ")
|
|
33
|
+
if description.strip(" "):
|
|
34
|
+
raise ValueError(f"Name '{description}' is not recognized as a part of progress bar style")
|
|
35
|
+
|
|
36
|
+
return obj(alt=is_alt, clean=is_clean, color=color, color_empty=color_empty)
|
|
37
|
+
|
|
10
38
|
available_names = ", ".join([obj.name for obj in available_pbar_styles()])
|
|
11
|
-
raise ValueError(f"Progress bar style '{
|
|
39
|
+
raise ValueError(f"Progress bar style '{description}' not found. Available: {available_names}")
|
|
12
40
|
else:
|
|
13
|
-
return
|
|
41
|
+
return description
|
|
14
42
|
|
|
15
43
|
|
|
16
|
-
def
|
|
17
|
-
if isinstance(
|
|
18
|
-
table_style_name = table_style_name.lower()
|
|
44
|
+
def parse_table_style(description):
|
|
45
|
+
if isinstance(description, str):
|
|
19
46
|
for obj in available_table_styles():
|
|
20
|
-
if obj.name
|
|
21
|
-
|
|
47
|
+
if contains_word(obj.name, description):
|
|
48
|
+
description = description.replace(obj.name, "").strip(" ")
|
|
49
|
+
if description:
|
|
50
|
+
raise ValueError(f"Name '{description}' is not recognized as a part of table style")
|
|
51
|
+
|
|
52
|
+
return obj()
|
|
22
53
|
available_names = ", ".join([obj.name for obj in available_table_styles()])
|
|
23
|
-
raise ValueError(f"Table style '{
|
|
54
|
+
raise ValueError(f"Table style '{description}' not found. Available: {available_names}")
|
|
24
55
|
else:
|
|
25
|
-
return
|
|
56
|
+
return description
|
|
26
57
|
|
|
27
58
|
|
|
28
59
|
def available_table_styles():
|
|
@@ -42,34 +73,53 @@ class PbarStyleBase:
|
|
|
42
73
|
name: str
|
|
43
74
|
filled: str
|
|
44
75
|
empty: str
|
|
45
|
-
head: str
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
76
|
+
head: str | tuple[str, ...]
|
|
77
|
+
color: str = ""
|
|
78
|
+
color_empty: str = ""
|
|
79
|
+
|
|
80
|
+
def __init__(self, alt=False, clean=False, color=None, color_empty=None):
|
|
81
|
+
if color is not None:
|
|
82
|
+
self.color = maybe_convert_to_colorama(color)
|
|
83
|
+
if color_empty is not None:
|
|
84
|
+
self.color_empty = maybe_convert_to_colorama(color_empty)
|
|
85
|
+
if alt:
|
|
86
|
+
self.empty = self.filled
|
|
87
|
+
if clean:
|
|
88
|
+
self.empty = " "
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class PbarStyleSquare(PbarStyleBase):
|
|
92
|
+
name = "square"
|
|
50
93
|
filled = "■"
|
|
51
94
|
empty = "□"
|
|
52
95
|
head = "◩"
|
|
53
96
|
|
|
54
97
|
|
|
55
|
-
class
|
|
56
|
-
name = "
|
|
57
|
-
filled = "
|
|
98
|
+
class PbarStyleFull(PbarStyleBase):
|
|
99
|
+
name = "full"
|
|
100
|
+
filled = "█"
|
|
58
101
|
empty = " "
|
|
59
|
-
head = "
|
|
102
|
+
head = ("▏", "▎", "▍", "▌", "▋", "▊", "▉")
|
|
60
103
|
|
|
61
104
|
|
|
62
|
-
class
|
|
63
|
-
name = "
|
|
64
|
-
filled = "
|
|
65
|
-
empty = "
|
|
66
|
-
head = "
|
|
105
|
+
class PbarStyleDots(PbarStyleBase):
|
|
106
|
+
name = "dots"
|
|
107
|
+
filled = "⣿"
|
|
108
|
+
empty = "⣀"
|
|
109
|
+
head = ("⣄", "⣤", "⣦", "⣶", "⣷")
|
|
110
|
+
|
|
67
111
|
|
|
112
|
+
class PbarStyleShort(PbarStyleBase):
|
|
113
|
+
name = "short"
|
|
114
|
+
filled = "▬"
|
|
115
|
+
empty = "▭"
|
|
116
|
+
head = "▬"
|
|
68
117
|
|
|
69
|
-
|
|
70
|
-
|
|
118
|
+
|
|
119
|
+
class PbarStyleCircle(PbarStyleBase):
|
|
120
|
+
name = "circle"
|
|
71
121
|
filled = "●"
|
|
72
|
-
empty = "
|
|
122
|
+
empty = "○"
|
|
73
123
|
head = "◉"
|
|
74
124
|
|
|
75
125
|
|
|
@@ -80,13 +130,6 @@ class PbarStyleAngled(PbarStyleBase):
|
|
|
80
130
|
head = "▰"
|
|
81
131
|
|
|
82
132
|
|
|
83
|
-
class PbarStyleAngledClean(PbarStyleBase):
|
|
84
|
-
name = "angled clean"
|
|
85
|
-
filled = "▰"
|
|
86
|
-
empty = " "
|
|
87
|
-
head = "▰"
|
|
88
|
-
|
|
89
|
-
|
|
90
133
|
class PbarStyleEmbed(PbarStyleBase):
|
|
91
134
|
name = "embed"
|
|
92
135
|
filled = "ꞏ"
|
|
@@ -94,6 +137,21 @@ class PbarStyleEmbed(PbarStyleBase):
|
|
|
94
137
|
head = ">"
|
|
95
138
|
|
|
96
139
|
|
|
140
|
+
class PbarStyleRich(PbarStyleBase):
|
|
141
|
+
name = "rich"
|
|
142
|
+
filled = "━"
|
|
143
|
+
empty = " "
|
|
144
|
+
head = "━"
|
|
145
|
+
|
|
146
|
+
def __init__(self, *args, **kwds):
|
|
147
|
+
"""Similar to the default progress bar from rich"""
|
|
148
|
+
super().__init__(*args, **kwds)
|
|
149
|
+
if not self.color and not self.color_empty:
|
|
150
|
+
self.color = maybe_convert_to_colorama("red")
|
|
151
|
+
self.color_empty = maybe_convert_to_colorama("black")
|
|
152
|
+
self.empty = self.filled
|
|
153
|
+
|
|
154
|
+
|
|
97
155
|
class PbarStyleNone(PbarStyleBase):
|
|
98
156
|
name = "hidden"
|
|
99
157
|
filled = " "
|
|
@@ -122,8 +180,8 @@ class TableStyleBase:
|
|
|
122
180
|
no_down: str
|
|
123
181
|
|
|
124
182
|
|
|
125
|
-
class
|
|
126
|
-
name = "
|
|
183
|
+
class TableStyleModern(TableStyleBase):
|
|
184
|
+
name = "modern"
|
|
127
185
|
cell_overflow = "…"
|
|
128
186
|
horizontal = "─"
|
|
129
187
|
vertical = "│"
|
|
@@ -219,7 +277,7 @@ class TableStyleAscii(TableStyleBase):
|
|
|
219
277
|
|
|
220
278
|
|
|
221
279
|
class TableStyleAsciiBare(TableStyleBase):
|
|
222
|
-
name = "
|
|
280
|
+
name = "asciib"
|
|
223
281
|
cell_overflow = "_"
|
|
224
282
|
horizontal = "-"
|
|
225
283
|
vertical = " "
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: progress-table
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: Display progress as a pretty table in the command line.
|
|
5
5
|
Home-page: https://github.com/gahaalt/progress-table.git
|
|
6
6
|
Author: Szymon Mikler
|
|
@@ -118,8 +118,8 @@ Progress Table works correctly in most consoles, but there are some exceptions:
|
|
|
118
118
|
* Some consoles like `PyCharm Python Console` or `IDLE` don't support cursor movement.
|
|
119
119
|
You can still use ProgressTable, but with `interactive=1` option. This mode displays only 1 progress bar at once.
|
|
120
120
|
|
|
121
|
-
> By default `interactive=2`. You can change the default `interactive`
|
|
122
|
-
> setting `PTABLE_INTERACTIVE` environment variable, e.g. `PTABLE_INTERACTIVE=1`.
|
|
121
|
+
> By default `interactive=2`. You can change the default `interactive` with an argument when creating the table object
|
|
122
|
+
> or by setting `PTABLE_INTERACTIVE` environment variable, e.g. `PTABLE_INTERACTIVE=1`.
|
|
123
123
|
|
|
124
124
|
## Installation
|
|
125
125
|
|
|
@@ -14,6 +14,7 @@ progress_table/v0/__init__.py
|
|
|
14
14
|
progress_table/v0/progress_table.py
|
|
15
15
|
progress_table/v0/symbols.py
|
|
16
16
|
progress_table/v1/__init__.py
|
|
17
|
+
progress_table/v1/common.py
|
|
17
18
|
progress_table/v1/progress_table.py
|
|
18
19
|
progress_table/v1/styles.py
|
|
19
20
|
tests/test_docs_automated.py
|
|
@@ -8,7 +8,7 @@ from io import StringIO
|
|
|
8
8
|
|
|
9
9
|
EXPECTED_OUTPUTS = {
|
|
10
10
|
"examples.training": "14af860a37118c16aec4604e5629e5ed",
|
|
11
|
-
"examples.tictactoe": "
|
|
11
|
+
"examples.tictactoe": "378133fb7804a678282564d751068531",
|
|
12
12
|
"examples.brown2d": "c0f37fdfcfc2db6ef465473c67c05d83",
|
|
13
13
|
}
|
|
14
14
|
|
|
@@ -27,7 +27,7 @@ def capture_example_stdout(main_fn):
|
|
|
27
27
|
# We will replace stdout with custom StringIO and check whether example stdout is as expected
|
|
28
28
|
out_buffer = StringIO()
|
|
29
29
|
sys.stdout = out_buffer
|
|
30
|
-
main_fn(random_seed=42, **override_kwds)
|
|
30
|
+
main_fn(random_seed=42, sleep_duration=0, **override_kwds)
|
|
31
31
|
sys.stdout = sys.__stdout__
|
|
32
32
|
return out_buffer.getvalue()
|
|
33
33
|
|
|
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
|