progress-table 3.1.2__tar.gz → 3.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: progress-table
3
- Version: 3.1.2
3
+ Version: 3.2.0
4
4
  Summary: Display progress as a pretty table in the command line.
5
5
  Project-URL: Home, https://github.com/gahaalt/progress-table
6
6
  Project-URL: Documentation, https://github.com/sjmikler/progress-table/blob/main/docs
@@ -18,6 +18,7 @@ Classifier: Programming Language :: Python :: 3.12
18
18
  Classifier: Programming Language :: Python :: 3.13
19
19
  Requires-Python: >=3.7
20
20
  Requires-Dist: colorama
21
+ Requires-Dist: wcwidth
21
22
  Provides-Extra: dev
22
23
  Requires-Dist: hatch; extra == 'dev'
23
24
  Requires-Dist: pyright; extra == 'dev'
@@ -10,7 +10,7 @@ Supported features:
10
10
  """
11
11
 
12
12
  __license__ = "MIT"
13
- __version__ = "3.1.2"
13
+ __version__ = "3.2.0"
14
14
  __author__ = "Szymon Mikler"
15
15
 
16
16
  from progress_table.progress_table import ProgressTable, styles
@@ -17,6 +17,7 @@ from dataclasses import dataclass
17
17
  from threading import Thread
18
18
  from typing import Any, TextIO
19
19
 
20
+ import wcwidth
20
21
  from colorama import Style
21
22
 
22
23
  from progress_table import styles
@@ -129,34 +130,34 @@ class ProgressTable:
129
130
  DEFAULT_ROW_COLOR = None
130
131
 
131
132
  def __init__(
132
- self,
133
- *cols: str,
134
- columns: Iterable[str] = (),
135
- interactive: int = int(os.environ.get("PTABLE_INTERACTIVE", "2")),
136
- refresh_rate: int = 20,
137
- num_decimal_places: int = 4,
138
- default_column_width: int | None = None,
139
- default_column_color: ColorFormat = None,
140
- default_column_alignment: str | None = None,
141
- default_column_aggregate: str | None = None,
142
- default_header_color: ColorFormat = None,
143
- default_row_color: ColorFormat = None,
144
- pbar_show_throughput: bool = True,
145
- pbar_show_progress: bool = False,
146
- pbar_show_percents: bool = False,
147
- pbar_show_eta: bool = False,
148
- pbar_embedded: bool = True,
149
- pbar_style: str | styles.PbarStyleBase = "square",
150
- pbar_style_embed: str | styles.PbarStyleBase = "cdots",
151
- print_header_on_top: bool = True,
152
- print_header_every_n_rows: int = 30,
153
- custom_cell_format: Callable[[Any], str] | None = None,
154
- table_style: str | styles.TableStyleBase = "round",
155
- file: TextIO | list[TextIO] | tuple[TextIO] | None = None,
156
- # DEPRECATED ARGUMENTS
157
- custom_format: None = None,
158
- embedded_progress_bar: None = None,
159
- print_row_on_update: None = None,
133
+ self,
134
+ *cols: str,
135
+ columns: Iterable[str] = (),
136
+ interactive: int = int(os.environ.get("PTABLE_INTERACTIVE", "2")),
137
+ refresh_rate: int = 20,
138
+ num_decimal_places: int = 4,
139
+ default_column_width: int | None = None,
140
+ default_column_color: ColorFormat = None,
141
+ default_column_alignment: str | None = None,
142
+ default_column_aggregate: str | None = None,
143
+ default_header_color: ColorFormat = None,
144
+ default_row_color: ColorFormat = None,
145
+ pbar_show_throughput: bool = True,
146
+ pbar_show_progress: bool = False,
147
+ pbar_show_percents: bool = False,
148
+ pbar_show_eta: bool = False,
149
+ pbar_embedded: bool = True,
150
+ pbar_style: str | styles.PbarStyleBase = "square",
151
+ pbar_style_embed: str | styles.PbarStyleBase = "cdots",
152
+ print_header_on_top: bool = True,
153
+ print_header_every_n_rows: int = 30,
154
+ custom_cell_format: Callable[[Any], str] | None = None,
155
+ table_style: str | styles.TableStyleBase = "round",
156
+ file: TextIO | list[TextIO] | tuple[TextIO] | None = None,
157
+ # DEPRECATED ARGUMENTS
158
+ custom_format: None = None,
159
+ embedded_progress_bar: None = None,
160
+ print_row_on_update: None = None,
160
161
  ) -> None:
161
162
  """Progress Table instance.
