progress-table 3.2.1__tar.gz → 3.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.
@@ -1,4 +1,6 @@
1
1
  .idea
2
+ .vscode
3
+ .zed
2
4
  .ipynb_checkpoints
3
5
  *.ipynb
4
6
  __pycache__
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: progress-table
3
- Version: 3.2.1
3
+ Version: 3.3.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
@@ -40,6 +40,7 @@ Lightweight utility to display the progress of your process as a pretty table in
40
40
  * Designed to monitor ML experiments, but works for any metrics-producing process
41
41
  * Allows you to see at a glance what's going on with your process
42
42
  * Increases readability and simplifies your command line logging
43
+ * Is efficient: redraws only the modified rows
43
44
 
44
45
  ### Change this:
45
46
 
@@ -117,15 +118,15 @@ Go to [advanced usage](https://github.com/sjmikler/progress-table/blob/main/docs
117
118
 
118
119
  ## Troubleshooting
119
120
 
120
- ### Exceesive output
121
+ ### Excessive output
121
122
 
122
123
  Progress Table works correctly in most consoles, but there are some exceptions:
123
124
 
124
- * Some cloud logging consoles (e.g. kubernetes) don't support `\r` properly. You can still use ProgressTable, but with `interactive=0` option. This mode will not display progress bars.
125
+ * Some cloud logging consoles (e.g. Kubernetes) do not handle live, carriage-return-based redraws properly. You can still use ProgressTable with `interactive=0`. This mode prints rows when they are finalized and does not display progress bars.
125
126
 
126
- * Some consoles like 'PyCharm Python Console' or 'IDLE' don't support cursor movement. You can still use ProgressTable, but with `interactive=1` option. In this mode, you can display only a single progress bar.
127
+ * Some consoles, such as the PyCharm Python Console or IDLE, do not support moving the cursor to previous lines. You can still use ProgressTable with `interactive=1`. This mode can redraw the current line and display one progress-bar position, but previous rows remain visually frozen.
127
128
 
128
- > By default `interactive=2`. You can change the default 'interactive' with an argument when creating the table object or by setting 'PTABLE_INTERACTIVE' environment variable, e.g. `PTABLE_INTERACTIVE=1`.
129
+ > When `interactive` is omitted, it defaults to `1` in Jupyter, `0` when output is redirected, and `2` in an interactive terminal. Set it explicitly when creating the table, or override the automatic default with the `PTABLE_INTERACTIVE` environment variable, for example `PTABLE_INTERACTIVE=1`.
129
130
 
130
131
  ### Other problems
131
132
 
@@ -10,6 +10,7 @@ Lightweight utility to display the progress of your process as a pretty table in
10
10
  * Designed to monitor ML experiments, but works for any metrics-producing process
11
11
  * Allows you to see at a glance what's going on with your process
12
12
  * Increases readability and simplifies your command line logging
13
+ * Is efficient: redraws only the modified rows
13
14
 
14
15
  ### Change this:
15
16
 
@@ -87,15 +88,15 @@ Go to [advanced usage](docs/advanced-usage.md) page for more information.
87
88
 
88
89
  ## Troubleshooting
89
90
 
90
- ### Exceesive output
91
+ ### Excessive output
91
92
 
92
93
  Progress Table works correctly in most consoles, but there are some exceptions:
93
94
 
94
- * Some cloud logging consoles (e.g. kubernetes) don't support `\r` properly. You can still use ProgressTable, but with `interactive=0` option. This mode will not display progress bars.
95
+ * Some cloud logging consoles (e.g. Kubernetes) do not handle live, carriage-return-based redraws properly. You can still use ProgressTable with `interactive=0`. This mode prints rows when they are finalized and does not display progress bars.
95
96
 
96
- * Some consoles like 'PyCharm Python Console' or 'IDLE' don't support cursor movement. You can still use ProgressTable, but with `interactive=1` option. In this mode, you can display only a single progress bar.
97
+ * Some consoles, such as the PyCharm Python Console or IDLE, do not support moving the cursor to previous lines. You can still use ProgressTable with `interactive=1`. This mode can redraw the current line and display one progress-bar position, but previous rows remain visually frozen.
97
98
 
98
- > By default `interactive=2`. You can change the default 'interactive' with an argument when creating the table object or by setting 'PTABLE_INTERACTIVE' environment variable, e.g. `PTABLE_INTERACTIVE=1`.
99
+ > When `interactive` is omitted, it defaults to `1` in Jupyter, `0` when output is redirected, and `2` in an interactive terminal. Set it explicitly when creating the table, or override the automatic default with the `PTABLE_INTERACTIVE` environment variable, for example `PTABLE_INTERACTIVE=1`.
99
100
 
100
101
  ### Other problems
101
102
 
@@ -10,6 +10,7 @@ Lightweight utility to display the progress of your process as a pretty table in
10
10
  * Designed to monitor ML experiments, but works for any metrics-producing process
11
11
  * Allows you to see at a glance what's going on with your process
12
12
  * Increases readability and simplifies your command line logging
13
+ * Is efficient: redraws only the modified rows
13
14
 
14
15
  ### Change this:
15
16
 
@@ -87,15 +88,15 @@ Go to [advanced usage](https://github.com/sjmikler/progress-table/blob/main/docs
87
88
 
88
89
  ## Troubleshooting
89
90
 
90
- ### Exceesive output
91
+ ### Excessive output
91
92
 
92
93
  Progress Table works correctly in most consoles, but there are some exceptions:
93
94
 
94
- * Some cloud logging consoles (e.g. kubernetes) don't support `\r` properly. You can still use ProgressTable, but with `interactive=0` option. This mode will not display progress bars.
95
+ * Some cloud logging consoles (e.g. Kubernetes) do not handle live, carriage-return-based redraws properly. You can still use ProgressTable with `interactive=0`. This mode prints rows when they are finalized and does not display progress bars.
95
96
 
96
- * Some consoles like 'PyCharm Python Console' or 'IDLE' don't support cursor movement. You can still use ProgressTable, but with `interactive=1` option. In this mode, you can display only a single progress bar.
97
+ * Some consoles, such as the PyCharm Python Console or IDLE, do not support moving the cursor to previous lines. You can still use ProgressTable with `interactive=1`. This mode can redraw the current line and display one progress-bar position, but previous rows remain visually frozen.
97
98
 
98
- > By default `interactive=2`. You can change the default 'interactive' with an argument when creating the table object or by setting 'PTABLE_INTERACTIVE' environment variable, e.g. `PTABLE_INTERACTIVE=1`.
99
+ > When `interactive` is omitted, it defaults to `1` in Jupyter, `0` when output is redirected, and `2` in an interactive terminal. Set it explicitly when creating the table, or override the automatic default with the `PTABLE_INTERACTIVE` environment variable, for example `PTABLE_INTERACTIVE=1`.
99
100
 
100
101
  ### Other problems
101
102
 
@@ -2,12 +2,12 @@
2
2
 
3
3
  ## Indexing
4
4
 
5
- Progress Table with `interactive>=2` supports modyfing already closed rows (rows above the current row).
6
- This can be done either with `.update` method or using `.at` indexing which is a shorthand for `AtIndexer` object.
5
+ Progress Table with `interactive>=2` supports modifying already closed rows (rows above the current row).
6
+ This can be done either with the `.update` method or with `.at` indexing, which is shorthand for the `AtIndexer`
7
+ object.
7
8
 
8
9
 
9
- > When using `interactive<2` mode, you can only modify the current row.
10
- > Any changes made to other rows will not be displayed.
10
+ > With `interactive<2`, only the current row can be redrawn. Changes to other rows are stored but are not displayed.
11
11
 
12
12
  ### `.update` method
13
13
 
@@ -79,9 +79,10 @@ Which should give you the following:
79
79
  There are two types of progress bars in Progress Table: embedded and non-embedded.
80
80
 
81
81
 
82
- > When using `interactive=0` mode, the progress bars will not be displayed.
82
+ > With `interactive=0`, live redraws are disabled, rows are printed when finalized, and progress bars are not
83
+ > displayed.
83
84
 
84
- > When using `interactive=1` mode, progress bars are be displayed only in the bottom row.
85
+ > With `interactive=1`, only the current line can be redrawn, so only one progress-bar position is visible.
85
86
 
86
87
  ### Embedded progress bars
87
88
 
@@ -10,7 +10,7 @@ Supported features:
10
10
  """
11
11
 
12
12
  __license__ = "MIT"
13
- __version__ = "3.2.1"
13
+ __version__ = "3.3.0"
14
14
  __author__ = "Szymon Mikler"
15
15
 
16
16
  from progress_table.progress_table import ProgressTable, styles
@@ -3,7 +3,9 @@
3
3
 
4
4
  """Common utilities for progress_table."""
5
5
 
6
- from typing import Union
6
+ import os
7
+ import sys
8
+ from typing import Optional, TextIO, Union
7
9
 
8
10
  from colorama import Back, Fore, Style
9
11
 
@@ -49,3 +51,26 @@ def maybe_convert_to_colorama(color: ColorFormat) -> str:
49
51
  color = color.split(" ")
50
52
  results = [maybe_convert_to_colorama_str(x) for x in color]
51
53
  return "".join(results)
54
+
55
+
56
+ def is_ipython_kernel() -> bool:
57
+ try:
58
+ from IPython.core.getipython import get_ipython
59
+
60
+ ipython = get_ipython()
61
+ if ipython is not None:
62
+ return "IPKernelApp" in ipython.config
63
+ return False
64
+ except ImportError:
65
+ return False
66
+
67
+
68
+ def is_interactive_terminal(stream: Optional[TextIO] = None) -> bool:
69
+ """Check whether a stream supports interactive terminal output."""
70
+ if stream is None:
71
+ stream = sys.stdout
72
+ assert stream is not None
73
+ try:
74
+ return stream.isatty() and os.environ.get("TERM") != "dumb"
75
+ except (AttributeError, OSError, ValueError):
76
+ return False
@@ -25,6 +25,8 @@ from progress_table.common import (
25
25
  CURSOR_UP,
26
26
  ColorFormat,
27
27
  ColorFormatTuple,
28
+ is_interactive_terminal,
29
+ is_ipython_kernel,
28
30
  maybe_convert_to_colorama,
29
31
  )
30
32
 
@@ -133,7 +135,7 @@ class ProgressTable:
133
135
  self,
134
136
  *cols: str,
135
137
  columns: Iterable[str] = (),
136
- interactive: int = int(os.environ.get("PTABLE_INTERACTIVE", "2")),
138
+ interactive: int | None = None,
137
139
  refresh_rate: int = 20,
138
140
  num_decimal_places: int = 4,
139
141
  default_column_width: int | None = None,
@@ -148,7 +150,7 @@ class ProgressTable:
148
150
  pbar_show_eta: bool = False,
149
151
  pbar_embedded: bool = True,
150
152
  pbar_style: str | styles.PbarStyleBase = "square",
151
- pbar_style_embed: str | styles.PbarStyleBase = "cdots",
153
+ pbar_style_embed: str | styles.PbarStyleBase = "dash",
152
154
  print_header_on_top: bool = True,
153
155
  print_header_every_n_rows: int = 30,
154
156
  custom_cell_format: Callable[[Any], str] | None = None,
@@ -177,15 +179,16 @@ class ProgressTable:
177
179
  settings like alignment, color and width, while columns added through methods can have those
178
180
  customized.
179
181
  columns: Alias for `cols`.
180
- interactive: Three interactivity levels are available: 2, 1 and 0. It's recommended to use 2, but some
181
- terminal environments might not all features. When using decreased interactivity, some features
182
- will be supressed. If something doesn't look right in your terminal, try to decrease the
183
- interactivity.
184
- On level 2 you can modify all rows, including the rows above the current one.
185
- You can also add columns on-the-fly or reorder them. You can use nested progress bars.
186
- On level 1 you can only operate on the current row, the old rows are frozen, but you still get
187
- to use a progress bar, albeit not nested. On level 0 there are no progress bars and rows are
188
- only printed after calling `next_row`.
182
+ interactive: Three interactivity levels are available: 2, 1 and 0. Level 2 is recommended, but some
183
+ environments do not support all of its features. If the output does not look right, try a
184
+ lower level. When omitted, this defaults to level 1 in Jupyter, level 0 when output is
185
+ redirected, and level 2 in an interactive terminal. The `PTABLE_INTERACTIVE` environment
186
+ variable can override this automatic default.
187
+ Level 2 supports redrawing any displayed row, adding or reordering columns on the fly, and
188
+ nested progress bars. Level 1 redraws only the current line; changes to previous rows are
189
+ stored but not displayed, and only one progress-bar position is visible. Level 0 disables
190
+ live redraws and progress bars; rows are displayed when finalized with methods such as
191
+ `next_row` or `add_row`.
189
192
  refresh_rate: The maximal number of times per second to render the updates in the table.
190
193
  num_decimal_places: This is only applicable when using the default formatting. This won't be used if
191
194
  `custom_cell_repr` is set. If applicable, for every displayed value except integers
@@ -292,7 +295,26 @@ class ProgressTable:
292
295
  self._CURSOR_ROW = 0
293
296
 
294
297
  # Interactivity settings
295
- self.interactive = interactive
298
+ auto_detected: bool = False
299
+
300
+ if interactive is not None:
301
+ self.interactive = interactive
302
+ elif "PTABLE_INTERACTIVE" in os.environ:
303
+ self.interactive = int(os.environ.get("PTABLE_INTERACTIVE", ""))
304
+ elif is_ipython_kernel():
305
+ auto_detected = True
306
+ self.interactive = 1
307
+ elif not all(is_interactive_terminal(stream) for stream in self.files):
308
+ auto_detected = True
309
+ self.interactive = 0
310
+ else:
311
+ self.interactive = 2
312
+
313
+ if auto_detected:
314
+ logger.warning(
315
+ f"Automatically deduced `interactive` as {self.interactive} for compatibility."
316
+ " Set `interactive` explicitly to hide the warning."
317
+ )
296
318
  assert self.interactive in (2, 1, 0)
297
319
 
298
320
  self._printing_buffer: list[str] = []
@@ -413,6 +435,10 @@ class ProgressTable:
413
435
  If column already exists, they will have no effect.
414
436
 
415
437
  """
438
+ if self._closed:
439
+ msg = "Table was closed! Updating closed tables is not supported."
440
+ raise TableClosedError(msg)
441
+
416
442
  if name not in self.column_names:
417
443
  self.add_column(name, **column_kwds)
418
444
 
@@ -1290,19 +1316,22 @@ class TableAtIndexer:
1290
1316
  self.edit_mode_prefix_map.update({word[:i].lower(): word for i in range(1, len(word) + 1)})
1291
1317
  self.edit_mode_prefix_map.update({word[:i].upper(): word for i in range(1, len(word) + 1)})
1292
1318
 
1293
- def _parse_index(self, key: slice | tuple) -> tuple:
1319
+ def _parse_index(self, key: slice | tuple) -> tuple[list[int], list[str], str]:
1320
+ rows: slice | int
1321
+ cols: slice | int
1322
+ mode: str
1294
1323
  if isinstance(key, slice):
1295
- rows: slice | int = key
1296
- cols: slice | int = slice(None)
1297
- mode: str = "values"
1324
+ rows = key
1325
+ cols = slice(None)
1326
+ mode = "values"
1298
1327
  elif len(key) == 2:
1299
- rows: slice | int = key[0]
1300
- cols: slice | int = key[1]
1301
- mode: str = "values"
1328
+ rows = key[0]
1329
+ cols = key[1]
1330
+ mode = "values"
1302
1331
  elif len(key) >= 3:
1303
- rows: slice | int = key[0]
1304
- cols: slice | int = key[1]
1305
- mode: str = key[2]
1332
+ rows = key[0]
1333
+ cols = key[1]
1334
+ mode = key[2]
1306
1335
  assert mode in self.edit_mode_prefix_map, f"Unknown mode `{mode}`. Available: values, weights, colors"
1307
1336
  mode = self.edit_mode_prefix_map[mode]
1308
1337
  else: