11from __future__ import annotations
22
3+ import dataclasses
34import warnings
45from typing import (
56 Any ,
67 Dict ,
7- Iterable ,
8+ FrozenSet ,
89 Optional ,
910 Tuple ,
1011 Union ,
1314from coloredstrings import color_support , stylize , types , utils
1415
1516
17+ @dataclasses .dataclass (frozen = True )
1618class StyleBuilder :
17- def __init__ (
18- self ,
19- fg : Optional [types .Color ] = None ,
20- bg : Optional [types .Color ] = None ,
21- attrs : Iterable [types .Attribute ] = (),
22- next_color_for_bg : bool = False ,
23- mode : Optional [types .ColorMode ] = None ,
24- visible_if_colors : bool = False ,
25- extensions : Optional [
26- Dict [str , Union [str , Tuple [int , int , int ], StyleBuilder ]]
27- ] = None ,
28- ) -> None :
29- self .fg = fg
30- self .bg = bg
31- self .attrs = frozenset (attrs )
32- self .next_color_for_bg = next_color_for_bg
33- self .mode = mode
34- self .visible_if_colors = visible_if_colors
35- self .extensions = {} if extensions is None else extensions
19+ fg : Optional [types .Color ] = None
20+ """Foreground color."""
21+
22+ bg : Optional [types .Color ] = None
23+ """Background color."""
24+
25+ attrs : FrozenSet [types .Attribute ] = dataclasses .field (default_factory = frozenset )
26+ """Styling attributes (bold, italic, etc.)."""
27+
28+ next_color_for_bg : bool = False
29+ """Whether the next `color` method should be treated as setting the background color."""
30+
31+ mode : Optional [types .ColorMode ] = None
32+ """Color mode."""
33+
34+ visible_if_colors : bool = False
35+ """Used for `visible` style: whether the text should be replaced with an empty string when colors are not available."""
36+
37+ # This annotation hurts me very much...
38+ extensions : Dict [str , Union [str , Tuple [int , int , int ], StyleBuilder ]] = (
39+ dataclasses .field (default_factory = dict )
40+ )
41+ """User-defined extension styles."""
3642
3743 def __call__ (
3844 self ,
@@ -56,27 +62,11 @@ def __call__(
5662 )
5763
5864 def color_mode (self , mode : types .ColorMode ) -> StyleBuilder :
59- return StyleBuilder (
60- fg = self .fg ,
61- bg = self .bg ,
62- attrs = self .attrs ,
63- next_color_for_bg = self .next_color_for_bg ,
64- mode = mode ,
65- visible_if_colors = self .visible_if_colors ,
66- extensions = self .extensions ,
67- )
65+ return dataclasses .replace (self , mode = mode )
6866
6967 @property
7068 def on (self ) -> StyleBuilder :
71- return StyleBuilder (
72- fg = self .fg ,
73- bg = self .bg ,
74- attrs = self .attrs ,
75- next_color_for_bg = True ,
76- mode = self .mode ,
77- visible_if_colors = self .visible_if_colors ,
78- extensions = self .extensions ,
79- )
69+ return dataclasses .replace (self , next_color_for_bg = True )
8070
8171 @property
8272 def black (self ) -> StyleBuilder :
@@ -329,15 +319,7 @@ def double_underline(self) -> StyleBuilder:
329319
330320 @property
331321 def visible (self ) -> StyleBuilder :
332- return StyleBuilder (
333- fg = self .fg ,
334- bg = self .bg ,
335- attrs = self .attrs ,
336- next_color_for_bg = self .next_color_for_bg ,
337- mode = self .mode ,
338- visible_if_colors = True ,
339- extensions = self .extensions ,
340- )
322+ return dataclasses .replace (self , visible_if_colors = True )
341323
342324 def extend (
343325 self ,
@@ -380,36 +362,20 @@ def extend(
380362 StyleBuilder
381363 A new `StyleBuilder` instance with the merged extensions.
382364 """
383- extensions = {
384- ** self .extensions ,
385- ** (style_dict or {}),
386- ** styles ,
387- }
388-
389- return StyleBuilder (
390- fg = self .fg ,
391- bg = self .bg ,
392- attrs = self .attrs ,
393- next_color_for_bg = self .next_color_for_bg ,
394- mode = self .mode ,
395- visible_if_colors = self .visible_if_colors ,
396- extensions = extensions ,
365+ return dataclasses .replace (
366+ self ,
367+ extensions = {
368+ ** self .extensions ,
369+ ** (style_dict or {}),
370+ ** styles ,
371+ },
397372 )
398373
399374 def __repr__ (self ) -> str :
400375 return f"StyleBuilder(fg={ self .fg !r} , bg={ self .bg !r} , attrs={ set (self .attrs )!r} , on={ self .next_color_for_bg } )"
401376
402377 def _with_attrs (self , * attrs : types .Attribute ) -> StyleBuilder :
403- new_attrs = self .attrs .union (attrs )
404- return StyleBuilder (
405- fg = self .fg ,
406- bg = self .bg ,
407- attrs = new_attrs ,
408- next_color_for_bg = self .next_color_for_bg ,
409- mode = self .mode ,
410- visible_if_colors = self .visible_if_colors ,
411- extensions = self .extensions ,
412- )
378+ return dataclasses .replace (self , attrs = self .attrs .union (attrs ))
413379
414380 def _with_color (
415381 self , color : Union [types .Ansi16Color , types .Extended256 , types .Rgb ]
@@ -424,12 +390,6 @@ def _with_color(
424390 else :
425391 fg = color
426392
427- return StyleBuilder (
428- fg = fg ,
429- bg = bg ,
430- attrs = self .attrs ,
431- next_color_for_bg = next_color_for_bg ,
432- mode = self .mode ,
433- visible_if_colors = self .visible_if_colors ,
434- extensions = self .extensions ,
393+ return dataclasses .replace (
394+ self , fg = fg , bg = bg , next_color_for_bg = next_color_for_bg
435395 )
0 commit comments