162
163
 
@@ -305,13 +306,13 @@ class ProgressTable:
305
306
  ####################
306
307
 
307
308
  def add_column(
308
- self,
309
- name: str,
310
- *,
311
- width: int | None = None,
312
- color: ColorFormat = None,
313
- alignment: str | None = None,
314
- aggregate: None | str | Callable = None,
309
+ self,
310
+ name: str,
311
+ *,
312
+ width: int | None = None,
313
+ color: ColorFormat = None,
314
+ alignment: str | None = None,
315
+ aggregate: None | str | Callable = None,
315
316
  ) -> None:
316
317
  """Add column to the table.
317
318
 
@@ -391,14 +392,14 @@ class ProgressTable:
391
392
  self._set_all_display_rows_as_pending()
392
393
 
393
394
  def update(
394
- self,
395
- name: str,
396
- value: Any,
397
- *,
398
- row: int = -1,
399
- weight: float = 1.0,
400
- cell_color: ColorFormat = None,
401
- **column_kwds,
395
+ self,
396
+ name: str,
397
+ value: Any,
398
+ *,
399
+ row: int = -1,
400
+ weight: float = 1.0,
401
+ cell_color: ColorFormat = None,
402
+ **column_kwds,
402
403
  ) -> None:
403
404
  """Update value in the current row. More powerful than __setitem__.
404
405
 
@@ -490,17 +491,17 @@ class ProgressTable:
490
491
  return self._at_indexer
491
492
 
492
493
  def next_row(
493
- self,
494
- color: ColorFormat | dict[str, ColorFormat] = None,
495
- split: bool | None = None,
496
- header: bool | None = None,
494
+ self,
495
+ color: ColorFormat | dict[str, ColorFormat] = None,
496
+ split: bool | None = None,
497
+ header: bool | None = None,
497
498
  ) -> None:
498
499
  """End the current row."""
499
500
  # Force header if it wasn't printed for a long enough time
500
501
  if (
501
- header is None
502
- and len(self._data_rows) - self._previous_header_row_number >= self._print_header_every_n_rows
503
- and self._print_header_every_n_rows > 0
502
+ header is None
503
+ and len(self._data_rows) - self._previous_header_row_number >= self._print_header_every_n_rows
504
+ and self._print_header_every_n_rows > 0
504
505
  ):
505
506
  header = True
506
507
  header = header or False
@@ -833,31 +834,38 @@ class ProgressTable:
833
834
  return {col: self.column_colors[col] + color_colorama[col] for col in color}
834
835
 
835
836
  def _apply_cell_formatting(self, value: Any, column_name: str, color: str) -> str:
836
- str_value = self.custom_cell_format(value)
837
837
  width = self.column_widths[column_name]
838
+ str_value = self.custom_cell_format(value)
838
839
  alignment = self.column_alignments[column_name]
839
840
 
841
+ real_width = 0
842
+ clipped = False
843
+ num_characters = len(str_value)
844
+ for idx, letter in enumerate(str_value):
845
+ ch_width = wcwidth.wcwidth(letter)
846
+ if real_width + ch_width > width:
847
+ num_characters = idx
848
+ clipped = True
849
+ break
850
+ real_width += ch_width
851
+
852
+ str_value = str_value[:num_characters]
853
+ num_characters += width - real_width
854
+
840
855
  if alignment == "center":
841
- str_value = str_value.center(width)
856
+ str_value = str_value.center(num_characters)
842
857
  elif alignment == "left":
843
- str_value = str_value.ljust(width)
858
+ str_value = str_value.ljust(num_characters)
844
859
  elif alignment == "right":
