2929)
3030from .terminal import os_specific
3131
32- if typing .TYPE_CHECKING :
33- # Imported lazily at runtime (see the local imports in the full-bar
34- # methods below) so the lean fast path and a bare `import progressbar`
35- # don't pull in the widgets module (and its terminal/colour tables).
36- from . import widgets as widgets_module
37-
3832try :
3933 # Optional native accelerator, shipped as the ``progressbar2[fast]`` extra
4034 # (the separate ``speedups`` package). When importable, the iterator path
4741except Exception : # pragma: no cover - environmental (absent / ABI mismatch)
4842 _FastBarIterator = None
4943
44+
45+ def _load_widgets () -> typing .Any :
46+ """Import the widgets module lazily.
47+
48+ The full-bar code needs ``widgets``, but the lean fast path must not pull
49+ it in (it drags the terminal/colour tables). Imported via importlib so the
50+ deferred load doesn't read as a static ``bar -> widgets`` import cycle.
51+ """
52+ return importlib .import_module ('progressbar.widgets' )
53+
54+
5055logger = logging .getLogger (__name__ )
5156
5257# float also accepts integers and longs but we don't want an explicit union
@@ -66,7 +71,9 @@ class ProgressBarMixinBase(abc.ABC):
6671 #: fall back to 80 if auto detection is not possible.
6772 term_width : int = 80
6873 #: The widgets to render, defaults to the result of `default_widget()`
69- widgets : types .MutableSequence [widgets_module .WidgetBase | str ]
74+ #: (typed loosely as Any to avoid a static bar->widgets import cycle; the
75+ #: public ``progressbar()`` shortcut keeps the precise WidgetBase typing).
76+ widgets : types .MutableSequence [typing .Any ]
7077 #: When going beyond the max_value, raise an error if True or silently
7178 #: ignore otherwise
7279 max_error : bool
@@ -367,7 +374,7 @@ def _format_line(self):
367374 return widgets .rjust (self .term_width )
368375
369376 def _format_widgets (self ):
370- from . import widgets
377+ widgets = _load_widgets ()
371378
372379 result = []
373380 expanding = []
@@ -654,9 +661,7 @@ def __init__(
654661 self ,
655662 min_value : NumberT = 0 ,
656663 max_value : ValueT = None ,
657- widgets : types .Optional [
658- types .Sequence [widgets_module .WidgetBase | str ]
659- ] = None ,
664+ widgets : types .Optional [types .Sequence [typing .Any ]] = None ,
660665 left_justify : bool = True ,
661666 initial_value : NumberT = 0 ,
662667 poll_interval : types .Optional [float ] = None ,
@@ -748,7 +753,7 @@ def __init__(
748753 # A dictionary of names that can be used by Variable and FormatWidget
749754 self .variables = utils .AttributeDict (variables or {})
750755 if self .widgets :
751- from . import widgets as widgets_module
756+ widgets_module = _load_widgets ()
752757
753758 for widget in self .widgets :
754759 if (
@@ -910,7 +915,7 @@ def data(self) -> types.Dict[str, types.Any]:
910915 )
911916
912917 def default_widgets (self ):
913- from . import widgets
918+ widgets = _load_widgets ()
914919
915920 if self .max_value :
916921 return [
@@ -1302,7 +1307,7 @@ def start(
13021307
13031308 def _init_suffix (self ):
13041309 if self .suffix :
1305- from . import widgets
1310+ widgets = _load_widgets ()
13061311
13071312 self .widgets .append (
13081313 widgets .FormatLabel (self .suffix , new_style = True ),
@@ -1313,7 +1318,7 @@ def _init_suffix(self):
13131318
13141319 def _init_prefix (self ):
13151320 if self .prefix :
1316- from . import widgets
1321+ widgets = _load_widgets ()
13171322
13181323 self .widgets .insert (
13191324 0 ,
@@ -1391,7 +1396,7 @@ class DataTransferBar(ProgressBar):
13911396 """
13921397
13931398 def default_widgets (self ):
1394- from . import widgets
1399+ widgets = _load_widgets ()
13951400
13961401 if self .max_value :
13971402 return [
0 commit comments