0
# Utilities and Extensions
1
2
Additional utilities, helper functions, and extensions that enhance tqdm functionality. These include iterator helpers, logging integration, external service notifications, and low-level I/O wrappers for advanced use cases.
3
4
## Capabilities
5
6
### Iterator Utilities
7
8
Enhanced iterator functions with built-in progress tracking for common iteration patterns.
9
10
```python { .api }
11
from tqdm.contrib import tenumerate, tzip, tmap, DummyTqdmFile
12
from tqdm.contrib.itertools import product
13
14
def tenumerate(iterable, start=0, total=None, tqdm_class=tqdm_auto, **kwargs):
15
"""
16
Progress-wrapped enumerate function.
17
18
Equivalent to enumerate() but with tqdm progress tracking.
19
20
Parameters:
21
- iterable: Iterable to enumerate
22
- start: Starting value for enumeration (default: 0)
23
- total: Total number of items (auto-detected if None)
24
- tqdm_class: tqdm class to use (default: tqdm.auto.tqdm)
25
- **kwargs: Additional arguments passed to tqdm constructor
26
27
Yields:
28
Tuples of (index, item) with progress tracking
29
"""
30
31
def tzip(iter1, *iter2plus, **kwargs):
32
"""
33
Progress-wrapped zip function.
34
35
Equivalent to zip() but with tqdm progress tracking.
36
37
Parameters:
38
- iter1: First iterable
39
- *iter2plus: Additional iterables to zip
40
- **kwargs: Arguments passed to tqdm constructor
41
42
Yields:
43
Tuples of items from each iterable with progress tracking
44
"""
45
46
def tmap(function, *sequences, **kwargs):
47
"""
48
Progress-wrapped map function.
49
50
Equivalent to map() but with tqdm progress tracking.
51
52
Parameters:
53
- function: Function to apply to each element
54
- *sequences: Sequences to map over
55
- **kwargs: Arguments passed to tqdm constructor
56
57
Yields:
58
Results of function applied to each element with progress tracking
59
"""
60
61
def product(*iterables, **tqdm_kwargs):
62
"""
63
Progress-wrapped itertools.product function.
64
65
Equivalent to itertools.product() but with tqdm progress tracking.
66
Automatically calculates total iterations based on input sizes.
67
68
Parameters:
69
- *iterables: Iterables to compute Cartesian product of
70
- tqdm_class: tqdm class to use (default: tqdm.auto.tqdm)
71
- **tqdm_kwargs: Additional arguments passed to tqdm constructor
72
73
Yields:
74
Tuples from Cartesian product with progress tracking
75
"""
76
77
class DummyTqdmFile(ObjectWrapper):
78
"""
79
File-like wrapper for tqdm output redirection.
80
81
Allows redirecting progress bar output to custom file objects
82
while maintaining compatibility with standard file operations.
83
"""
84
def __init__(self, wrapped): ...
85
def write(self, x, nolock=False): ...
86
def __del__(self): ...
87
```
88
89
### Monitoring and Synchronization
90
91
Classes for thread monitoring and synchronization warnings.
92
93
```python { .api }
94
from tqdm import TMonitor, TqdmSynchronisationWarning
95
96
class TMonitor(threading.Thread):
97
"""
98
Monitoring thread for maximum interval enforcement.
99
100
Ensures progress bars are updated at least every maxinterval seconds
101
even if the main thread is busy with other tasks.
102
"""
103
def __init__(self, tqdm_cls, sleep_interval=None): ...
104
def exit(self): ...
105
def get_instances(self): ...
106
107
class TqdmSynchronisationWarning(TqdmWarning, RuntimeWarning):
108
"""
109
Warning for thread synchronization issues.
110
111
Raised when multiple progress bars interfere with each other
112
in multi-threaded environments.
113
"""
114
pass
115
```
116
117
### Low-Level Utilities
118
119
Low-level utility classes and functions for advanced tqdm customization and integration.
120
121
```python { .api }
122
from tqdm.utils import (
123
FormatReplace, Comparable, ObjectWrapper, SimpleTextIOWrapper,
124
DisableOnWriteError, CallbackIOWrapper, envwrap, _supports_unicode,
125
_is_ascii, _screen_shape_wrapper, _term_move_up, disp_len, disp_trim
126
)
127
128
class FormatReplace(object):
129
"""
130
String formatting with field replacements.
131
132
Provides advanced string templating with replacement patterns
133
for custom progress bar formats.
134
"""
135
def __init__(self, fmt, **fmt_vars): ...
136
def format(self, **fmt_vars): ...
137
138
class Comparable(object):
139
"""
140
Base class providing comparison operations.
141
142
Enables comparison and sorting of tqdm instances based on
143
position, description, or other attributes.
144
"""
145
def __lt__(self, other): ...
146
def __le__(self, other): ...
147
def __eq__(self, other): ...
148
def __ne__(self, other): ...
149
def __gt__(self, other): ...
150
def __ge__(self, other): ...
151
152
class ObjectWrapper(object):
153
"""
154
Base wrapper class for object proxying.
155
156
Provides foundation for creating wrapper objects that
157
proxy method calls and attribute access to wrapped objects.
158
"""
159
def __init__(self, wrapped): ...
160
def __getattr__(self, name): ...
161
def __setattr__(self, name, value): ...
162
163
class SimpleTextIOWrapper(ObjectWrapper):
164
"""
165
Text stream wrapper with encoding handling.
166
167
Wraps text I/O streams to handle encoding issues and
168
provide consistent text output across different platforms.
169
"""
170
def write(self, s): ...
171
def flush(self): ...
172
173
class DisableOnWriteError(ObjectWrapper):
174
"""
175
Wrapper that disables on write errors.
176
177
Automatically disables progress bars when write operations
178
fail, preventing cascading errors in restricted environments.
179
"""
180
def write(self, s): ...
181
182
class CallbackIOWrapper(ObjectWrapper):
183
"""
184
I/O wrapper with callback functionality.
185
186
Provides hooks for monitoring I/O operations and
187
integrating with progress tracking systems.
188
"""
189
def __init__(self, callback, stream, method="read"): ...
190
def read(self, n=-1): ...
191
def write(self, s): ...
192
193
def envwrap(prefix, types=None, is_method=False):
194
"""
195
Decorator for environment variable configuration.
196
197
Automatically reads configuration from environment variables
198
with specified prefix and applies type conversion.
199
200
Parameters:
201
- prefix: Environment variable prefix (e.g., 'TQDM_')
202
- types: Type conversion mapping for parameters
203
- is_method: Whether decorating a method (vs function)
204
205
Returns:
206
Decorator function that applies environment configuration
207
"""
208
```
209
210
### Terminal and Display Utilities
211
212
Functions for terminal capability detection and display formatting.
213
214
```python { .api }
215
def _supports_unicode(fp):
216
"""
217
Check if file pointer supports Unicode output.
218
219
Parameters:
220
- fp: File pointer to test
221
222
Returns:
223
Boolean indicating Unicode support
224
"""
225
226
def _is_ascii(s):
227
"""
228
Check if string contains only ASCII characters.
229
230
Parameters:
231
- s: String to test
232
233
Returns:
234
Boolean indicating ASCII-only content
235
"""
236
237
def _screen_shape_wrapper():
238
"""
239
Get terminal screen dimensions with fallbacks.
240
241
Returns:
242
Tuple of (rows, columns) or None if unavailable
243
"""
244
245
def _term_move_up():
246
"""
247
Generate terminal cursor move up sequence.
248
249
Returns:
250
ANSI escape sequence for moving cursor up one line
251
"""
252
253
def disp_len(data):
254
"""
255
Calculate display length accounting for Unicode.
256
257
Parameters:
258
- data: String data to measure
259
260
Returns:
261
Display width of string accounting for wide characters
262
"""
263
264
def disp_trim(data, length):
265
"""
266
Trim string to specified display length.
267
268
Parameters:
269
- data: String to trim
270
- length: Target display length
271
272
Returns:
273
Trimmed string with proper Unicode handling
274
"""
275
```
276
277
### Logging Integration
278
279
Integration with Python's logging system for progress-aware logging.
280
281
```python { .api }
282
from tqdm.contrib.logging import tqdm_logging_redirect
283
284
@contextmanager
285
def tqdm_logging_redirect(*tqdm_args, **tqdm_kwargs):
286
"""
287
Context manager for redirecting logging output during progress tracking.
288
289
Temporarily redirects log messages to avoid interfering with
290
progress bar display, then restores normal logging.
291
292
Parameters:
293
- *tqdm_args: Arguments passed to tqdm constructor
294
- **tqdm_kwargs: Keyword arguments passed to tqdm constructor
295
296
Yields:
297
tqdm instance with logging redirection active
298
"""
299
```
300
301
### External Service Notifications
302
303
Integration modules for sending progress notifications to external services.
304
305
```python { .api }
306
from tqdm.contrib.slack import SlackTqdm, tqdm_slack
307
from tqdm.contrib.discord import DiscordTqdm, tqdm_discord
308
from tqdm.contrib.telegram import TelegramTqdm, tqdm_telegram
309
310
class SlackTqdm(tqdm_auto):
311
"""
312
Progress bar that sends updates to Slack channels.
313
314
Requires slack-sdk package and proper authentication setup.
315
Useful for monitoring long-running processes remotely.
316
"""
317
def __init__(self, *args, token=None, channel=None, **kwargs): ...
318
319
class DiscordTqdm(tqdm_auto):
320
"""
321
Progress bar that sends updates to Discord channels.
322
323
Requires requests package and Discord webhook URL.
324
Provides real-time progress updates via Discord messages.
325
"""
326
def __init__(self, *args, token=None, channel=None, **kwargs): ...
327
328
class TelegramTqdm(tqdm_auto):
329
"""
330
Progress bar that sends updates to Telegram chats.
331
332
Requires requests package and Telegram bot token.
333
Sends progress notifications to specified chat ID.
334
"""
335
def __init__(self, *args, token=None, chat_id=None, **kwargs): ...
336
337
# Convenience functions
338
def tqdm_slack(*args, **kwargs):
339
"""Slack-enabled tqdm with simplified setup"""
340
341
def tqdm_discord(*args, **kwargs):
342
"""Discord-enabled tqdm with simplified setup"""
343
344
def tqdm_telegram(*args, **kwargs):
345
"""Telegram-enabled tqdm with simplified setup"""
346
```
347
348
### Command Line Interface
349
350
Main CLI functionality for using tqdm as a shell command processor in pipelines.
351
352
```python { .api }
353
from tqdm.cli import main, cast
354
355
def main(fp=sys.stderr, argv=None):
356
"""
357
Command-line interface for tqdm as shell pipe processor.
358
359
Enables using tqdm in shell pipelines to add progress bars
360
to any command that processes stdin/stdout. Supports extensive
361
configuration options for progress display and data processing.
362
363
CLI Options:
364
- --help: Show help message
365
- --version: Show version information
366
- --desc: Set description text
367
- --total: Set total expected iterations
368
- --ncols: Set progress bar width
369
- --ascii: Use ASCII characters only
370
- --unit: Set unit of measurement
371
- --unit_scale: Enable unit scaling (K, M, G)
372
- --rate: Show iteration rate
373
- --bar_format: Custom bar format string
374
- --bytes: Count bytes instead of lines
375
- --delim: Set delimiter character (default: newline)
376
- --buf_size: Set buffer size for processing
377
- --null: Discard input (no output)
378
- --update: Treat input as progress updates
379
- --update_to: Treat input as absolute position
380
- --tee: Pass input to both stderr and stdout
381
- --log: Set logging level
382
- --manpath: Directory for manual pages
383
- --comppath: Directory for completions
384
385
Parameters:
386
- fp: Output stream for progress bar (default: sys.stderr)
387
- argv: Command line arguments (default: sys.argv)
388
389
Returns:
390
Exit code (0 for success)
391
"""
392
393
def cast(val, typ):
394
"""
395
Type casting utility for CLI arguments with support for multiple types.
396
397
Handles type conversion for CLI parameters including booleans,
398
characters, strings, integers, floats, and union types.
399
400
Parameters:
401
- val: String value to cast
402
- typ: Target type string (e.g., 'int', 'float', 'bool', 'str or int')
403
404
Returns:
405
Casted value with appropriate type
406
407
Raises:
408
TqdmTypeError: If type conversion fails
409
"""
410
```
411
412
## Usage Examples
413
414
### Iterator Utilities
415
416
```python
417
from tqdm.contrib import tenumerate, tzip, tmap
418
import time
419
420
# Progress-wrapped enumerate
421
data = ['item1', 'item2', 'item3', 'item4', 'item5'] * 200
422
for i, item in tenumerate(data, desc="Enumerating"):
423
time.sleep(0.001)
424
# Process item with index
425
426
# Progress-wrapped zip
427
list1 = range(1000)
428
list2 = range(1000, 2000)
429
list3 = range(2000, 3000)
430
431
for a, b, c in tzip(list1, list2, list3, desc="Zipping"):
432
result = a + b + c
433
time.sleep(0.0001)
434
435
# Progress-wrapped map
436
def square(x):
437
time.sleep(0.001) # Simulate processing
438
return x ** 2
439
440
numbers = range(100)
441
squared = list(tmap(square, numbers, desc="Mapping"))
442
print(f"First 10 squares: {squared[:10]}")
443
```
444
445
### Advanced Iterator Patterns
446
447
```python
448
from tqdm.contrib import tenumerate, tzip, tmap
449
import itertools
450
import random
451
452
# Complex data processing pipeline
453
def process_data_pipeline():
454
# Generate sample data
455
raw_data = [random.randint(1, 1000) for _ in range(1000)]
456
457
# Step 1: Filter and enumerate with progress
458
print("Step 1: Filtering data...")
459
filtered_data = []
460
for i, value in tenumerate(raw_data, desc="Filtering"):
461
if value % 2 == 0: # Keep even numbers
462
filtered_data.append((i, value))
463
464
# Step 2: Pair with additional data
465
print("Step 2: Pairing with metadata...")
466
metadata = [f"meta_{i}" for i in range(len(filtered_data))]
467
468
paired_data = []
469
for (idx, val), meta in tzip(filtered_data, metadata, desc="Pairing"):
470
paired_data.append({
471
'original_index': idx,
472
'value': val,
473
'metadata': meta,
474
'processed': False
475
})
476
477
# Step 3: Apply transformations
478
print("Step 3: Applying transformations...")
479
def transform_item(item):
480
time.sleep(0.001) # Simulate processing
481
return {
482
**item,
483
'transformed_value': item['value'] * 2 + 10,
484
'processed': True
485
}
486
487
transformed_data = list(tmap(
488
transform_item,
489
paired_data,
490
desc="Transforming",
491
total=len(paired_data)
492
))
493
494
return transformed_data
495
496
# Run the pipeline
497
results = process_data_pipeline()
498
print(f"Processed {len(results)} items")
499
```
500
501
### Logging Integration
502
503
```python
504
from tqdm.contrib.logging import tqdm_logging_redirect
505
from tqdm.auto import tqdm
506
import logging
507
import time
508
509
# Setup logging
510
logging.basicConfig(
511
level=logging.INFO,
512
format='%(asctime)s - %(levelname)s - %(message)s'
513
)
514
logger = logging.getLogger(__name__)
515
516
def process_with_logging():
517
"""Example of processing with logging that doesn't interfere with progress bars"""
518
519
# Without tqdm_logging_redirect, log messages would interfere with progress bar
520
with tqdm_logging_redirect(total=100, desc="Processing with logging") as pbar:
521
for i in range(100):
522
# Simulate work
523
time.sleep(0.02)
524
525
# Log messages are redirected and won't interfere with progress bar
526
if i % 10 == 0:
527
logger.info(f"Processed {i} items")
528
529
if i % 25 == 0 and i > 0:
530
logger.warning(f"Checkpoint at {i} items")
531
532
pbar.update(1)
533
534
# After context exits, logging returns to normal
535
logger.info("Processing completed successfully")
536
537
# Run example
538
process_with_logging()
539
```
540
541
### Custom I/O Wrappers
542
543
```python
544
from tqdm.utils import CallbackIOWrapper, DisableOnWriteError
545
from tqdm.auto import tqdm
546
import io
547
import time
548
549
def file_processing_with_progress():
550
"""Example of file processing with progress tracking"""
551
552
# Create sample data
553
sample_data = "Sample line of data\n" * 10000
554
input_stream = io.StringIO(sample_data)
555
output_stream = io.StringIO()
556
557
# Calculate total size for progress tracking
558
total_size = len(sample_data)
559
560
# Create progress bar
561
pbar = tqdm(total=total_size, desc="Processing file", unit="B", unit_scale=True)
562
563
def update_callback(chunk_size):
564
"""Callback to update progress bar"""
565
pbar.update(chunk_size)
566
567
# Wrap input stream with callback
568
wrapped_input = CallbackIOWrapper(update_callback, input_stream, method="read")
569
570
# Process data with progress tracking
571
chunk_size = 1024
572
while True:
573
chunk = wrapped_input.read(chunk_size)
574
if not chunk:
575
break
576
577
# Simulate processing
578
processed_chunk = chunk.upper() # Simple transformation
579
output_stream.write(processed_chunk)
580
time.sleep(0.001) # Simulate processing time
581
582
pbar.close()
583
584
# Get results
585
result = output_stream.getvalue()
586
print(f"Processed {len(result)} characters")
587
588
return result
589
590
# Run file processing example
591
processed_data = file_processing_with_progress()
592
```
593
594
### Error-Resilient I/O
595
596
```python
597
from tqdm.utils import DisableOnWriteError
598
from tqdm.auto import tqdm
599
import sys
600
import io
601
602
def resilient_output_example():
603
"""Example of error-resilient output handling"""
604
605
# Create a stream that might fail
606
class UnreliableStream:
607
def __init__(self):
608
self.write_count = 0
609
610
def write(self, s):
611
self.write_count += 1
612
# Simulate occasional write failures
613
if self.write_count % 50 == 0:
614
raise IOError("Simulated write failure")
615
return len(s)
616
617
def flush(self):
618
pass
619
620
unreliable_stream = UnreliableStream()
621
622
# Wrap with error-resilient wrapper
623
safe_stream = DisableOnWriteError(unreliable_stream)
624
625
# Use with tqdm - progress bar will automatically disable on write errors
626
try:
627
for i in tqdm(range(200), desc="Resilient output", file=safe_stream):
628
time.sleep(0.01)
629
except Exception as e:
630
print(f"Caught exception: {e}")
631
632
print("Processing completed (progress bar may have been disabled due to write errors)")
633
634
# Run resilient output example
635
resilient_output_example()
636
```
637
638
### Custom Display Formatting
639
640
```python
641
from tqdm.utils import FormatReplace, disp_len, disp_trim
642
from tqdm.auto import tqdm
643
import time
644
645
def custom_formatting_example():
646
"""Example of custom progress bar formatting"""
647
648
# Custom format with replaceable fields
649
custom_format = FormatReplace(
650
"Processing: {percentage:3.0f}% |{bar}| {n_fmt}/{total_fmt} "
651
"[{elapsed}<{remaining}, {rate_fmt}] {custom_field}"
652
)
653
654
# Progress with custom formatting
655
pbar = tqdm(total=100, desc="Custom Format")
656
657
for i in range(100):
658
time.sleep(0.02)
659
660
# Update progress with custom field
661
custom_info = f"Step_{i//10}"
662
pbar.set_postfix_str(f"Stage: {custom_info}")
663
pbar.update(1)
664
665
pbar.close()
666
667
# Demonstrate text measurement and trimming
668
long_text = "This is a very long text that might not fit in the available space"
669
display_width = 30
670
671
print(f"Original text length: {len(long_text)}")
672
print(f"Display length: {disp_len(long_text)}")
673
674
trimmed_text = disp_trim(long_text, display_width)
675
print(f"Trimmed text: '{trimmed_text}'")
676
print(f"Trimmed display length: {disp_len(trimmed_text)}")
677
678
# Run custom formatting example
679
custom_formatting_example()
680
```
681
682
### Environment Configuration
683
684
```python
685
from tqdm.utils import envwrap
686
from tqdm.auto import tqdm
687
import os
688
import time
689
690
# Example of environment-configurable function
691
@envwrap('MYTQDM_')
692
def configurable_progress(iterable, desc="Processing", **kwargs):
693
"""Function that can be configured via environment variables"""
694
# Environment variables like MYTQDM_NCOLS, MYTQDM_ASCII, etc.
695
# will automatically override default values
696
return tqdm(iterable, desc=desc, **kwargs)
697
698
def environment_config_example():
699
"""Example of environment-based configuration"""
700
701
# Set some environment variables for testing
702
os.environ['MYTQDM_NCOLS'] = '50'
703
os.environ['MYTQDM_ASCII'] = 'True'
704
os.environ['MYTQDM_COLOUR'] = 'green'
705
706
# Use the configurable function
707
data = range(100)
708
for item in configurable_progress(data, desc="Env Configured"):
709
time.sleep(0.01)
710
711
# Clean up environment variables
712
for key in ['MYTQDM_NCOLS', 'MYTQDM_ASCII', 'MYTQDM_COLOUR']:
713
os.environ.pop(key, None)
714
715
# Run environment configuration example
716
environment_config_example()
717
```
718
719
### External Service Notifications Usage
720
721
```python
722
from tqdm.contrib.slack import tqdm_slack
723
from tqdm.contrib.discord import tqdm_discord
724
from tqdm.contrib.telegram import tqdm_telegram
725
import time
726
import os
727
728
def notification_examples():
729
"""Examples of using external service notifications"""
730
731
# Slack integration example
732
if os.getenv('SLACK_TOKEN') and os.getenv('SLACK_CHANNEL'):
733
print("Running with Slack notifications...")
734
for i in tqdm_slack(
735
range(100),
736
desc="Processing with Slack",
737
token=os.getenv('SLACK_TOKEN'),
738
channel=os.getenv('SLACK_CHANNEL')
739
):
740
time.sleep(0.1)
741
742
# Discord integration example
743
if os.getenv('DISCORD_WEBHOOK'):
744
print("Running with Discord notifications...")
745
for i in tqdm_discord(
746
range(50),
747
desc="Processing with Discord",
748
token=os.getenv('DISCORD_WEBHOOK')
749
):
750
time.sleep(0.2)
751
752
# Telegram integration example
753
if os.getenv('TELEGRAM_TOKEN') and os.getenv('TELEGRAM_CHAT_ID'):
754
print("Running with Telegram notifications...")
755
for i in tqdm_telegram(
756
range(75),
757
desc="Processing with Telegram",
758
token=os.getenv('TELEGRAM_TOKEN'),
759
chat_id=os.getenv('TELEGRAM_CHAT_ID')
760
):
761
time.sleep(0.15)
762
763
# Run notification examples (only if environment variables are set)
764
notification_examples()
765
```
766
767
### CLI Usage Examples
768
769
```python
770
import subprocess
771
import os
772
773
def cli_examples():
774
"""Examples of using tqdm CLI in shell pipelines"""
775
776
# Basic pipe usage
777
cmd1 = "seq 1000 | python -m tqdm --desc 'Counting' --unit 'numbers'"
778
print(f"Running: {cmd1}")
779
subprocess.run(cmd1, shell=True)
780
781
# Byte counting with progress
782
cmd2 = "cat /dev/zero | head -c 10MB | python -m tqdm --bytes --desc 'Reading bytes'"
783
print(f"Running: {cmd2}")
784
subprocess.run(cmd2, shell=True)
785
786
# Custom formatting
787
cmd3 = "seq 500 | python -m tqdm --desc 'Custom' --ncols 50 --ascii"
788
print(f"Running: {cmd3}")
789
subprocess.run(cmd3, shell=True)
790
791
# Progress updates from external source
792
cmd4 = "echo -e '10\\n20\\n30\\n40\\n50' | python -m tqdm --update --total 50"
793
print(f"Running: {cmd4}")
794
subprocess.run(cmd4, shell=True)
795
796
# Uncomment to run CLI examples
797
# cli_examples()
798
```
799
800
### Terminal Capability Detection
801
802
```python
803
from tqdm.utils import _supports_unicode, _is_ascii, _screen_shape_wrapper, _term_move_up
804
import sys
805
806
def terminal_capabilities_demo():
807
"""Demonstrate terminal capability detection"""
808
809
print("Terminal Capability Detection:")
810
print(f"Unicode support: {_supports_unicode(sys.stderr)}")
811
print(f"Screen dimensions: {_screen_shape_wrapper()}")
812
813
# Test ASCII detection
814
test_strings = [
815
"Hello World",
816
"Hello π",
817
"Progress: ββββββ",
818
"Progress: ======",
819
]
820
821
for test_str in test_strings:
822
is_ascii = _is_ascii(test_str)
823
display_length = disp_len(test_str)
824
print(f"'{test_str}': ASCII={is_ascii}, Display length={display_length}")
825
826
# Demonstrate cursor movement (be careful with this in production)
827
print("\nDemonstrating cursor movement:")
828
print("Line 1")
829
print("Line 2")
830
print("Line 3")
831
832
# Move cursor up and overwrite
833
move_sequence = _term_move_up()
834
if move_sequence:
835
sys.stderr.write(move_sequence)
836
sys.stderr.write("Overwritten Line 3\n")
837
838
# Run terminal capabilities demo
839
terminal_capabilities_demo()
840
```
841
842
## Integration Patterns
843
844
### Creating Custom Extensions
845
846
```python
847
from tqdm.utils import ObjectWrapper
848
from tqdm.auto import tqdm
849
850
class CustomTqdmExtension(ObjectWrapper):
851
"""Example of creating a custom tqdm extension"""
852
853
def __init__(self, wrapped_tqdm, custom_config=None):
854
super().__init__(wrapped_tqdm)
855
self.custom_config = custom_config or {}
856
self.custom_stats = {'custom_counter': 0}
857
858
def update(self, n=1):
859
"""Override update to add custom functionality"""
860
result = super().update(n)
861
self.custom_stats['custom_counter'] += n
862
863
# Custom logic based on progress
864
if self.custom_stats['custom_counter'] % 100 == 0:
865
self.set_postfix({
866
'milestone': self.custom_stats['custom_counter']
867
})
868
869
return result
870
871
def get_custom_stats(self):
872
"""Provide access to custom statistics"""
873
return self.custom_stats.copy()
874
875
# Usage example
876
def custom_extension_example():
877
base_pbar = tqdm(total=1000, desc="Custom Extension")
878
custom_pbar = CustomTqdmExtension(base_pbar, {'threshold': 100})
879
880
for i in range(1000):
881
custom_pbar.update(1)
882
time.sleep(0.001)
883
884
stats = custom_pbar.get_custom_stats()
885
print(f"Custom stats: {stats}")
886
custom_pbar.close()
887
888
# Run custom extension example
889
custom_extension_example()
890
```
891
892
## Best Practices
893
894
### Performance Considerations
895
- Use utilities sparingly in performance-critical code
896
- Cache terminal capability detection results
897
- Consider overhead of callback functions in I/O wrappers
898
899
### Error Handling
900
- Always use error-resilient wrappers in production
901
- Implement graceful fallbacks for terminal detection failures
902
- Handle encoding issues in text I/O wrappers
903
904
### Customization Guidelines
905
- Extend existing classes rather than reimplementing
906
- Use environment variables for user-configurable options
907
- Maintain compatibility with standard tqdm interfaces