845
- str_value = str_value.rjust(width)
860
+ str_value = str_value.rjust(num_characters)
846
861
  else:
847
862
  allowed_alignments = ["center", "left", "right"]
848
863
  msg = f"Alignment '{alignment}' not in {allowed_alignments}!"
849
864
  raise KeyError(msg)
850
865
 
851
- clipped = len(str_value) > width
852
- str_value = "".join(
853
- [
854
- " ", # space at the beginning of the row
855
- str_value[:width].center(width),
856
- self.table_style.cell_overflow if clipped else " ",
857
- ],
858
- )
859
866
  reset = Style.RESET_ALL if color else ""
860
- return f"{color}{str_value}{reset}"
867
+ maybe_overflow = self.table_style.cell_overflow if clipped else ' '
868
+ return f"{color} {str_value}{maybe_overflow}{reset}"
861
869
 
862
870
  def _get_outer_inner_width(self) -> int:
863
871
  return sum(self.column_widths.values()) + 3 * len(self.column_widths) + 1
@@ -952,21 +960,21 @@ class ProgressTable:
952
960
  ##################
953
961
 
954
962
  def pbar(
955
- self,
956
- iterable: Iterable | int,
957
- *range_args,
958
- position=None,
959
- static=False,
960
- total=None,
961
- description="",
962
- show_throughput: bool | None = None,
963
- show_progress: bool | None = None,
964
- show_percents: bool | None = None,
965
- show_eta: bool | None = None,
966
- style=None,
967
- style_embed=None,
968
- color=None,
969
- color_empty=None,
963
+ self,
964
+ iterable: Iterable | int,
965
+ *range_args,
966
+ position=None,
967
+ static=False,
968
+ total=None,
969
+ description="",
970
+ show_throughput: bool | None = None,
971
+ show_progress: bool | None = None,
972
+ show_percents: bool | None = None,
973
+ show_eta: bool | None = None,
974
+ style=None,
975
+ style_embed=None,
976
+ color=None,
977
+ color_empty=None,
970
978
  ) -> TableProgressBar:
971
979
  """Create iterable progress bar object.
972
980
 
@@ -1033,22 +1041,22 @@ class ProgressTable:
1033
1041
 
1034
1042
  class TableProgressBar:
1035
1043
  def __init__(
1036
- self,
1037
- iterable,
1038
- *,
1039
- table,
1040
- total,
1041
- style,
1042
- style_embed,
1043
- color,
1044
- color_empty,
1045
- position,
1046
- static,
1047
- description,
1048
- show_throughput: bool,
1049
- show_progress: bool,
1050
- show_percents: bool,
1051
- show_eta: bool,
1044
+ self,
1045
+ iterable,
1046
+ *,
1047
+ table,
1048
+ total,
1049
+ style,
1050
+ style_embed,
1051
+ color,
1052
+ color_empty,
1053
+ position,
1054
+ static,
1055
+ description,
1056
+ show_throughput: bool,
1057
+ show_progress: bool,
1058
+ show_percents: bool,
1059
+ show_eta: bool,
1052
1060
  ) -> None:
1053
1061
  self.iterable: Iterable | None = iterable
1054
1062
 
@@ -1163,7 +1171,7 @@ class TableProgressBar:
1163
1171
  num_empty = inner_width - num_filled
1164
1172
 
1165
1173
  if embed_str is not None:
1166
- row_str = embed_str[1 + len(infobar) :]
1174
+ row_str = embed_str[1 + len(infobar):]
1167
1175
 
1168
1176
  filled_part = row_str[:num_filled]
1169
1177
  if len(filled_part) > 0 and filled_part[-1] == " ":
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
6
6
  name = "progress-table"
7
7
  dynamic = ["version"]
8
8
  description = "Display progress as a pretty table in the command line."
9
- dependencies = ["colorama"]
9
+ dependencies = ["colorama", "wcwidth"]
10
10
  license = { text = "MIT" }
11
11
  requires-python = ">=3.7"
12
12
  authors = [
File without changes