1111from multibar .interfaces .containers import AbstractSeqBasedContainerMixin
1212from multibar .interfaces .customer import AbstractCustomerMixin
1313from multibar .interfaces .product import AbstractSectorMixin
14- from multibar .internal .crate import (
15- ProgressbarContainer ,
16- ProgressContainer ,
17- SectorContainer ,
18- )
14+ from multibar .internal .crate import ProgressbarContainer
15+ from multibar .internal .crate import ProgressContainer
16+ from multibar .internal .crate import SectorContainer
1917from multibar .internal .factories import SphinxSectorFactory
2018from multibar .internal .product import Sector
2119from multibar .pytypes import NoneType , NotImplementedType
20+ from multibar .internal .sentinel import MissingOr , MISSING , Sentinel
2221
2322_AbcSectorT_co = TypeVar ("_AbcSectorT_co" , bound = AbstractSectorMixin , covariant = True )
2423_AbcContainerT_co = TypeVar ("_AbcContainerT_co" , bound = AbstractSeqBasedContainerMixin [Any ], covariant = True )
@@ -54,15 +53,15 @@ class ProgressBar(Generic[_AbcSectorT_co, _AbcContainerT_co]):
5453 length: :class:`int` = 20
5554 Length of progress bar.
5655
57- sector_cls: :class:`Optional [Type[AbstractSectorMixin]]` = None
56+ sector_cls: :class:`MissingOr [Type[AbstractSectorMixin]]` = MISSING
5857 Custom Sector implementation.
5958
6059 For more information and examples see:
6160 https://animatea.github.io/python-multibar/abc/?h=abstractsectormixin
6261
63- container_cls: :class:`Optional [
62+ container_cls: :class:`MissingOr [
6463 Type[AbstractSeqBasedContainerMixin[AbstractSectorMixin]]
65- ] = None `
64+ ] = MISSING `
6665 Custom container implementation.
6766
6867 For more information and examples see:
@@ -72,19 +71,19 @@ class ProgressBar(Generic[_AbcSectorT_co, _AbcContainerT_co]):
7271 current : int
7372 total : int
7473 length : int = 20
75- sector_cls : Optional [Type [_AbcSectorT_co ]] = None
76- container_cls : Optional [Type [_AbcContainerT_co ]] = None
74+ sector_cls : MissingOr [Type [_AbcSectorT_co ]] = MISSING
75+ container_cls : MissingOr [Type [_AbcContainerT_co ]] = MISSING
7776
7877 def __post_init__ (self ) -> None :
7978 assert self .current >= 0 , "Current progress cannot be less than 0."
8079 assert self .current <= self .total , "Current progress cannot be more than total progress."
8180
82- if self .container_cls is None :
81+ if self .container_cls is MISSING :
8382 self .container_cls = SectorContainer # type: ignore[assignment]
8483
8584 self .factory : SphinxSectorFactory [AbstractSectorMixin ] = SphinxSectorFactory .from_bind (
8685 sector_type = cast (
87- Type [AbstractSectorMixin ], Sector if self .sector_cls is None else self .sector_cls
86+ Type [AbstractSectorMixin ], Sector if self .sector_cls is MISSING else self .sector_cls
8887 )
8988 )
9089
@@ -93,10 +92,10 @@ def write_progress(
9392 * args : Any ,
9493 fill : str ,
9594 line : str ,
96- start : Optional [str ] = None ,
97- unfilled_start : Optional [str ] = None ,
98- end : Optional [str ] = None ,
99- unfilled_end : Optional [str ] = None ,
95+ start : MissingOr [str ] = MISSING ,
96+ unfilled_start : MissingOr [str ] = MISSING ,
97+ end : MissingOr [str ] = MISSING ,
98+ unfilled_end : MissingOr [str ] = MISSING ,
10099 ** kwargs : Any ,
101100 ) -> ProgressbarContainer [_AbcSectorT_co ]:
102101 # TODO: Maybe adapter?
@@ -122,16 +121,16 @@ def write_progress(
122121 !!! Abstract:
123122 This symbol is used on last (second) fill (depending on progress).
124123
125- start: :class:`Optional [str]` = None
124+ start: :class:`MissingOr [str]` = MISSING
126125 If passed, will replace first FILLED emoji of progress bar (depending on progress).
127126
128- unfilled_start: :class:`Optional [str]` = None
127+ unfilled_start: :class:`MissingOr [str]` = MISSING
129128 If passed, will replace first EMPTY emoji of progress bar (depending on progress).
130129
131- end: :class:`Optional [str]` = None
130+ end: :class:`MissingOr [str]` = MISSING
132131 If passed, will replace last FILLED emoji of progress bar (depending on progress).
133132
134- unfilled_end: :class:`Optional [str]` = None
133+ unfilled_end: :class:`MissingOr [str]` = MISSING
135134 If passed, will replace last EMPTY emoji of progress bar (depending on progress).
136135
137136 **kwargs: :class:`Any`
@@ -142,7 +141,7 @@ def write_progress(
142141 """
143142 progress = ProgressContainer (self .current , self .total )
144143 percents = progress .percents (allow_float = False )
145- assert self .container_cls is not None
144+ assert self .container_cls is not MISSING
146145
147146 with self .container_cls () as container :
148147 for i in range (rest := (round (percents / (100 / self .length )))):
@@ -168,21 +167,21 @@ def write_progress(
168167 )
169168
170169 # Add `unfilled_start` if it is specified and none of the sectors is yet filled.
171- if unfilled_start is not None and percents < FillFlag .FIRST :
170+ if unfilled_start is not MISSING and percents < FillFlag .FIRST :
172171 container [0 ].name = unfilled_start
173172
174173 # Otherwise, if `start` is specified, it will be added to the beginning.
175- elif percents >= FillFlag .FIRST and start is not None :
174+ elif percents >= FillFlag .FIRST and start is not MISSING :
176175 container [0 ].name = start
177176
178177 # If `unfilled_end` is specified and the last sector is not filled, then the
179178 # corresponding character will be added to the end of the progress bar.
180- if unfilled_end is not None and percents < FillFlag .LAST :
179+ if unfilled_end is not MISSING and percents < FillFlag .LAST :
181180 container [- 1 ].name = unfilled_end
182181
183182 # Otherwise, if end is specified, the character corresponding to the
184183 # given argument will be appended to the end of the progressbar.
185- elif percents >= FillFlag .LAST and end is not None :
184+ elif percents >= FillFlag .LAST and end is not MISSING :
186185 container [- 1 ].name = end
187186
188187 return ProgressbarContainer (
@@ -196,11 +195,11 @@ async def async_write_progress(
196195 * args : Any ,
197196 fill : str ,
198197 line : str ,
199- start : Optional [str ] = None ,
200- unfilled_start : Optional [str ] = None ,
201- end : Optional [str ] = None ,
202- unfilled_end : Optional [str ] = None ,
203- loop : Optional [asyncio .AbstractEventLoop ] = None ,
198+ start : Optional [str ] = MISSING ,
199+ unfilled_start : Optional [str ] = MISSING ,
200+ end : Optional [str ] = MISSING ,
201+ unfilled_end : Optional [str ] = MISSING ,
202+ loop : Optional [asyncio .AbstractEventLoop ] = MISSING ,
204203 ** kwargs : Any ,
205204 ) -> Coroutine [ProgressbarContainer [_AbcSectorT_co ], None , None ]:
206205 """``sync method``
@@ -224,19 +223,19 @@ async def async_write_progress(
224223 !!! Abstract:
225224 This symbol is used on last (second) fill (depending on progress).
226225
227- start: :class:`Optional [str]` = None
226+ start: :class:`MissingOr [str]` = MISSING
228227 If passed, will replace first FILLED emoji of progress bar (depending on progress).
229228
230- unfilled_start: :class:`Optional [str]` = None
229+ unfilled_start: :class:`MissingOr [str]` = MISSING
231230 If passed, will replace first EMPTY emoji of progress bar (depending on progress).
232231
233- end: :class:`Optional [str]` = None
232+ end: :class:`MissingOr [str]` = MISSING
234233 If passed, will replace last FILLED emoji of progress bar (depending on progress).
235234
236- unfilled_end: :class:`Optional [str]` = None
235+ unfilled_end: :class:`MissingOr [str]` = MISSING
237236 If passed, will replace last EMPTY emoji of progress bar (depending on progress).
238237
239- loop: :class:`Optional [asyncio.AbstractEventLoop]` = None
238+ loop: :class:`MissingOr [asyncio.AbstractEventLoop]` = MISSING
240239 Event loop that used for creating awaitable object and further run in executor.
241240
242241 **kwargs: :class:`Any`
@@ -245,7 +244,7 @@ async def async_write_progress(
245244 For more information and examples see:
246245 https://animatea.github.io/python-multibar/abc/?h=abstractseqbasedcontainermixin
247246 """
248- if loop is None :
247+ if loop is MISSING :
249248 loop = asyncio .get_event_loop ()
250249
251250 return cast (
@@ -296,7 +295,7 @@ def write_from_customer(
296295 kwargs_new = {}
297296 for as_str in AbstractCustomerMixin .__abstractmethods__ :
298297 progress_char = getattr (customer , as_str )(customer , ctx )
299- if not isinstance (progress_char , (NotImplementedType , NoneType )):
298+ if not isinstance (progress_char , (Sentinel , NotImplementedType , NoneType )):
300299 kwargs_new [as_str ] = progress_char
301300
302301 kwargs .update (kwargs_new )
@@ -306,7 +305,7 @@ async def async_write_from_customer(
306305 self ,
307306 * args : Any ,
308307 customer : Type [AbstractCustomerMixin ],
309- loop : Optional [asyncio .AbstractEventLoop ] = None ,
308+ loop : MissingOr [asyncio .AbstractEventLoop ] = MISSING ,
310309 ** kwargs : Any ,
311310 ) -> Coroutine [ProgressbarContainer [_AbcSectorT_co ], None , None ]:
312311 """``sync method``
@@ -323,7 +322,7 @@ async def async_write_from_customer(
323322 customer: :class:`Type[AbstractCustomerMixin]`
324323 Customer implementation class.
325324
326- loop: :class:`Optional [asyncio.AbstractEventLoop]` = None
325+ loop: :class:`MissingOr [asyncio.AbstractEventLoop]` = MISSING
327326 Event loop that used for creating awaitable object and further run in executor.
328327
329328 **kwargs: :class:`Any`
@@ -332,7 +331,7 @@ async def async_write_from_customer(
332331 For more information and examples see:
333332 https://animatea.github.io/python-multibar/abc/?h=abstractseqbasedcontainermixin
334333 """
335- if loop is None :
334+ if loop is MISSING :
336335 loop = asyncio .get_event_loop ()
337336
338337 return cast (
0 commit comments