11from __future__ import annotations
22
33import abc
4+ import contextlib
45import itertools
56import logging
67import math
@@ -159,6 +160,9 @@ class DefaultFdMixin(ProgressBarMixinBase):
159160 #: compatible we will automatically enable `colors` and disable
160161 #: `line_breaks`.
161162 is_ansi_terminal : bool = False
163+ #: Whether the file descriptor is a terminal or not. This is used to
164+ #: determine whether to use ANSI escape codes or not.
165+ is_terminal : bool
162166 #: Whether to print line breaks. This is useful for logging the
163167 #: progressbar. When disabled the current line is overwritten.
164168 line_breaks : bool = True
@@ -175,13 +179,13 @@ class DefaultFdMixin(ProgressBarMixinBase):
175179 enable_colors : terminal .ColorSupport | bool | None = terminal .color_support
176180
177181 def __init__ (
178- self ,
179- fd : base .IO = sys .stderr ,
180- is_terminal : bool | None = None ,
181- line_breaks : bool | None = None ,
182- enable_colors : terminal .ColorSupport | None = None ,
183- line_offset : int = 0 ,
184- ** kwargs ,
182+ self ,
183+ fd : base .IO = sys .stderr ,
184+ is_terminal : bool | None = None ,
185+ line_breaks : bool | None = None ,
186+ enable_colors : terminal .ColorSupport | None = None ,
187+ line_offset : int = 0 ,
188+ ** kwargs ,
185189 ):
186190 if fd is sys .stdout :
187191 fd = utils .streams .original_stdout
@@ -201,15 +205,15 @@ def _apply_line_offset(self, fd: base.IO, line_offset: int) -> base.IO:
201205 if line_offset :
202206 return progressbar .terminal .stream .LineOffsetStreamWrapper (
203207 line_offset ,
204- fd ,
208+ types . cast ( base . TextIO , fd ) ,
205209 )
206210 else :
207211 return fd
208212
209213 def _determine_is_terminal (
210- self ,
211- fd : base .IO ,
212- is_terminal : bool | None ,
214+ self ,
215+ fd : base .IO ,
216+ is_terminal : bool | None ,
213217 ) -> bool :
214218 if is_terminal is not None :
215219 return utils .is_terminal (fd , is_terminal )
@@ -226,8 +230,8 @@ def _determine_line_breaks(self, line_breaks: bool | None) -> bool:
226230 return bool (line_breaks )
227231
228232 def _determine_enable_colors (
229- self ,
230- enable_colors : terminal .ColorSupport | None ,
233+ self ,
234+ enable_colors : terminal .ColorSupport | None ,
231235 ) -> terminal .ColorSupport :
232236 if enable_colors is None :
233237 colors = (
@@ -243,6 +247,10 @@ def _determine_enable_colors(
243247 else :
244248 enable_colors = terminal .ColorSupport .NONE
245249 break
250+ else : # pragma: no cover
251+ # This scenario should never occur because `is_ansi_terminal`
252+ # should always be `True` or `False`
253+ raise ValueError ('Unable to determine color support' )
246254
247255 elif enable_colors is True :
248256 enable_colors = terminal .ColorSupport .XTERM_256
@@ -253,10 +261,10 @@ def _determine_enable_colors(
253261
254262 return enable_colors
255263
256- def print (self , * args , ** kwargs ) :
264+ def print (self , * args : types . Any , ** kwargs : types . Any ) -> None :
257265 print (* args , file = self .fd , ** kwargs )
258266
259- def update (self , * args , ** kwargs ) :
267+ def update (self , * args : types . Any , ** kwargs : types . Any ) -> None :
260268 ProgressBarMixinBase .update (self , * args , ** kwargs )
261269
262270 line : str = converters .to_unicode (self ._format_line ())
@@ -270,7 +278,9 @@ def update(self, *args, **kwargs):
270278 except UnicodeEncodeError : # pragma: no cover
271279 self .fd .write (line .encode ('ascii' , 'replace' ))
272280
273- def finish (self , * args , ** kwargs ): # pragma: no cover
281+ def finish (
282+ self , * args : types .Any , ** kwargs : types .Any
283+ ) -> None : # pragma: no cover
274284 if self ._finished :
275285 return
276286
@@ -299,8 +309,8 @@ def _format_widgets(self):
299309
300310 for index , widget in enumerate (self .widgets ):
301311 if isinstance (
302- widget ,
303- widgets .WidgetBase ,
312+ widget ,
313+ widgets .WidgetBase ,
304314 ) and not widget .check_size (self ):
305315 continue
306316 elif isinstance (widget , widgets .AutoWidthWidgetBase ):
@@ -341,15 +351,13 @@ def __init__(self, term_width: int | None = None, **kwargs):
341351 if term_width :
342352 self .term_width = term_width
343353 else : # pragma: no cover
344- try :
354+ with contextlib . suppress ( Exception ) :
345355 self ._handle_resize ()
346356 import signal
347357
348358 self ._prev_handle = signal .getsignal (signal .SIGWINCH )
349359 signal .signal (signal .SIGWINCH , self ._handle_resize )
350360 self .signal_set = True
351- except Exception :
352- pass
353361
354362 def _handle_resize (self , signum = None , frame = None ):
355363 'Tries to catch resize signals sent from the terminal.'
@@ -359,12 +367,10 @@ def _handle_resize(self, signum=None, frame=None):
359367 def finish (self ): # pragma: no cover
360368 ProgressBarMixinBase .finish (self )
361369 if self .signal_set :
362- try :
370+ with contextlib . suppress ( Exception ) :
363371 import signal
364372
365373 signal .signal (signal .SIGWINCH , self ._prev_handle )
366- except Exception : # pragma no cover
367- pass
368374
369375
370376class StdRedirectMixin (DefaultFdMixin ):
@@ -376,10 +382,10 @@ class StdRedirectMixin(DefaultFdMixin):
376382 _stderr : base .IO
377383
378384 def __init__ (
379- self ,
380- redirect_stderr : bool = False ,
381- redirect_stdout : bool = False ,
382- ** kwargs ,
385+ self ,
386+ redirect_stderr : bool = False ,
387+ redirect_stdout : bool = False ,
388+ ** kwargs ,
383389 ):
384390 DefaultFdMixin .__init__ (self , ** kwargs )
385391 self .redirect_stderr = redirect_stderr
@@ -507,24 +513,24 @@ class ProgressBar(
507513 paused : bool = False
508514
509515 def __init__ (
510- self ,
511- min_value : T = 0 ,
512- max_value : T | types .Type [base .UnknownLength ] | None = None ,
513- widgets : types .Optional [
514- types .Sequence [widgets_module .WidgetBase | str ]
515- ] = None ,
516- left_justify : bool = True ,
517- initial_value : T = 0 ,
518- poll_interval : types .Optional [float ] = None ,
519- widget_kwargs : types .Optional [types .Dict [str , types .Any ]] = None ,
520- custom_len : types .Callable [[str ], int ] = utils .len_color ,
521- max_error = True ,
522- prefix = None ,
523- suffix = None ,
524- variables = None ,
525- min_poll_interval = None ,
526- ** kwargs ,
527- ):
516+ self ,
517+ min_value : T = 0 ,
518+ max_value : T | types .Type [base .UnknownLength ] | None = None ,
519+ widgets : types .Optional [
520+ types .Sequence [widgets_module .WidgetBase | str ]
521+ ] = None ,
522+ left_justify : bool = True ,
523+ initial_value : T = 0 ,
524+ poll_interval : types .Optional [float ] = None ,
525+ widget_kwargs : types .Optional [types .Dict [str , types .Any ]] = None ,
526+ custom_len : types .Callable [[str ], int ] = utils .len_color ,
527+ max_error = True ,
528+ prefix = None ,
529+ suffix = None ,
530+ variables = None ,
531+ min_poll_interval = None ,
532+ ** kwargs ,
533+ ): # sourcery skip: low-code-quality
528534 '''Initializes a progress bar with sane defaults.'''
529535 StdRedirectMixin .__init__ (self , ** kwargs )
530536 ResizableMixin .__init__ (self , ** kwargs )
@@ -547,7 +553,7 @@ def __init__(
547553 )
548554 poll_interval = kwargs .get ('poll' )
549555
550- if max_value and min_value > max_value :
556+ if max_value and min_value > types . cast ( T , max_value ) :
551557 raise ValueError (
552558 'Max value needs to be bigger than the min value' ,
553559 )
@@ -588,8 +594,8 @@ def __init__(
588594 default = None ,
589595 )
590596 self ._MINIMUM_UPDATE_INTERVAL = (
591- utils .deltas_to_seconds (self ._MINIMUM_UPDATE_INTERVAL )
592- or self ._MINIMUM_UPDATE_INTERVAL
597+ utils .deltas_to_seconds (self ._MINIMUM_UPDATE_INTERVAL )
598+ or self ._MINIMUM_UPDATE_INTERVAL
593599 )
594600
595601 # Note that the _MINIMUM_UPDATE_INTERVAL sets the minimum in case of
@@ -604,8 +610,10 @@ def __init__(
604610 # A dictionary of names that can be used by Variable and FormatWidget
605611 self .variables = utils .AttributeDict (variables or {})
606612 for widget in self .widgets :
607- if isinstance (widget , widgets_module .VariableMixin ) \
608- and widget .name not in self .variables :
613+ if (
614+ isinstance (widget , widgets_module .VariableMixin )
615+ and widget .name not in self .variables
616+ ):
609617 self .variables [widget .name ] = None
610618
611619 @property
@@ -725,7 +733,7 @@ def data(self) -> types.Dict[str, types.Any]:
725733 total_seconds_elapsed = total_seconds_elapsed ,
726734 # The seconds since the bar started modulo 60
727735 seconds_elapsed = (elapsed .seconds % 60 )
728- + (elapsed .microseconds / 1000000.0 ),
736+ + (elapsed .microseconds / 1000000.0 ),
729737 # The minutes since the bar started modulo 60
730738 minutes_elapsed = (elapsed .seconds / 60 ) % 60 ,
731739 # The hours since the bar started modulo 24
@@ -840,16 +848,12 @@ def _needs_update(self):
840848 # Update if value increment is not large enough to
841849 # add more bars to progressbar (according to current
842850 # terminal width)
843- try :
851+ with contextlib . suppress ( Exception ) :
844852 divisor : float = self .max_value / self .term_width # type: ignore
845853 value_divisor = self .value // divisor # type: ignore
846854 pvalue_divisor = self .previous_value // divisor # type: ignore
847855 if value_divisor != pvalue_divisor :
848856 return True
849- except Exception :
850- # ignore any division errors
851- pass
852-
853857 # No need to redraw yet
854858 return False
855859
@@ -859,22 +863,24 @@ def update(self, value=None, force=False, **kwargs):
859863 self .start ()
860864
861865 if (
862- value is not None
863- and value is not base .UnknownLength
864- and isinstance (value , int )
866+ value is not None
867+ and value is not base .UnknownLength
868+ and isinstance (value , int )
865869 ):
866870 if self .max_value is base .UnknownLength :
867871 # Can't compare against unknown lengths so just update
868872 pass
869873 elif self .min_value > value : # type: ignore
870874 raise ValueError (
871875 f'Value { value } is too small. Should be '
872- f'between { self .min_value } and { self .max_value } ' )
876+ f'between { self .min_value } and { self .max_value } '
877+ )
873878 elif self .max_value < value : # type: ignore
874879 if self .max_error :
875880 raise ValueError (
876881 f'Value { value } is too large. Should be between '
877- f'{ self .min_value } and { self .max_value } ' )
882+ f'{ self .min_value } and { self .max_value } '
883+ )
878884 else :
879885 value = self .max_value
880886
@@ -982,9 +988,9 @@ def _init_prefix(self):
982988
983989 def _verify_max_value (self ):
984990 if (
985- self .max_value is not base .UnknownLength
986- and self .max_value is not None
987- and self .max_value < 0 # type: ignore
991+ self .max_value is not base .UnknownLength
992+ and self .max_value is not None
993+ and self .max_value < 0 # type: ignore
988994 ):
989995 raise ValueError ('max_value out of range, got %r' % self .max_value )
990996
0 commit comments